<script setup>
import {defineEmits, defineProps, ref, watch, computed} from 'vue';
import {SessionUser} from "@/components/session/token/SessionUser.vue";
import {getError, parseError} from "@/components/request/HandleGlobalError.vue";

const props = defineProps(
    {
        inputId: {
            type: String,
            required: true
        },
        tabIndex: {
            type: Number,
            required: true
        },
        inputModel: {
            type: String,
            required: false
        },
      actualValue: {
            type: String,
            required: false
        },
        customer_number: {
            type: Number,
            required: false
        },
        reg_1: {
          type: String,
          required: false
        },
        customer_id: {
          type: Number,
          required: false,
        }
    }
);
const emits = defineEmits(['update:inputModel']);

const customerRegistrationNumbers = ref([]);
const isLoading = ref(false);
const minLicensePlateLength = 6;
const maxLicensePlateLength = 7;
const licensePlateRegex = /^[A-Z]{2}[0-9]{4,5}$/;
const isLicensePlateValid = ref(false);
const uniqueFieldId = Math.random().toString(36).substring(7);
const currentFieldVal = ref('');
const vehicleDataDefault = ref(
    {
      "registration_number": "AB12345",
      "status": "Registreret",
      "status_date": "2024-06-27T11:59:50.000+02:00",
      "type": "Personbil",
      "use": "Privat personkørsel",
      "first_registration": "2008-06-26+02:00",
      "vin": "VIN12345678901234",
      "own_weight": null,
      "cerb_weight": 1302,
      "total_weight": 1705,
      "axels": 2,
      "pulling_axels": 1,
      "seats": 1,
      "coupling": true,
      "trailer_maxweight_nobrakes": 600,
      "trailer_maxweight_withbrakes": 900,
      "doors": null,
      "make": "PEUGEOT",
      "model": "207",
      "variant": "1,6 I 16V STC.",
      "model_type": "W",
      "model_year": 0,
      "color": "Ukendt",
      "chassis_type": "",
      "engine_cylinders": 0,
      "engine_volume": 1598,
      "engine_power": 88,
      "fuel_type": "Benzin",
      "is_hybrid": false,
      "hybrid_type": "mild",
      "registration_zipcode": "",
      "vehicle_id": 123456789,
      "mot_info": {
        "type": "PeriodiskSyn",
        "date": "2024-12-31",
        "result": "Godkendt",
        "status": "Aktiv",
        "status_date": "2024-12-31",
        "mileage": 200000
      },
      "is_leasing": false,
      "leasing_from": null,
      "leasing_to": null
    }
);

const vehicleData = ref({});
vehicleData.value = vehicleDataDefault.value;

/**
 * Set the loading state of the input field
 * @param value boolean
 */
const setLoading = (value) => {
    isLoading.value = value;
};

const runParserFocusOut = async () => {
  justLostFocus();
  // Push the vehicle data to the parent
  emits('update:inputModel', event.target.value);
  vehicleData.value = {};
  currentFieldVal.value = event.target.value;
  setLoading(true);
  // Transform the input to uppercase
  event.target.value = event.target.value.toUpperCase();
  checkLicensePlateValid(event.target.value);
  // Lookup vehicle data
  await lookupVehicleData();
  setLoading(false);
  };

const runParserInput = async () => {
  // Push the vehicle data to the parent
  emits('update:inputModel', event.target.value);
  vehicleData.value = {};
  currentFieldVal.value = event.target.value;
  // Transform the input to uppercase
  event.target.value = event.target.value.toUpperCase();
  checkLicensePlateValid(event.target.value);
  // Search in the customer registration numbers
  searchCustomerRegistrationNumbers(event.target.value);
};

const searchCustomerRegistrationNumbers = (licensePlate, allowEmpty = false) => {
  if (props.customer_number === 0 || props.customer_number === undefined || (licensePlate.length < 1 && !allowEmpty)) {
    customerRegistrationNumbers.value = [];
    return;
  }
  // Search for the license plate in the customer registration numbers
  SessionUser.adminUser.plates.search_customer_plates(props.customer_number, licensePlate, props.inputId).then((response) => {
    if (response === undefined) {
      return;
    }
    // Remove duplicates
    let uniqueRegistrationNumbers = response.filter((v, i, a) => a.findIndex(t => (t.registration_number === v.registration_number)) === i);
    // Remove those entries with registration_number = ""
    uniqueRegistrationNumbers = uniqueRegistrationNumbers.filter((object) => {
      return object.registration_number !== '';
    })

    customerRegistrationNumbers.value = uniqueRegistrationNumbers
  }).catch((error) => {
    parseError(error, 'license_plate_input_' + uniqueFieldId);
  });
  customerRegistrationNumbers.value = customerRegistrationNumbers.value.filter((customer) => {
    //console.log('Searching for: ' + licensePlate, 'In: ' + props.customer_number);
    return customer.registration_number.includes(licensePlate);
  });
}

const checkLicensePlateValid = (licensePlate) => {
    isLicensePlateValid.value = licensePlateRegex.test(licensePlate);
};

const isValueValid = () => {
    return isLicensePlateValid.value;
};

const isEmpty = () => {
    return currentFieldVal.value === '';
};

const lookupVehicleData = () => {
    // Check if the value is valid
    if (!isValueValid()) {
        return;
    }
    SessionUser.superUser.modules.motorapi.functions.lookup(currentFieldVal.value).then((response) => {
      vehicleData.value = response.data.data;
    }).catch((error) => {
      parseError(error, 'license_plate_input_' + uniqueFieldId);
    });
};

const lostFocusAt = ref(null)

const justLostFocus = () => {
  lostFocusAt.value = Date.now();
}

const wasUserJustFocused = () => {
  if (lostFocusAt.value === null) {
    return false;
  }
  const now = Date.now();
  const timeDiff = now - lostFocusAt.value;
  lostFocusAt.value = now;
  return timeDiff < 200;
}

const isDropdownOpen = () => {
  let tmp_result = false;
  // Check if the user is focused right now
  if (isUserFocused.value) { tmp_result = true; }
  // Check if the user was focused in the last 200 ms
  if (wasUserJustFocused()) { tmp_result = true; }
  return tmp_result;
}

//const isUserFocused = ref((document.activeElement === document.getElementById(props.inputId)));

const isUserFocused = computed(() => {
  return hasFocus.value;
})

const selectedDropdownItem = ref(-1);

const pressedKey = (event) => {
    if (event.key === 'ArrowDown') {
        event.preventDefault();
        if (selectedDropdownItem.value < customerRegistrationNumbers.value.length - 1) {
            selectedDropdownItem.value++;
        }
    }
    if (event.key === 'ArrowUp') {
        event.preventDefault();
        if (selectedDropdownItem.value > -1) {
            selectedDropdownItem.value--;
        }
    }
    if (event.key === 'Enter') {
        event.preventDefault();
        // Check if the dropdown item is selected
        if (selectedDropdownItem.value === -1) {
            return;
        }
        // Select the license plate
        setInputValue(customerRegistrationNumbers.value[selectedDropdownItem.value]);
        selectedDropdownItem.value = -1;
        // Set the active input to the reference field (If it exists)
      if (document.getElementById('reference')) {
        document.getElementById('reference').focus();
      }
    }
};

const setInputValue = (licensePlate) => {
    inputField.value.value = licensePlate.registration_number;
    currentFieldVal.value = licensePlate.registration_number;
    event.target.value = licensePlate.registration_number;
};

const isDropdownItemSelected = (registrationNumber) => {
    return registrationNumber === customerRegistrationNumbers.value[selectedDropdownItem.value];
};

const inputField = ref(null);

watch(() => props.actualValue, (newValue) => {
    if (newValue === currentFieldVal.value) {
        return;
    }
    currentFieldVal.value = newValue;
    checkLicensePlateValid(newValue);
    searchCustomerRegistrationNumbers(newValue);
});

const onChangeReg1 = () => {
  // If the field is empty, search all
  console.log('onBecomeActive');
  // Check if reg_1 is set
  if (props.reg_1) {
    console.log('reg_1 is set, searching matching plates');
    searchCustomerRegistrationNumbers('', true);
  }
}

watch(() => props.reg_1, (newValue) => {
  onChangeReg1();
})

watch(() => props.customer_id, (newValue) => {
  onChangeReg1();
})

const onClickDropdownItem = (newRegistrationNumber) => {
  // Get the inputField
  if (inputField.value) {
    currentFieldVal.value = newRegistrationNumber;
    // Update the input value
    inputField.value.value = newRegistrationNumber;
    // Get the inputField
    emits('update:inputModel', newRegistrationNumber);
  }
}

const hasFocus = ref(false);

const isRegistrationNumberKnown = (registrationNumber) => {
  return customerRegistrationNumbers.value.some((customer) => {
    return customer.registration_number === registrationNumber;
  });
}

const getRegistrationNumberColor = (registrationNumber) => {
  let tmp_result = 'has-text-grey';
  function isRegistrationNumberVerified() {
    // If the registration number exists in the results
    return isRegistrationNumberKnown(registrationNumber);
  }
  if (isRegistrationNumberVerified()) {
    tmp_result = 'has-text-warning';
  }
  return tmp_result;
}

const getCurrentIconColor = () => {
  let tmp_result = 'has-text-grey';
  if (isRegistrationNumberKnown(currentFieldVal.value)) {
    tmp_result = 'has-text-warning';
  }
  return tmp_result;
}
</script>

<template>
  <div>
    <div
      class="control has-icons-left has-icons-right"
      :class="{'is-loading': isLoading}">
      <span class="icon is-small is-left">
        <!-- Circle icon -->
        <i class="fas fa-circle" :class="getCurrentIconColor()"></i>
      </span>
    <input class="input reg-input has-sharp-edges"
           type="text"
           @focusout="runParserFocusOut; hasFocus = false"
           @focusin="hasFocus = true"
           @input="runParserInput"
           :id="props.inputId"
           :tabindex="props.tabIndex"
           autocomplete="off"
           @keydown="pressedKey($event)"
           ref="inputField"
    />
    <span class="icon is-small is-right" v-if="isValueValid()">
      <i class="fas fa-check"></i>
    </span>
    <!-- Has been deactivated, since some users have reported that it is annoying. It will probably be added back in the future, with a better implementation -->
    <span class="icon is-small is-right has-text-warning" v-else-if="!isValueValid() && !isEmpty()" style="display: none;">
      <i class="fas fa-exclamation-triangle"></i>
    </span>
    <!-- Has been deactivated, since some users have reported that it is annoying. It will probably be added back in the future, with a better implementation -->
    <p class="help is-danger" v-if="!isValueValid() && !isEmpty()" style="display: none;">
      Nummerpladen er ikke gyldig
    </p>
    <!-- Error handling -->
    <p class="help is-danger" v-if="getError('license_plate_input_' + uniqueFieldId)" style="display: none;">
      {{ getError('license_plate_input_' + uniqueFieldId) }}
    </p>
    <!-- Vehicle data -->
      <p class="help is-info" v-if="isLoading">
        Henter køretøjsdata...
      </p>
      <p class="help is-info" v-if="isValueValid() && !isEmpty() && !isLoading && vehicleData.registration_number">
        <!-- Plate details -->
        {{ vehicleData.make }} - {{ vehicleData.model }} - {{ vehicleData.variant }} - {{ vehicleData.type }} - {{ SessionUser.adminUser.plates.parse_motorapi_string(vehicleData.use) }}
      </p>
  </div>
  <!-- Search results -->
  <div
      class="dropdown"
      :class="{'is-active': customerRegistrationNumbers.length > 0 && !isLoading && !isEmpty() && isUserFocused}"
      v-if="customerRegistrationNumbers.length > 0 && !isLoading && !isEmpty() && isUserFocused"
  >
    <div class="dropdown-menu">
      <div class="dropdown-content">
        <a class="dropdown-item"
           v-for="registrationNumberObj in customerRegistrationNumbers"
           :key="registrationNumberObj.registration_number"
           :class="{'is-active': isDropdownItemSelected(registrationNumberObj)}"
           @mousedown="onClickDropdownItem(registrationNumberObj.registration_number)"
        >
          <span class="icon">
            <!-- Circle icon -->
            <i class="fas fa-circle" :class="getRegistrationNumberColor(registrationNumberObj.registration_number)"></i>
          </span>

          {{ registrationNumberObj.registration_number }}
        </a>
      </div>
    </div>
  </div>
  </div>
</template>

<style scoped>
.input.has-sharp-edges {
  border-radius: 0;
}
</style>