<script lang="ts" setup>
import { ref, watch } from 'vue';
import { QTableProps } from 'quasar';
import { storeToRefs } from 'pinia';

import WorkerItem from './WorkerItem.vue';
import DeleteButton from '../button/DeleteButton.vue';
import { precisionRound } from 'src/utils/arithmetic';
import { QuotationPayload } from 'stores/quotations/types';
import { formatNumberDecimal, commaInput } from 'stores/utils';
import { useConfigStore } from 'stores/config';

const props = defineProps<{
  readonly?: boolean;
  agentPrice: boolean;
  installmentInput?: boolean;
  employeeRows?: {
    foreignRefNo: string;
    employeeName: string;
    birthDate: string;
    gender: string;
    age: string;
    nationality: string;
    documentExpireDate: string;
    imgUrl: string;
    status: string;
  }[];
}>();

defineEmits<{
  (e: 'delete', index: number): void;
}>();

const configStore = useConfigStore();
const { data: config } = storeToRefs(configStore);

const rows = defineModel<
  Required<QuotationPayload['productServiceList'][number]>[]
>('rows', { required: true });

const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
  { title: '', opened: [] },
]);

function calcPrice(c: (typeof rows.value)[number]) {
  return precisionRound(
    c.pricePerUnit * c.amount -
      c.discount +
      (c.product.calcVat
        ? (c.pricePerUnit * c.amount - c.discount) * (config.value?.vat || 0.07)
        : 0),
  );
}

const discount4Show = ref<string[]>([]);

const columns = [
  {
    name: 'order',
    align: 'center',
    label: 'general.order',
    field: 'order',
  },
  {
    name: 'code',
    align: 'left',
    label: 'general.code',
    field: (v) => v.product.code,
  },
  {
    name: 'name',
    align: 'center',
    label: 'productService.service.list',
    field: (v) => v.product.name,
  },
  {
    name: 'amount',
    align: 'center',
    label: 'general.amount',
    field: 'amount',
  },
  {
    name: 'pricePerUnit',
    align: 'right',
    label: 'quotation.pricePerUnit',
    field: 'pricePerUnit',
  },
  {
    name: 'discount',
    align: 'center',
    label: 'general.discount',
    field: 'discount',
  },
  {
    name: 'priceBeforeVat',
    align: 'center',
    label: 'quotation.priceBeforeVat',
    field: 'priceBeforeVat',
  },
  {
    name: 'tax',
    align: 'center',
    label: 'general.vat',
    field: 'tax',
  },
  {
    name: 'sumPrice',
    align: 'right',
    label: 'quotation.sumPrice',
    field: 'sumPrice',
  },
] satisfies QTableProps['columns'];

function openEmployeeTable(title: string, index: number) {
  currentBtnOpen.value[0].title = title;
  currentBtnOpen.value[0].opened.map((_, i) => {
    if (i !== index) {
      currentBtnOpen.value[0].opened[i] = false;
    }
  });

  currentBtnOpen.value[0].opened[index] =
    !currentBtnOpen.value[0].opened[index];
}

function groupByServiceId(data: typeof rows.value) {
  if (data.length === 0) return;
  const groupedItems: {
    title: string;
    product: QuotationPayload['productServiceList'][number][];
  }[] = [];
  let noServiceGroup: QuotationPayload['productServiceList'][number][] = [];
  let currentServiceId: string | null = null;
  let currentServiceName: string | null = null;
  let serviceFlag: boolean = false;

  data.forEach((item) => {
    if (item.service) {
      if (noServiceGroup.length > 0) {
        // console.log('push p changmode');
        groupedItems.push({
          title: `_product${groupedItems.length}`,
          product: noServiceGroup,
        });
        noServiceGroup = [];
        currentServiceId = null;
        currentServiceName = null;
      }

      if (currentServiceId !== null && currentServiceId !== item.service.id) {
        // console.log('push s chageS');
        groupedItems.push({
          title: currentServiceName || '',
          product: rows.value.filter((i) => i.service?.id === currentServiceId),
        });
      }

      // console.log('set id');
      currentServiceId = item.service.id;
      currentServiceName = item.service.name;
      serviceFlag = true;
    } else {
      // console.log('push s chagemode');
      serviceFlag &&
        groupedItems.push({
          title: currentServiceName || '',
          product: rows.value.filter((i) => i.service?.id === currentServiceId),
        });
      noServiceGroup.push(item);
      serviceFlag = false;
    }
  });

  if (serviceFlag && currentServiceId !== null) {
    // console.log('push s last');
    groupedItems.push({
      title: currentServiceName || '',
      product: rows.value.filter((i) => i.service?.id === currentServiceId),
    });
  }

  if (noServiceGroup.length > 0) {
    // console.log('push p last');
    groupedItems.push({
      title: `_product${groupedItems.length}`,
      product: noServiceGroup,
    });
  }

  return groupedItems;
}

function handleCheck(
  index: number,
  data: QuotationPayload['productServiceList'][number],
) {
  const target = data.workerIndex.indexOf(index);
  if (target > -1) {
    data.amount -= 1;
    data.workerIndex.splice(target, 1);
  } else {
    data.workerIndex.push(index);
    data.amount += 1;
  }
}

watch(
  () => props.employeeRows,
  (a, b) => {
    if (a === undefined || b === undefined) return;

    const removed = b.findIndex(
      (c) => !a.find((d) => JSON.stringify(c) === JSON.stringify(d)),
    );

    if (a.length < b.length) {
      rows.value.forEach((p) => {
        const maxValue = Math.max(...p.workerIndex);
        if (removed !== -1) {
          p.workerIndex = p.workerIndex.map((i) => (i > removed ? i - 1 : i));
        }
        p.workerIndex = p.workerIndex.filter((i) => i !== maxValue);
      });
    }
  },
);
</script>
<template>
  <div class="column">
    <div class="full-width">
      <section
        v-for="(item, i) in groupByServiceId(
          rows.map((v, i) => Object.assign(v, { i })),
        ) || [{ title: '', product: [] }]"
        :key="i"
        class="q-pb-md"
      >
        <q-table
          flat
          bordered
          hide-pagination
          :columns="
            installmentInput
              ? [
                  ...columns.slice(0, 1),
                  {
                    name: 'periodNo',
                    align: 'left',
                    label: 'quotation.periodNo',
                    field: (v) => v.product.code,
                  },
                  ...columns.slice(1),
                ]
              : columns
          "
          :rows="item.product"
          class="full-width"
          :no-data-label="$t('general.noDataTable')"
          :pagination="{
            rowsPerPage: 0,
          }"
        >
          <template #header="{ cols }">
            <q-tr style="background-color: hsla(var(--info-bg) / 0.07)">
              <q-th v-for="v in cols" :key="v">
                {{ $t(v.label) }}
              </q-th>
              <q-th auto-width />
            </q-tr>
          </template>

          <template #body="props">
            <q-tr>
              <q-td class="text-center">{{ props.rowIndex + 1 }}</q-td>
              <q-td v-if="installmentInput">
                <q-input
                  v-model="props.row.installmentNo"
                  :readonly
                  :bg-color="readonly ? 'transparent' : ''"
                  dense
                  min="0"
                  outlined
                  input-class="text-right"
                  type="number"
                  style="width: 60px"
                ></q-input>
              </q-td>
              <q-td>{{ props.row.product.code }}</q-td>
              <q-td style="width: 100%">
                <q-avatar class="q-mr-sm" size="md">
                  <q-icon
                    class="full-width full-height"
                    name="mdi-shopping-outline"
                    :style="`color: var(--teal-10); background: hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
                  />
                </q-avatar>
                {{ props.row.product.name }}
              </q-td>
              <q-td align="center">
                <q-input
                  :readonly
                  :bg-color="readonly ? 'transparent' : ''"
                  dense
                  outlined
                  :type="readonly ? 'text' : 'number'"
                  style="width: 70px"
                  min="0"
                  debounce="500"
                  v-model="props.row.amount"
                />
              </q-td>
              <q-td align="right">
                {{
                  formatNumberDecimal(
                    props.row.pricePerUnit +
                      (props.row.product.calcVat
                        ? props.row.pricePerUnit * (config?.vat || 0.07)
                        : 0),
                    2,
                  )
                }}
              </q-td>
              <q-td align="center">
                <q-input
                  :readonly
                  :bg-color="readonly ? 'transparent' : ''"
                  dense
                  min="0"
                  outlined
                  input-class="text-right"
                  style="width: 90px"
                  debounce="500"
                  :model-value="
                    commaInput(props.row.discount.toString() || '0')
                  "
                  @update:model-value="
                    (v) => {
                      if (typeof v === 'string')
                        discount4Show[props.rowIndex] = commaInput(v);
                      const x = parseFloat(
                        discount4Show[props.rowIndex] &&
                          typeof discount4Show[props.rowIndex] === 'string'
                          ? discount4Show[props.rowIndex].replace(/,/g, '')
                          : '',
                      );
                      props.row.discount = x;
                    }
                  "
                />
              </q-td>
              <q-td align="right">
                {{ formatNumberDecimal(props.row.pricePerUnit, 2) }}
              </q-td>
              <q-td align="right">
                {{
                  formatNumberDecimal(
                    props.row.product.calcVat
                      ? precisionRound(
                          (props.row.pricePerUnit * props.row.amount -
                            props.row.discount) *
                            (config?.vat || 0.07),
                        )
                      : 0,
                    2,
                  )
                }}
              </q-td>
              <q-td align="right">
                {{ formatNumberDecimal(calcPrice(props.row), 2) }}
              </q-td>
              <q-td>
                <div
                  class="row items-center full-width justify-end no-wrap"
                  v-if="!readonly"
                >
                  <q-btn
                    @click.stop="openEmployeeTable(item.title, props.rowIndex)"
                    dense
                    flat
                    size="sm"
                    class="rounded q-mr-xs"
                  >
                    <div class="row items-center no-wrap">
                      <q-icon name="mdi-account-group-outline" />
                      <q-icon
                        size="xs"
                        :name="`mdi-chevron-${currentBtnOpen[0].title === item.title && currentBtnOpen[0].opened[props.rowIndex] ? 'down' : 'up'}`"
                      />
                    </div>
                  </q-btn>
                  <q-btn
                    icon="mdi-monitor"
                    size="sm"
                    class="rounded q-mr-xs"
                    padding="4px 8px"
                    dense
                    flat
                    style="
                      background-color: hsla(var(--positive-bg) / 0.1);
                      color: hsl(var(--positive-bg));
                    "
                  />
                  <DeleteButton
                    iconOnly
                    @click="$emit('delete', props.row.i)"
                  />
                </div>
              </q-td>
            </q-tr>

            <q-tr
              v-show="
                currentBtnOpen[0].title === item.title &&
                currentBtnOpen[0].opened[props.rowIndex]
              "
              :props="props"
            >
              <q-td colspan="100%" style="padding: 16px">
                <WorkerItem
                  @check="(wokerIndex) => handleCheck(wokerIndex, props.row)"
                  checkable
                  fallback-img="/images/employee-avatar.png"
                  inTable
                  hideQuantity
                  :check-list="props.row.workerIndex"
                  :rows="employeeRows"
                />
              </q-td>
            </q-tr>
          </template>
        </q-table>
      </section>
    </div>
  </div>
</template>

<style scoped>
.bg-color-orange-light {
  --_color: var(--yellow-7-hsl);
  background: hsla(var(--_color) / 0.2);
}

.bg-color-orange {
  --_color: var(--yellow-7-hsl);
  color: white;
  background: hsla(var(--_color));
}

.dark .bg-color-orange {
  --_color: var(--orange-6-hsl / 0.2);
}

.worker-item {
  --side-color: var(--brand-1);
  position: relative;
  overflow-x: hidden;

  &.worker-item__female {
    --side-color: hsl(var(--gender-female));
  }

  &.worker-item__male {
    --side-color: hsl(var(--gender-male));
  }
}

:deep(.price-tag .q-field__control) {
  display: flex;
  align-items: center;
  height: 25px;
}

.worker-item::before {
  position: absolute;
  content: ' ';
  left: 0;
  width: 7px;
  top: 0;
  bottom: 0;
  background: var(--side-color);
}

:deep(i.q-icon.mdi.mdi-alert.q-table__bottom-nodata-icon) {
  color: #ffc224 !important;
}
</style>
