<script lang="ts" setup>
import { QTable, QTableProps, QTableSlots } from 'quasar';
import { Icon } from '@iconify/vue/dist/iconify.js';

import BadgeComponent from 'src/components/BadgeComponent.vue';
import ExpirationDate from 'src/components/03_customer-management/ExpirationDate.vue';

import { baseUrl } from 'src/stores/utils';
import { employeeColumn } from './constants';
import useOptionStore from 'src/stores/options';
import { RequestWork } from 'src/stores/request-list';
import { QuotationFull } from 'src/stores/quotations/types';
import { dateFormatJS, calculateAge } from 'src/utils/datetime';
import { TaskStatus } from 'src/stores/task-order/types';

const props = withDefaults(
  defineProps<{
    validate?: boolean;
    checkboxOn?: boolean;
    checkAll?: boolean;
    stepOn?: boolean;
    rows: QTableProps['rows'];
    grid?: boolean;
  }>(),
  {
    rows: () => [],
    grid: false,
  },
);

const selectedEmployee = defineModel<
  (RequestWork & {
    taskStatus: TaskStatus;
    _template?: {
      id: string;
      templateName: string;
      templateStepName: string;
      step: number;
    } | null;
  })[]
>('selectedEmployee', {
  default: [],
});

defineEmits<{
  (
    e: 'changeAllStatus',
    payload: {
      data: (RequestWork & {
        _template?: {
          id: string;
          templateName: string;
          templateStepName: string;
          step: number;
        } | null;
      })[];
      status: TaskStatus;
    },
  ): void;
}>();

function getEmployeeName(
  record: RequestWork,
  opts?: {
    locale?: string;
  },
) {
  const employee = record.request.employee;

  return (
    {
      ['eng']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstNameEN} ${employee?.lastNameEN}`,
      ['tha']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstName} ${employee?.lastName}`,
    }[opts?.locale || 'eng'] || '-'
  );
}

function goToQuotation(quotation: QuotationFull) {
  const url = new URL('/quotation/view', window.location.origin);

  localStorage.setItem(
    'new-quotation',
    JSON.stringify({
      customerBranchId: quotation.customerBranchId,
      agentPrice: quotation.agentPrice,
      statusDialog: 'info',
      quotationId: quotation.id,
    }),
  );

  window.open(url.toString(), '_blank');
}

function goToRequestList(id: string) {
  const url = new URL(`/request-list/${id}`, window.location.origin);
  window.open(url.toString(), '_blank');
}

function handleCheckAll() {
  const arr = JSON.parse(JSON.stringify(props.rows));
  const shouldExclude = (status: TaskStatus, validate: boolean) =>
    validate
      ? status === TaskStatus.Success ||
        status === TaskStatus.Complete ||
        status === TaskStatus.Redo
      : status === TaskStatus.Failed ||
        status === TaskStatus.Success ||
        status === TaskStatus.Complete ||
        status === TaskStatus.Redo;

  const selectableTasks = arr.filter(
    (
      t: RequestWork & {
        _template?: {
          id: string;
          templateName: string;
          templateStepName: string;
          step: number;
        } | null;
        taskStatus: TaskStatus;
      },
    ) => !shouldExclude(t.taskStatus, props.validate),
  );

  if (selectedEmployee.value.length !== selectableTasks.length) {
    selectedEmployee.value = selectableTasks;
  } else {
    selectedEmployee.value = [];
  }
}

function handleCheck(
  row: RequestWork & {
    _template?: {
      id: string;
      templateName: string;
      templateStepName: string;
      step: number;
    };
    taskStatus: TaskStatus;
  },
) {
  if (
    (!props.validate && row.taskStatus === TaskStatus.Failed) ||
    row.taskStatus === TaskStatus.Success ||
    row.taskStatus === TaskStatus.Complete ||
    row.taskStatus === TaskStatus.Redo ||
    (selectedEmployee.value.length > 0 &&
      selectedEmployee.value.some((v) => v._template?.id !== row._template?.id))
  ) {
    return;
  }

  const index = selectedEmployee.value.findIndex((data) => data.id === row.id);
  if (index !== -1) {
    selectedEmployee.value.splice(index, 1);
  } else {
    selectedEmployee.value.push(row);
  }
}
</script>
<template>
  <q-table
    flat
    bordered
    row-key="id"
    v-bind="props"
    hide-pagination
    class="full-width"
    :selection="!checkboxOn ? undefined : 'multiple'"
    :columns="
      stepOn
        ? [
            ...employeeColumn.slice(0, 2),
            {
              name: 'periodNo',
              align: 'center',
              label: 'flow.step',
              field: (v) => v.product.code,
            },
            ...employeeColumn.slice(2),
          ]
        : employeeColumn
    "
    :rows-per-page-options="[0]"
    :no-data-label="$t('general.noDataTable')"
    v-model:selected="selectedEmployee"
    hide-selected-banner
  >
    <template v-slot:header="props">
      <q-tr
        style="background-color: hsla(var(--info-bg) / 0.07)"
        :props="props"
      >
        <q-th v-if="checkboxOn" class="relative-position">
          <q-checkbox
            v-if="checkAll"
            :model-value="
              selectedEmployee.length > 0 &&
              selectedEmployee.length ===
                (validate
                  ? rows.filter(
                      (t) =>
                        t.taskStatus !== TaskStatus.Complete &&
                        t.taskStatus !== TaskStatus.Success,
                    ).length
                  : rows.filter(
                      (t) =>
                        t.taskStatus !== TaskStatus.Complete &&
                        t.taskStatus !== TaskStatus.Success &&
                        t.taskStatus !== TaskStatus.Failed,
                    ).length)
            "
            @click="handleCheckAll"
            size="sm"
          />
          <div v-if="checkAll" class="absolute-right row items-center">
            <q-btn
              flat
              dense
              rounded
              icon="mdi-chevron-down"
              size="sm"
              class=""
            >
              <q-menu :offset="[0, 4]">
                <q-list v-if="validate">
                  <q-item
                    v-if="
                      !selectedEmployee.some(
                        (e) => e.taskStatus === TaskStatus.Failed,
                      )
                    "
                    clickable
                    v-close-popup
                    class="items-center"
                    @click="
                      $emit('changeAllStatus', {
                        data: selectedEmployee,
                        status: TaskStatus.Complete,
                      })
                    "
                  >
                    <q-icon
                      style="color: hsl(var(--positive-bg))"
                      name="mdi-file-check-outline"
                      class="q-pr-sm"
                      size="xs"
                    ></q-icon>
                    {{ $t(`taskOrder.status.Complete`) }}
                  </q-item>
                  <q-item
                    clickable
                    v-close-popup
                    class="items-center"
                    @click="
                      $emit('changeAllStatus', {
                        data: selectedEmployee,
                        status: TaskStatus.Redo,
                      })
                    "
                  >
                    <q-icon
                      style="color: hsl(var(--negative-bg))"
                      name="mdi-file-remove-outline"
                      class="q-pr-sm"
                      size="xs"
                    ></q-icon>
                    {{ $t(`taskOrder.status.Redo`) }}
                  </q-item>
                </q-list>
                <q-list v-if="!validate" dense>
                  <q-item
                    clickable
                    v-close-popup
                    class="items-center"
                    @click="
                      $emit('changeAllStatus', {
                        data: selectedEmployee,
                        status: TaskStatus.Success,
                      })
                    "
                  >
                    <q-icon
                      style="color: hsl(var(--positive-bg))"
                      name="mdi-file-check-outline"
                      class="q-pr-sm"
                      size="xs"
                    ></q-icon>
                    {{ $t(`taskOrder.status.Success`) }}
                  </q-item>
                  <q-item
                    clickable
                    v-close-popup
                    class="items-center"
                    @click="
                      $emit('changeAllStatus', {
                        data: selectedEmployee,
                        status: TaskStatus.Failed,
                      })
                    "
                  >
                    <q-icon
                      style="color: hsl(var(--negative-bg))"
                      name="mdi-file-remove-outline"
                      class="q-pr-sm"
                      size="xs"
                    ></q-icon>
                    {{ $t(`taskOrder.status.Failed`) }}
                  </q-item>
                </q-list>
              </q-menu>
            </q-btn>
          </div>
        </q-th>
        <q-th v-for="col in props.cols" :key="col.name" :props="props">
          {{ col.label && $t(col.label) }}
        </q-th>
        <q-th></q-th>
        <q-th v-if="$slots.append"></q-th>

        <q-th v-if="$slots.action"></q-th>
      </q-tr>
    </template>

    <template
      v-slot:body="props: {
        row: RequestWork & {
          _template?: {
            id: string;
            templateName: string;
            templateStepName: string;
            step: number;
          };
          taskStatus: TaskStatus;
        };
      } & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
    >
      <q-tr
        :class="{
          urgent: props.row.request.quotation.urgent,
          dark: $q.dark.isActive,
          ['disabled-row']:
            selectedEmployee.length > 0 &&
            selectedEmployee.some(
              (v) => v._template?.id !== props.row._template?.id,
            ),
        }"
        class="text-center"
      >
        <q-td v-if="checkboxOn">
          <q-checkbox
            :model-value="selectedEmployee.some((t) => t.id === props.row.id)"
            @click="handleCheck(props.row)"
            size="sm"
            :disable="
              (!validate && props.row.taskStatus === TaskStatus.Failed) ||
              props.row.taskStatus === TaskStatus.Success ||
              props.row.taskStatus === TaskStatus.Complete ||
              props.row.taskStatus === TaskStatus.Redo ||
              (selectedEmployee.length > 0 &&
                selectedEmployee.some(
                  (v) => v._template?.id !== props.row._template?.id,
                ))
            "
          />
        </q-td>
        <q-td>
          {{ props.rowIndex + 1 }}
        </q-td>
        <q-td>
          <span
            class="cursor-pointer link"
            @click="goToRequestList(props.row.request.id)"
          >
            {{ props.row.request.code }}
          </span>
        </q-td>
        <q-td v-if="stepOn" class="text-left">
          <div v-if="props.row._template" class="column text-left">
            <span>{{ props.row._template.templateName }}</span>
            <span class="app-text-muted text-caption">
              {{ $t('flow.stepNo', { msg: props.row._template.step }) }}
              {{ props.row._template.templateStepName }}
            </span>
          </div>
          <span v-else>-</span>
        </q-td>
        <q-td>
          <div class="row items-center no-wrap">
            <q-avatar class="q-mr-sm" size="md">
              <q-img
                class="text-center"
                :ratio="1"
                :src="`${baseUrl}/employee/${props.row.request.employee.id}/image/${props.row.request.employee.selectedImage}`"
              >
                <template #error>
                  <span class="full-width full-height">
                    <q-img src="/images/employee-avatar.png" />
                  </span>
                </template>
              </q-img>
            </q-avatar>
            <div class="column text-left q-ml-sm">
              <div>
                {{ getEmployeeName(props.row, { locale: $i18n.locale }) }}
              </div>

              <div class="app-text-muted">
                {{ props.row.request.employee.code }}
              </div>
            </div>
            <Icon
              class="q-ml-md"
              :class="`app-text-${props.row.request.employee.gender}`"
              :icon="`material-symbols:${props.row.request.employee.gender}`"
              width="24px"
            />
          </div>
        </q-td>
        <q-td>{{ calculateAge(props.row.request.employee.dateOfBirth) }}</q-td>
        <q-td>
          {{
            useOptionStore().mapOption(props.row.request.employee.nationality)
          }}
        </q-td>
        <q-td>
          {{
            dateFormatJS({
              date: props.row.request.quotation.dueDate,
              locale: $i18n.locale,
              dayStyle: '2-digit',
              monthStyle: 'short',
            })
          }}
        </q-td>
        <q-td>
          <ExpirationDate
            :expiration-date="new Date(props.row.request.quotation.dueDate)"
          />
        </q-td>
        <q-td>
          <span
            class="cursor-pointer link"
            @click="goToQuotation(props.row.request.quotation)"
          >
            {{ props.row.request.quotation.code }}
          </span>
        </q-td>
        <q-td>
          <BadgeComponent
            v-if="props.row.request.quotation.urgent"
            icon="mdi-fire"
            :title="$t('general.urgent2')"
            hsla-color="--gray-1-hsl"
            hsla-background="--red-8-hsl"
            solid
          />
        </q-td>
        <q-td v-if="$slots.append">
          <slot name="append" :props="props"></slot>
        </q-td>

        <q-td v-if="$slots.action">
          <slot name="action" :props="props"></slot>
        </q-td>
      </q-tr>
    </template>

    <!-- <template v-slot:item="props"></template> -->
  </q-table>
</template>

<style scoped>
:deep(tr:nth-child(2n)) {
  background: #f9fafc;
  &.dark {
    background: hsl(var(--gray-11-hsl) / 0.2);
  }
}

.q-table tr.urgent {
  background: hsla(var(--red-6-hsl) / 0.03);
}

.q-table tr.urgent td:first-child {
  &::after {
    content: ' ';
    display: block;
    position: absolute;
    left: 0;
    top: 15%;
    bottom: 15%;
    background: var(--red-8);
    width: 4px;
    border-radius: 99rem;
    animation: blink 1s infinite;
  }
}

@keyframes blink {
  0% {
    background: var(--red-8);
  }
  50% {
    background: var(--red-3);
  }
  100% {
    background: var(--red-8);
  }
}

.link {
  color: hsl(var(--info-bg));
  text-decoration: underline;
}

.disabled-row {
  opacity: 0.3;
  filter: grayscale(1);
}

:deep(.q-table tbody td:after) {
  background: transparent;
}
</style>
