<template>
  <div class="table-search-box">
    <input type="text" placeholder="Wyszukaj pojazd..." v-model="vehicleSearchInput" />
    <button @click="addVehicleRow()">DODAJ NOWY POJAZD</button>
  </div>

  <div class="table-wrapper">
    <table class="vehicle-manager-table">
      <thead>
        <tr>
          <td style="width: 50px">#</td>
          <td style="width: 200px">Nazwa</td>
          <td style="width: 150px">Typ</td>
          <td style="width: 150px">Kabina (lok.)</td>
          <td style="width: 170px">Grupa</td>
          <td style="width: 100px">Tylko sponsorzy do</td>
          <td style="width: 100px">Tylko zespół</td>
          <td style="width: 50px">Ukryty</td>
          <td style="width: 50px">Usuń</td>
        </tr>
      </thead>

      <tbody>
        <tr v-for="row in vehiclesTableComp" :key="row.vehicleRef.id">
          <td>{{ row.vehicleRef.id }}</td>

          <td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.NAME)">
            {{ row.vehicleRef.name }}
          </td>

          <td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.TYPE)">
            {{ row.vehicleRef.type }}
          </td>

          <td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.CABIN)">
            {{ row.vehicleRef.cabinName }}
          </td>

          <td class="editable" @click="selectRowVehicleGroup(row)">
            <select
              v-if="currentEditingGroupId == row.vehicleRef.id"
              @blur="(e) => editVehicleGroup(e, row)"
              :id="`select-group-${row.vehicleRef.id}`"
              ref="select-group"
              style="width: 100%"
            >
              <option
                v-for="value in vehiclesStore.vehicleGroupsTable"
                :value="value.vehicleGroupRef.id"
                :selected="row.vehicleRef.group.id == value.vehicleGroupRef.id"
              >
                {{ value.vehicleGroupRef.name }}
              </option>
            </select>

            <span v-else>{{ row.vehicleRef.group.name }}</span>
          </td>

          <td class="editable" @click="editRowRestrictions(row, VehicleEditRestrictionKey.SPONSOR_ONLY)">
            <span v-if="row.vehicleRef.restrictions?.sponsorOnly !== undefined">
              {{ new Date(row.vehicleRef.restrictions.sponsorOnly).toLocaleString() }}
            </span>

            <span v-else>❌</span>
          </td>

          <td class="editable" @click="editRowRestrictions(row, VehicleEditRestrictionKey.TEAM_ONLY)">
            <span v-if="row.vehicleRef.restrictions?.teamOnly !== undefined">
              {{ row.vehicleRef.restrictions.teamOnly ? '✅' : '❌' }}
            </span>

            <span v-else>❌</span>
          </td>

          <td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.HIDDEN)">
            {{ row.vehicleRef.hidden ? '✅' : '❌' }}
          </td>

          <td class="editable" @click="removeVehicle(row.vehicleRef.id)"><img src="/icon-trash.svg" alt="remove" /></td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script lang="ts" setup>
import { computed, nextTick, ref, useTemplateRef } from 'vue';
import { useVehiclesStore } from '../../stores/vehicles.store';
import { IVehicleTableRow, VehicleEditRestrictionKey, VehicleEditRowKey } from '../../types/vehicles.types';

const vehiclesStore = useVehiclesStore();
const vehicleSearchInput = ref('');
const currentEditingGroupId = ref(-1);
const selectGroup = useTemplateRef('select-group');

const vehiclesTableComp = computed(() => {
  return vehiclesStore.vehiclesTable
    .filter((row) => row.vehicleRef.name.toLowerCase().includes(vehicleSearchInput.value.trim().toLowerCase()))
    .sort((r1, r2) => {
      return r1.vehicleRef.id - r2.vehicleRef.id;
    });
});

async function editRowPrimitive(row: IVehicleTableRow, editKey: VehicleEditRowKey) {
  if (!(editKey in row.vehicleRef)) return;

  let rowValue = row.vehicleRef[editKey];

  if (typeof rowValue === 'string' || typeof rowValue === 'undefined' || rowValue == null) {
    const promptValue = prompt('Zmień wartość:', rowValue ?? '');
    if (promptValue == null) return;

    const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, editKey, promptValue);

    if (updatedData) {
      (row.vehicleRef[editKey] as any) = updatedData[editKey];
    }
  } else if (typeof rowValue == 'boolean') {
    const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, editKey, !rowValue);

    if (updatedData) {
      (row.vehicleRef[editKey] as any) = updatedData[editKey];
    }
  }
}

async function editRowRestrictions(row: IVehicleTableRow, editKey: VehicleEditRestrictionKey) {
  const restrictions: Record<VehicleEditRestrictionKey, any> = {
    teamOnly: row.vehicleRef.restrictions?.teamOnly ?? undefined,
    sponsorOnly: row.vehicleRef.restrictions?.sponsorOnly ?? undefined,
  };

  if (editKey == VehicleEditRestrictionKey.TEAM_ONLY) {
    restrictions[editKey] = row.vehicleRef.restrictions ? !row.vehicleRef.restrictions[editKey] : true;

    const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'restrictions', restrictions);

    if (updatedData) {
      if (!row.vehicleRef.restrictions) row.vehicleRef.restrictions = {};

      row.vehicleRef.restrictions[editKey] = updatedData.restrictions![editKey];
    }
  }

  if (editKey == VehicleEditRestrictionKey.SPONSOR_ONLY) {
    const promptValue = prompt(
      'Zmień wartość (timestamp):',
      row.vehicleRef.restrictions?.sponsorOnly?.toString() ?? Date.now().toString(),
    );

    if (promptValue == null) return;

    restrictions[editKey] = promptValue.trim() != '' ? parseInt(promptValue) : undefined;

    const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'restrictions', restrictions);

    if (updatedData) {
      if (!row.vehicleRef.restrictions) row.vehicleRef.restrictions = {};

      row.vehicleRef.restrictions[editKey] = updatedData.restrictions![editKey];
    }
  }
}

async function selectRowVehicleGroup(row: IVehicleTableRow) {
  currentEditingGroupId.value = row.vehicleRef.id;

  nextTick(() => {
    if (selectGroup.value) {
      selectGroup.value[0].focus();
    }
  });
}

async function editVehicleGroup(e: Event, row: IVehicleTableRow) {
  const id = (e.target as HTMLSelectElement).value;


  if (row.vehicleRef.group.id !== +id) {
    const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'vehicleGroupId', +id);

    if (updatedData) {
      row.vehicleRef.group = vehiclesStore.vehicleGroupsTable.find(
        (g) => g.vehicleGroupRef.id == updatedData.vehicleGroupsId,
      )!.vehicleGroupRef;
    }
  }

  currentEditingGroupId.value = -1;
}

async function addVehicleRow() {
  const createdVehicleData = await vehiclesStore.createVehicle({
    name: 'Vehicle-' + Date.now(),
    type: 'loco-electric',
    hidden: true,
    vehicleGroupsId: 1,
  });

  if (createdVehicleData) {
    vehiclesStore.vehiclesTable.push({
      vehicleRef: {
        ...createdVehicleData,
        group: vehiclesStore.vehicleGroupsTable.find((g) => g.vehicleGroupRef.id == createdVehicleData.vehicleGroupsId)!
          .vehicleGroupRef,
      },
    });

    vehicleSearchInput.value = createdVehicleData.name;
  }
}

async function removeVehicle(id: number) {
  const confirmRemove = confirm('Czy na pewno chcesz usunąć ten pojazd?');

  if (!confirmRemove) return;

  const removedVehicleData = await vehiclesStore.removeVehicle(id);

  if (removedVehicleData) {
    vehiclesStore.vehiclesTable = vehiclesStore.vehiclesTable.filter((v) => v.vehicleRef.id != id);
  }
}
</script>

<style></style>
