<script setup lang="ts">
import { useI18n } from 'vue-i18n';

import { Lang } from 'src/utils/ui';

import { QTableSlots, QTableColumn } from 'quasar';
import { Employee } from 'src/stores/employee/types';

import { calculateAge, dateFormatJS } from 'src/utils/datetime';
import useOptionStore from 'stores/options';

const selected = defineModel<Employee[]>('selected');

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
const { locale } = useI18n();
const optionStore = useOptionStore();

defineEmits<{
  (e: 'create'): void;
}>();

type ExclusiveProps = {
  grid?: boolean;
  disabledWorkerId?: string[];
  rows: Employee[];
};

const columns = [
  {
    name: '#check',
    align: 'left',
    label: '',
    field: (_: any) => '#check',
  },
  {
    name: 'order',
    align: 'center',
    label: 'general.order',
    field: (e: Employee & { _index: number }) => e._index + 1,
  },
  {
    name: 'foreignRefNo',
    align: 'center',
    label: 'quotation.foreignRefNo',
    field: (v: Employee) =>
      v.employeePassport !== undefined
        ? v.employeePassport[0]?.number || '-'
        : '-',
  },
  {
    name: 'employeeName',
    align: 'left',
    label: 'quotation.employeeName',
    field: (v: Employee) =>
      locale.value === Lang.English
        ? `${v.firstNameEN} ${v.lastNameEN}`
        : v.firstName
          ? `${v.firstName} ${v.lastName}`
          : `${v.firstNameEN} ${v.lastNameEN}`,
  },
  {
    name: 'birthDate',
    align: 'left',
    label: 'general.birthDate',
    field: (v: Employee) => dateFormatJS({ date: v.dateOfBirth }),
  },
  {
    name: 'age',
    align: 'left',
    label: 'general.age',
    field: (v: Employee) => calculateAge(v.dateOfBirth),
  },
  {
    name: 'nationality',
    align: 'left',
    label: 'general.nationality',
    field: (v: Employee) => optionStore.mapOption(v.nationality),
  },
  {
    name: 'documentExpireDate',
    align: 'left',
    label: 'quotation.documentExpireDate',
    field: (v: Employee) =>
      v.employeePassport !== undefined &&
      v.employeePassport[0]?.expireDate !== undefined
        ? dateFormatJS({ date: v.employeePassport[0]?.expireDate })
        : '-',
  },
] satisfies QTableColumn[];

const props = defineProps<ExclusiveProps>();

function getEmployeeImageUrl(item: Employee) {
  if (item.selectedImage) {
    return `${API_BASE_URL}/employee/${item.id}/image/${item.selectedImage}`;
  }
  // NOTE: static image
  return `/images/employee-avatar-${item.gender}.png`;
}

function handleUpdate() {
  if (selected.value?.length === 0) {
    selected.value = props.rows?.filter(
      (v) => !props.disabledWorkerId?.includes(v.id),
    );
  } else {
    selected.value = [];
  }
}

function selectedIndex(item: Employee) {
  return selected.value?.findIndex((v) => v.id === item.id);
}
</script>
<template>
  <q-table
    v-model:selected="selected"
    :rows-per-page-options="[0]"
    :rows="
      rows.map((data, i) => ({
        ...data,
        _index: i,
      }))
    "
    :grid
    :columns
    hide-bottom
    bordered
    flat
    hide-pagination
    selection="multiple"
    card-container-class="q-col-gutter-sm"
    class="full-width"
    row-key="id"
  >
    <template v-slot:header="props">
      <q-tr
        style="background-color: hsla(var(--info-bg) / 0.07)"
        :props="props"
      >
        <q-th v-for="col in columns" :key="col.name" :props="props">
          <template v-if="!col.name.startsWith('#')">
            {{ $t(col.label) }}
          </template>
          <template v-if="col.name === '#check'">
            <q-checkbox
              id="select-worker-all"
              for="select-worker-all"
              v-model="props.selected"
              @update:model-value="(v) => handleUpdate()"
              size="sm"
            />
          </template>
        </q-th>
      </q-tr>
    </template>

    <template
      v-slot:body="props: {
        row: Employee & { _index: number };
      } & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
    >
      <q-tr
        :class="{
          dark: $q.dark.isActive,
          'selectable-item__disabled': disabledWorkerId?.some(
            (id) => id === props.row.id,
          ),
        }"
        class="text-center"
      >
        <q-td v-for="col in columns" :align="col.align" :key="col.name">
          <!-- NOTE: custom column will starts with # -->
          <template v-if="!col.name.startsWith('#')">
            <q-avatar
              v-if="col.name === 'employeeName'"
              class="q-mr-sm"
              size="md"
            >
              <q-img
                :src="getEmployeeImageUrl(props.row)"
                :ratio="1"
                class="text-center"
              />
            </q-avatar>
            <span>
              {{
                typeof col.field === 'string'
                  ? props.row[col.field as keyof Employee]
                  : col.field(props.row)
              }}
            </span>
          </template>
          <template
            v-if="
              col.name === '#check' &&
              !disabledWorkerId?.some((id) => id === props.row.id)
            "
          >
            <q-checkbox
              v-model="props.selected"
              size="sm"
              :id="`select-worker-${props.row.firstName}`"
              :for="`select-worker-${props.row.firstName}`"
            />
          </template>
        </q-td>
      </q-tr>
    </template>
    <template v-slot:item="props: { row: Employee; rowIndex: number }">
      <slot
        name="grid"
        :index="props.rowIndex"
        :item="{ ...props.row, _selectedIndex: selectedIndex(props.row) }"
      />
    </template>
  </q-table>
</template>

<style scoped>
.selectable-item__disabled {
  filter: grayscale(1);
  opacity: 0.5;

  & :deep(*) {
    cursor: not-allowed;
  }
}
</style>
