<script>
import { ref, watch } from "vue";
import { useCookies } from "vue3-cookies";
import TimeBookingsNewStep1
  from "@/views/dashboards/departmentDashboard/modules/time-bookings/book/steps/TimeBookingsNewStep1.vue";
import TimeBookingsNewStep2
  from "@/views/dashboards/departmentDashboard/modules/time-bookings/book/steps/TimeBookingsNewStep2.vue";
import TimeBookingsNewStep3
  from "@/views/dashboards/departmentDashboard/modules/time-bookings/book/steps/TimeBookingsNewStep3.vue";

const step = ref(1);
// Variables
const department_var = ref(null); // Placeholder for department selection
const departmentObject = ref(null); // Placeholder for department object
const vehicleType = ref(null); // Placeholder for vehicle type selection
const reg_1 = ref(null); // Placeholder for vehicle registration number 1
const phone = ref(); // Placeholder for phone number
const phone_country_code = ref(45); // Placeholder for phone country code
const isBookingForCustomer = ref(false); // Flag to indicate if the booking is for a customer (Department) or for the user (User Dashboard)
const persistentCookiesEnabled = ref(false); // Flag to indicate if persistent cookies are enabled
const cookie_expires = '365d'; // Cookie expiration time
const addons = ref([]); // Placeholder for addons, if any
const vehicleTypeObject = ref(null); // Placeholder for the vehicle type object
const departmentBookingType = ref(null); // Placeholder for the department booking type
const departmentBookingTypeObject = ref(null); // Placeholder for the department booking type object
const time_slot = ref(null); // Placeholder for the selected time slot
// Persistent cookies for storing user data
const cookies = useCookies().cookies;
const getCookieName = (name) => {
  // Function to get the cookie name with a specific prefix
  return `time_bookings_new_${name}`;
};
const clearPersistentCookies = () => {
  // Function to clear all persistent cookies
  const cookieNames = persistentCookies.map(cookie => getCookieName(cookie.name));
  // Remove all persistent cookies by their names
  if (!cookieNames.length) return; // If no cookies to clear, exit early
  cookieNames.forEach(name => {
    // Check if the cookie is required before removing
    if (cookies.get(name) && persistentCookies.some(cookie => cookie.name === name && cookie.required)) {
      // If the cookie is required, do not remove it
      return;
    }
    cookies.remove(name);
  });
};
const isPersistentCookiesEnabled = () => {
  // Function to check if persistent cookies are enabled
  return persistentCookiesEnabled.value;
};
const setPersistentCookiesEnabled = (enabled) => {
  // Function to set the persistent cookies enabled state
  persistentCookiesEnabled.value = enabled;
  if (!enabled) {
    // If persistent cookies are not enabled, clear all persistent cookies
    clearPersistentCookies();
  }
};
// Define the persistent cookies to be used in the booking process
const persistentCookies = [
  { name: 'persistentCookiesEnabled', ref: persistentCookiesEnabled, required: true },
  { name: 'vehicleType', ref: vehicleType },
  { name: 'reg_1', ref: reg_1 },
  { name: 'phone', ref: phone },
  { name: 'phone_country_code', ref: phone_country_code },
  { name: 'isBookingForCustomer', ref: isBookingForCustomer }
]

// Load persistent cookies if they exist
// Watch for changes in the refs and update cookies accordingly
persistentCookies.forEach(cookie => {
  // Check if the cookie is required and if it exists
  if (cookie.required && !cookies.get(getCookieName(cookie.name))) {
    // If the cookie is required and does not exist, set it to a default value
    cookies.set(getCookieName(cookie.name), cookie.ref.value, cookie_expires);
  }
  // Load the cookie value if it exists
  const cookieValue = cookies.get(getCookieName(cookie.name));
  if (cookieValue) {
    cookie.ref.value = cookieValue;
  }
  watch(cookie.ref, (newValue) => {
    // Check if the cookie is required (Otherwise, we might not want to set it)
    if (cookie.required || persistentCookiesEnabled.value) {
      // Update the cookie value whenever the ref changes
      cookies.set(getCookieName(cookie.name), newValue, cookie_expires);
    } else {
      // If the cookie is not required and persistent cookies are not enabled, remove the cookie
      cookies.remove(getCookieName(cookie.name));
    }
  });
});


const setDepartmentBookingType = (type, typeObject) => {
  // Function to set the department booking type
  if (type && type > 0) {
    departmentBookingType.value = type;
    // Set the department booking type object if provided
    if (typeObject) {
      departmentBookingTypeObject.value = typeObject;
    }
  } else {
    departmentBookingType.value = null; // Reset the department booking type if no valid type is selected
    departmentBookingTypeObject.value = null; // Reset the department booking type object
  }
};

const steps = [
  {
    id: 1,
    label: 'Vælg køretøj',
    description: 'Vælg det køretøj, du ønsker at booke tid for',
    component: TimeBookingsNewStep1, // Step 1 component
    requirements: [
      {
        condition: () => {
          // Check if a department is selected
          return !!department_var.value; // Ensure department is not null or undefined
        },
        message: 'Du skal vælge en afdeling for at fortsætte.'
      },
      {
        condition: () => {
          // Check if the phone country code is valid
          return phone_country_code.value && phone_country_code.value > 0;
        },
        message: 'Du skal vælge en gyldig landekode for at fortsætte.'
      },
      {
        condition: () => {
          // Check if the phone number is valid
          return phone.value && phone.value.toString().length >= 8; // Assuming a valid phone number has at least 8 digits
        },
        message: 'Du skal indtaste et gyldigt telefonnummer for at fortsætte.'
      },
    ]
  },
  {
    id: 2,
    label: 'Vælg vaske ydelse',
    description: 'Vælg den vaske ydelse, du ønsker at booke',
    component: TimeBookingsNewStep2, // Step 2 component
    requirements: [
      {
        condition: () => {
          // Check if a vehicle type is selected
          return vehicleType.value && vehicleType.value > 0; // Assuming a valid vehicle type is greater than 0
        },
        message: 'Du skal vælge en køretøjstype for at fortsætte.'
      },
      {
        condition: () => {
          // Check if a department booking type is selected
          return departmentBookingType.value && departmentBookingType.value > 0; // Assuming a valid booking type is greater than 0
        },
        message: 'Du skal vælge en bookingtype for at fortsætte.'
      },
    ]
  },
  {
    id: 3,
    label: 'Vælg tidspunkt',
    description: 'Vælg det tidspunkt, du ønsker at vaske dit køretøj',
    component: TimeBookingsNewStep3, // Step 3 component
    requirements: [
      {
        condition: () => {
          // Check if a time slot is selected
          return (time_slot.value);
        },
        message: 'Du skal vælge et tidspunkt for at fortsætte.'
      },
    ]
  },
  {
    id: 4,
    label: 'Bekræft booking',
    description: 'Bekræft din tidsbooking og afslut processen',
    component: null // Placeholder for Step 4 component
  }
];

const nextStep = () => {
  if (step.value < steps.length) {
    step.value++;
  }
};
const previousStep = () => {
  if (step.value > 1) {
    step.value--;
  }
};
const isNextStepAvailable = () => {
  return step.value < steps.length;
};
const isPreviousStepAvailable = () => {
  return step.value > 1;
};
const isCurrentStepValid = () => {
  const currentStep = steps.find(s => s.id === step.value);
  if (!currentStep) return false;

  // Check if all requirements are met for the current step
  return currentStep.requirements.every(req => req.condition());
};
const getCurrentStepConditions = () => {
  const currentStep = steps.find(s => s.id === step.value);
  if (!currentStep) return [];

  // Return the requirements for the current step
  return currentStep.requirements;
};
const currentComponent = ref(steps[step.value - 1].component);

const getCurrentComponentView = () => {
  const currentStep = steps.find(s => s.id === step.value);
  if (currentStep && currentStep.component) {
    return currentStep.component;
  }
  return null; // or a default component
};

const addAddon = (addon) => {
  // Function to add an addon to the booking
  if (!addons.value.includes(addon)) {
    addons.value.push(addon);
  }
};

const removeAddon = (addon) => {
  // Function to remove an addon from the booking
  const index = addons.value.indexOf(addon);
  if (index > -1) {
    addons.value.splice(index, 1);
  }
};

const hasAddon = (addon) => {
  // Function to check if an addon is already added
  return addons.value.includes(addon);
};

const getAddons = () => {
  // Function to get the list of addons
  return addons.value;
};

const addonObjects = ref([]); // Addon objects to be used in the booking process

const getAddonObject = (addon) => {
  // Function to get the addon object by its ID
  return addonObjects.value.find(obj => obj.id === addon) || null;
};

const addAddonObject = (addon) => {
  // Function to add an addon object to the list
  if (!addonObjects.value.some(obj => obj.id === addon.id)) {
    addonObjects.value.push(addon);
  }
};

const removeAddonObject = (addon) => {
  // Function to remove an addon object from the list
  const index = addonObjects.value.findIndex(obj => obj.id === addon.id);
  if (index > -1) {
    addonObjects.value.splice(index, 1);
  }
};

const toggleAddon = (addon, addon_object) => {
  // Function to toggle an addon
  if (hasAddon(addon)) {
    removeAddon(addon);
    removeAddonObject(addon_object);
  } else {
    addAddon(addon);
    addAddonObject(addon_object);
  }
};

const formatRegistrationNumber = (reg) => {
  if (!reg) return '';
  // Remove spaces and capitalize the registration number
  return reg.replace(/\s+/g, '').toUpperCase();
};

const formatOnlyDigits = (value) => {
  let allowedCharacters = '0123456789';
  let blacklistCharacters = '+-eE.,()[]{}'; // Characters to remove
  let regex = new RegExp(`[^${allowedCharacters}${blacklistCharacters}]`, 'g'); // Create a regex to match all non-allowed characters
  let result = value.toString().replace(regex, ''); // Replace all non-allowed characters with an empty string
  return parseInt(result, 10);
};

const formatPhoneNumber = (phoneNumber) => {
  // Remove all other characters, spaces, except digits [0-9]
  return formatOnlyDigits(phoneNumber);
};

const formatCountryCode = (countryCode) => {
  // Ensure the country code is a valid number and format it
  return formatOnlyDigits(countryCode);
};

const selectTimeSlot = (slot) => {
  // Function to select a time slot
  if (slot) {
    time_slot.value = slot;
  } else {
    time_slot.value = null; // Reset the time slot if no valid slot is selected
  }
};

const getSelectedTimeSlot = () => {
  // Function to get the currently selected time slot
  return time_slot.value;
};

const setDepartment = (dept, deptObject) => {
  // Function to set the department for the booking
  if (dept && dept > 0) {
    department_var.value = dept;
    departmentObject.value = deptObject; // Set the department object if provided
  } else {
    department_var.value = null; // Reset the department if no valid department is selected
    departmentObject.value = null; // Reset the department object
  }
};


// Watch for changes in the phone number and country code, format them accordingly
watch([phone, phone_country_code], ([newPhone, newCountryCode]) => {
  if (newPhone) phone.value = formatPhoneNumber(newPhone);
  if (newCountryCode) phone_country_code.value = formatCountryCode(newCountryCode);
});

// Watch for changes in the registration numbers, capitalize them and remove any spaces
watch([reg_1], ([newReg1]) => {
  if (newReg1) reg_1.value = formatRegistrationNumber(newReg1);
});

// Watch for changes in the vehicle type, remove the addon objects if the vehicle type is changed
watch(vehicleType, (newVehicleType) => {
  if (newVehicleType !== null) {
    // If a new vehicle type is selected, clear the addons
    addonObjects.value = [];
    addons.value = [];
  }
});

// Expose the nextStep and previousStep methods
export const timeBookingsNewProcess = {
  nextStep,
  previousStep,
  currentComponent,
  getCurrentComponentView,
  steps,
  step,
  vehicleType,
  reg_1,
  isBookingForCustomer,
  phone,
  phone_country_code,
  isNextStepAvailable,
  isPreviousStepAvailable,
  isCurrentStepValid,
  getCurrentStepConditions,
  clearPersistentCookies,
  isPersistentCookiesEnabled,
  setPersistentCookiesEnabled,
  addAddon,
  removeAddon,
  hasAddon,
  getAddons,
  toggleAddon,
  getAddonObject,
  addonObjects,
  addAddonObject,
  removeAddonObject,
  vehicleTypeObject,
  selectTimeSlot,
  getSelectedTimeSlot,
  time_slot,
  department: department_var,
  setDepartment,
  departmentObject,
  departmentBookingType,
  setDepartmentBookingType,
};
</script>