<script setup>
import { SessionUser } from "@/components/session/token/SessionUser.vue";
import {ref, watch, defineEmits, onMounted} from "vue";
import { reg_1, getCustomerName, searchAndSelectCustomer, customer_id, clearCache, clearCustomerSelection, department_id } from "@/components/shop/POSDepartmentProcess.vue"

const emit = defineEmits(['update:vehicleObject', 'update:focus', 'update:bookingObject']);

const pendingBookings = ref([]);
// Get the department booking list
const loadPendingBookings = () => {
  SessionUser.request(
      SessionUser.objects.bookings.meta.endpoint,
      'GET',
      {
        filters: 'department:' + department_id.value + ',status:pending',
        page: 1,
        limit: 100,
      }
  ).then(response => {
    pendingBookings.value = response.data.data;
    console.log("Pending bookings:", pendingBookings.value);
  }).catch(error => {
    console.error("Error:", error);
  });
};

// Load the pending bookings when the component is mounted
onMounted(() => {
  loadPendingBookings();
});
// Watch for changes in the department_id
watch(department_id, (newValue) => {
  if (newValue) {
    loadPendingBookings();
  }
});

const getVehiclePlateBooking = (vehiclePlate) => {
  if (!vehiclePlate || !doesVehiclePlateHaveBooking(vehiclePlate)) {
    // If the vehicle plate is empty or doesn't have a booking, return null
    return null;
  }
  // Find the booking for the given vehicle plate
  return pendingBookings.value.find(booking => booking.regNrTraekker === vehiclePlate || booking.regNrTrailer === vehiclePlate);
};

const doesVehiclePlateHaveBooking = (vehiclePlate) => {
  // Check if the vehicle has a booking in the pending bookings list
  return pendingBookings.value.some(booking => booking.regNrTraekker === vehiclePlate || booking.regNrTrailer === vehiclePlate);
};

// Function to emit the booking object to the parent component
const emitBookingObject = (vehicle) => {
  // Check if the vehicle has a booking
  if (vehicle && vehicle.reg && doesVehiclePlateHaveBooking(vehicle.reg)) {
    // Get the booking object for the vehicle
    const booking = getVehiclePlateBooking(vehicle.reg);
    if (booking) {
      // Emit the booking object to the parent component
      emit('update:bookingObject', booking);
    } else {
      // Emit null if no booking is found
      emit('update:bookingObject', null);
    }
  } else {
    // Emit null if no vehicle is provided
    emit('update:bookingObject', null);
  }
};


// Define the vehicle response object (Example)
const vehicle_response_object = {
  id: 43, // Vehicle ID
  user_id: 1820, // User ID
  customer_id: 25266211, // Economic customer ID
  customer_name: "", // Customer name (From E-conomic)
  type: 5, // Vehicle primary product id
  reg: "EC25573", // License plate
  wash_subscription: true, // Subscription status
  addons: {
    enabled: 1, // How many addons are enabled
    available: 2, // How many addons are available
    list: [
        // List of enabled addons
      {
        id: 289, // Vehicle addon ID (Unique, different from the product ID or option ID)
        vehicle_id: 43, // Vehicle ID
        addon_id: 64, // Product option ID (Unique, different from the product ID or vehicle ID)
        amount: 1,  // Amount of this addon
        product: {
          id: 24, // Product ID (Unique, different from the vehicle ID or option ID)
          name: "Spot Free- Lastbil", // Product name
          description: " ", // Product description
          price: 39, // Product (default) price
          subscription_allowed: 1, // True if subscription is allowed (This should be true for all products listed here.)
          category: "4", // Product category ID
          piktogram: "", // Product image URL can be empty
          economic_product_id: "33", // Economic product ID
          apply_category_discount: false, // True if the product allows category, or E-conomic customer discount rules.
          requires_note: false, // True if the product requires a note when added to a vehicle
          created_at: "2024-12-09 14:31:49", // Product created date
          updated_at: "2025-04-08 14:07:41" // Product updated date
        }
      }
    ]
  }
}

const get_unregistered_vehicle_object = (reg) => {
  // Generate an id for the unregistered vehicle, this is only used for the dropdown
  let id_prefix = 999999999999;
  let id = id_prefix + Math.floor(Math.random() * 1000000);
  return {
    id: id,
    user_id: null,
    customer_id: null,
    customer_name: "",
    type: null,
    barred: false,
    reg: reg,
    wash_subscription: false,
    addons: {
      enabled: 0,
      available: 0,
      list: []
    }
  };
}

// To prevent the searches from overriding more recent searches
const current_search_id = ref(null);
const register_new_search = () => {
  let search_id = Date.now();
  current_search_id.value = search_id;
  return search_id;
};

const is_latest_search = (search_id) => {
  return search_id === current_search_id.value;
};

// Define reactive properties
const vehicles_matching = ref([]);

const onInputChange = (event) => {
  const inputValue = event.target.value;
  // Perform any necessary validation or processing on the input value
  console.log("Input value changed:", inputValue);

};

// Function to search for vehicles
const searchVehicle = async ( inputValue, search_id ) => {
  // Check if the search ID is the latest
  if (!is_latest_search(search_id)) {
    console.log("Search ID is not the latest. Ignoring this search.");
    return;
  }
  // Set the isSearching flag to true
  isSearching.value = true;
  // Perform the search
  SessionUser.request(
      SessionUser.objects.vehicles.meta.endpoint,
      'GET',
      {
        search: inputValue,
        page: 1,
        limit: 10,
      }
  ).then(response => {
    if (!is_latest_search(search_id)) {
      return;
    }
    let result = response?.data?.data;
    if (result && result.length > 0) {
      // If there are results, set the vehicles_matching array
      vehicles_matching.value = result;
    } else {
      // If no results, clear the vehicles_matching array
      vehicles_matching.value = [];
    }
    getUnregisteredVehicleObjects(inputValue, search_id);
  }).catch(error => {
    console.error("Error:", error, search_id);
  }).finally(() => {
    console.log("Finish search", search_id);
    if (is_latest_search(search_id)) {
      // Set the isSearching flag to false
      isSearching.value = false;
    }
  });
};

const getUnregisteredVehicleObjects = (inputValue, search_id) => {
  // Check if the search ID is the latest
  if (!is_latest_search(search_id)) {
    console.log("Search ID is not the latest. Ignoring this search.");
    return;
  }
  // If the input value is empty, clear the vehicles_matching array
  if (!inputValue) {
    vehicles_matching.value = [];
    return;
  }
  SessionUser.request(
      '/department/vehicles/unknown-customer',
      'GET',
      {
        search: inputValue,
        page: 1,
        limit: 10,
      }
  ).then(response => {
    console.log("Unregistered vehicles:", response.data.data);
    if (!is_latest_search(search_id)) {
      return
    }
    let result = response?.data?.data;
    let unregistered_vehicles = [];
    if (result && result.length > 0) {
      // If there are results, parse them into unregistered_vehicles
      for (let i = 0; i < result.length; i++) {
        // Check if the unregistered vehicle already exists in the vehicles_matching array
        let existingVehicle = vehicles_matching.value.find(vehicle => vehicle.reg === result[i].reg_1);
        if (existingVehicle) {
          // If it exists, skip adding it again
          continue;
        }
        unregistered_vehicles.push(get_unregistered_vehicle_object(result[i].reg_1));
      }
      // Set the vehicles_matching array to include both registered and unregistered vehicles
      vehicles_matching.value = [...vehicles_matching.value, ...unregistered_vehicles];
    } else {
      // Do nothing
    }
  }).catch(error => {
    console.error("Error:", error, search_id);
  }).finally(() => {
    console.log("Finish search", search_id);
    if (is_latest_search(search_id)) {
      // Set the isSearching flag to false
      isSearching.value = false;
    }
  })
};

const getVehicleObjectFromId = (id) => {
  // Find the vehicle object by ID
  return vehicles_matching.value.find(vehicle => vehicle.id === id);
};

// Watch for changes in reg_1
watch(reg_1, (newValue) => {
  // Define the search ID for this input change
  const search_id = register_new_search();
  console.log("reg_1 changed:", newValue);
  unselectCustomerOnChange();
  emitVehicleObject(null);
  // Check if the new value is empty, if so, clear the vehicles_matching array
  if (!newValue) {
    vehicles_matching.value = [];
    // Set the isSearching flag to false, as no search is performed
    if (is_latest_search(search_id)) {
      // Set the isSearching flag to false
      isSearching.value = false;
    }
    return;
  }
  // Perform the search
  searchVehicle(
      newValue,
      search_id
  );
});

const unselectCustomerOnChange = () => {
  clearCustomerSelection();
};

const selectVehicle = (vehicle_id) => {
  console.log('Select using click', vehicle_id);
  // Find the vehicle object by ID
  const vehicle = getVehicleObjectFromId(vehicle_id);
  if (vehicle) {
    // If a vehicle is found, set the reg_1 value to the vehicle's reg
    reg_1.value = vehicle.reg;
    getCustomerName(vehicle.customer_id);
    if (vehicle.customer_id) {
      // If the vehicle has a customer ID, search and select the customer
      // This is to prevent the unregistered vehicle from trying to select an unknown customer
      // Optionally, you can also set other properties like customer_id, etc.
      customer_id.value = vehicle.customer_id;
      searchAndSelectCustomer(vehicle.customer_id);
    }
    // Emit the vehicle object to the parent component
    emitVehicleObject(vehicle);
  }
};

const getSearchIndexByVehicleId = (vehicle_id) => {
  // Find the index of the vehicle in the vehicles_matching array
  return vehicles_matching.value.findIndex(vehicle => vehicle.id === vehicle_id);
};

const selectDropdownItem = (index) => {
  // Select a vehicle from the dropdown
  if (vehicles_matching.value[index]) {
    selectVehicle(vehicles_matching.value[index].id);
  } else {
    emitVehicleObject(null);
  }
  // Go to the next input field
  focusNextField();
};

const keyDownNextTabIndexButton = (event, tabIndex) => {
  // Handle keydown event to navigate to the next button
  if (event.key === "Enter") {
    event.preventDefault();
    const button = document.querySelector(`button[tabindex="${tabIndex}"]`);
    if (button) {
      button.click();
    }
  }
};
const arrowKeyHandler = (event) => {
  // Handle arrow key navigation in the dropdown
  if (event.key === 'ArrowDown') {
    event.preventDefault();
    if (selectedDropdownItem.value < vehicles_matching.value.length - 1) {
      selectedDropdownItem.value++;
    }
  }
  if (event.key === 'ArrowUp') {
    event.preventDefault();
    if (selectedDropdownItem.value > -1) {
      selectedDropdownItem.value--;
    }
  }
  if (event.key === 'Enter') {
    event.preventDefault();
    selectDropdownItem(selectedDropdownItem.value);
    selectedDropdownItem.value = -1;
    // Imitate the tab key press to move to the next input
    focusNextField();
  }
  if (event.key === 'Tab') {
    event.preventDefault();
    selectDropdownItem(selectedDropdownItem.value);
    selectedDropdownItem.value = -1;
    // Set the active input to the next field
    focusNextField();
  }
};
const selectedDropdownItem = ref(-1);
const showSelector = ref(false);
const lostfocus = () => {
  emitFocus(false);
  // Delay to prevent the dropdown from closing immediately
  setTimeout(() => {
    showSelector.value = false;
  }, 200);
  // Check if the current input value is in the vehicles_matching array
  const currentValue = reg_1.value;
  const vehicle = vehicles_matching.value.find(vehicle => vehicle.reg === currentValue);
  if (vehicle) {
    // If the vehicle is found, set the reg_1 value to the vehicle's reg
    reg_1.value = vehicle.reg;
    customer_id.value = vehicle.customer_id;
    getCustomerName(vehicle.customer_id);
    if (vehicle.customer_id) {
      // If the vehicle has a customer ID, search and select the customer
      // This is to prevent the unregistered vehicle from trying to select an unknown customer
      searchAndSelectCustomer(vehicle.customer_id);
    }
    // Emit the vehicle object to the parent component
    emitVehicleObject(vehicle);
  } else {
    // If not found, clear the vehicles_matching array
    vehicles_matching.value = [];
    emitVehicleObject(null);
  }
};
const isSearching = ref(false);

// Watch for changes in the vehicles_matching array, to check if the current index is valid
watch(vehicles_matching, (newValue) => {
  // Check if the input directly matches an item in the vehicles_matching array (Then we can automatically select it)
  const currentValue = reg_1.value;
  const vehicle = newValue.find(vehicle => vehicle.reg === currentValue);
  if (vehicle) {
    // If the vehicle is found, set the reg_1 value to the vehicle's reg
    reg_1.value = vehicle.reg;
    customer_id.value = vehicle.customer_id;
    getCustomerName(vehicle.customer_id);
    if (vehicle.customer_id) {
      // If the vehicle has a customer ID, search and select the customer
      // This is to prevent the unregistered vehicle from trying to select an unknown customer
      searchAndSelectCustomer(vehicle.customer_id);
    }
    // Emit the vehicle object to the parent component
    emitVehicleObject(vehicle);
  }
  // Check if the selectedDropdownItem index is valid
  if (selectedDropdownItem.value >= newValue.length) {
    // Set the selectedDropdownItem to the last index if it exceeds the new length
    selectedDropdownItem.value = newValue.length - 1;
  }
});

const focusNextField = () => {
  // Focus on the next input field
  const nextField = document.querySelector('input[tabindex="2"]');
  if (nextField) {
    nextField.focus();
  }
};

// Function to emit the vehicle object to the parent component
const emitVehicleObject = (vehicle) => {
  // Emit the vehicle object
  emit('update:vehicleObject', vehicle);
  // Emit the booking object if the vehicle has a booking
  emitBookingObject(vehicle);
};

const emitFocus = (isFocused) => {
  // Emit the focus event
  emit('update:focus', isFocused);
};

const getDropdownIconColor = (vehicle) => {
  // Determine the icon color based on the vehicle's status
  const colors = {
    verified: 'has-text-success', // Used when the vehicles owner is verified
    unverified: 'has-text-warning', // Used when the vehicles owner is unverified
    barred: 'has-text-danger', // Used when the vehicles owner is barred
    hasBooking: 'has-text-link', // Used when the vehicle has a booking
  }
  let iconColor = colors.unverified; // Default color

  // Check if the vehicle is verified
  function isVerified(vehicle) {
    return vehicle.customer_id && vehicle.customer_id > 0;
  }
  // Check if the vehicle is barred
  function isBarred(vehicle) {
    return !!vehicle.barred;
  }
  // Check if the vehicle has a booking
  function hasBooking(vehicle) {
    return doesVehiclePlateHaveBooking(vehicle.reg);
  }

  if (isVerified(vehicle)) {
    iconColor = colors.verified;
  }
  if (hasBooking(vehicle)) {
    iconColor = colors.hasBooking;
  }
  if (isBarred(vehicle)) {
    iconColor = colors.barred;
  }

  return iconColor;
};

const getCurrentIconColor = () => {
  // Check if the current input value is in the vehicles_matching array
  const currentValue = reg_1.value;
  const vehicle = vehicles_matching.value.find(vehicle => vehicle.reg === currentValue);
  let tmp_color = 'has-text-grey';
  if (vehicle) {
    // If the vehicle is found, return the icon color
    tmp_color = getDropdownIconColor(vehicle);
  }
  // Check if there's a booking for the current vehicle
  if (doesVehiclePlateHaveBooking(currentValue)) {
    tmp_color = 'has-text-link';
  }
  // If not found, return the default color
  return tmp_color;
};

</script>

<template>
  <div>
    <!-- License Plate Registration 1 Input -->
    <div class="field">
      <div class="control has-icons-left" :class="{'is-loading': isSearching}">
         <span class="icon is-small is-left">
           <!-- Circle icon -->
           <i class="fas fa-circle" :class="getCurrentIconColor()"></i>
        </span>
        <input
            type="text"
            class="input has-sharp-edges is-loading"
            v-model="reg_1"
            @focus="showSelector = true; emitFocus(true)"
            @blur="lostfocus"
            @keydown="arrowKeyHandler"
            id="reg_1"
            autocomplete="off"
        />
      </div>
    </div>
    <!-- Dropdown for license plate suggestions -->
    <div
        class="dropdown"
        :class="{'is-active': showSelector}"
        v-show="showSelector && vehicles_matching.length > 0"
    >
      <div class="dropdown-menu">
        <div class="dropdown-content">
          <a
              class="dropdown-item is-clickable"
              v-for="result in vehicles_matching"
              :key="result.id"
              @mousedown="selectVehicle(result.id)"
              :class="{
                'is-active': getSearchIndexByVehicleId(result.id) === selectedDropdownItem,
                'is-drop-down-selected': getSearchIndexByVehicleId(result.customerNumber) === selectedDropdownItem,
              }">
            <span class="icon">
              <!-- Circle icon -->
              <i class="fas fa-circle" :class="getDropdownIconColor(result)"></i>
            </span>
            <span>
            {{ result.reg }}{{ result.customer_name ? (' - ' + result.customer_name ) : '' }}{{ result.barred ? ' ('+ SessionUser.objects.global.language.barred + ')' : '' }}
            </span>
          </a>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>

</style>