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

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

import { QTableSlots, QTableColumn } from 'quasar';
import { Product, Service } from 'src/stores/product-service/types';

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

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

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

const priceDisplay = computed(() => ({
  price: !isRoleInclude(['sale_agent']),
  agentPrice: isRoleInclude([
    'admin',
    'head_of_admin',
    'head_of_sale',
    'system',
    'owner',
    'accountant',
    'sale_agent',
  ]),
  serviceCharge: isRoleInclude([
    'admin',
    'head_of_admin',
    'system',
    'owner',
    'accountant',
  ]),
}));

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

type ExclusiveProps = {
  type: 'service' | 'product';
  grid?: boolean;
  disabledWorkerId?: string[];
  disabledProductFields?: (typeof columnsProduct)[number]['name'][];
  disabledServiceFields?: (typeof columnsService)[number]['name'][];
  rows: Product[];
};

const columnsProduct = [
  {
    name: '#check',
    align: 'left',
    label: '',
    field: (_) => '#check',
  },

  {
    name: 'order',
    align: 'center',
    label: 'general.order',
    field: (e: Product & { _index: number }) => e._index + 1,
  },

  {
    name: '#productName',
    align: 'left',
    label: 'general.name',
    field: (v: Product) => v.name,
  },

  {
    name: 'productProcessingTime',
    align: 'center',
    label: 'productService.product.processingTimeDay',
    field: (v: Product) => v.process,
  },

  {
    name: '#priceInformation',
    align: 'center',
    label: 'productService.product.priceInformation',
    field: (v: Product) => v,
  },
] as const satisfies QTableColumn[];

const columnsService = [
  {
    name: '#check',
    align: 'left',
    label: '',
    field: (_) => '#check',
  },
  {
    name: 'order',
    align: 'center',
    label: 'general.order',
    field: (e: Service & { _index: number }) => e._index + 1,
  },

  {
    name: '#serviceName',
    align: 'left',
    label: 'general.name',
    field: (v: Service) => v.name,
  },
  {
    name: 'serviceDetail',
    align: 'left',
    label: 'general.detail',
    field: (v: Service) => v.detail,
  },
  {
    name: 'serviceWorkTotal',
    align: 'left',
    label: 'productService.service.totalWork',
    field: (v: Service) => v.work.length,
  },
  {
    name: 'createdAt',
    align: 'left',
    label: 'general.createdAt',
    field: (v: Service) => dateFormatJS({ date: v.createdAt }),
  },
] as const satisfies QTableColumn[];

const props = defineProps<ExclusiveProps>();

function getProductImageUrl(
  item: (Product | Service) & { type: string; _index: number },
) {
  if (item.selectedImage) {
    return `${API_BASE_URL}/${item.type}/${item?.id}/image/${item?.selectedImage}`;
  }
  // NOTE: static image
  return `/images/${item.type}-avatar.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: any) {
  return selected.value?.findIndex((v: any) => 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="type === 'product' ? columnsProduct : columnsService"
    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 type === 'product'
            ? columnsProduct.filter((v) =>
                disabledProductFields
                  ? !disabledProductFields.includes(v.name)
                  : true,
              )
            : columnsService.filter((v) =>
                disabledServiceFields
                  ? !disabledServiceFields.includes(v.name)
                  : true,
              )"
          :auto-width="col.name === '#check'"
          :key="col.name"
          :props="props"
        >
          <template v-if="!col.name.startsWith('#')">
            {{ $t(col.label) }}
          </template>

          <template
            v-if="
              col.name === '#serviceName' ||
              col.name === '#productName' ||
              col.name === '#priceInformation'
            "
          >
            {{ $t(col.label) }}
          </template>

          <template v-if="col.name === '#check'">
            <q-checkbox
              v-model="props.selected"
              @update:model-value="(v) => handleUpdate()"
              size="sm"
            />
          </template>
        </q-th>
      </q-tr>
    </template>

    <template
      v-slot:body="props: {
        row: (Product | Service) & { type: string; _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 type === 'product'
            ? columnsProduct.filter((v) =>
                disabledProductFields
                  ? !disabledProductFields.includes(v.name)
                  : true,
              )
            : columnsService.filter((v) =>
                disabledServiceFields
                  ? !disabledServiceFields.includes(v.name)
                  : true,
              )"
          :align="col.align"
          :key="col.name"
        >
          <!-- NOTE: custom column will starts with # -->
          <template v-if="!col.name.startsWith('#')">
            <span v-if="col.name === 'serviceDetail'">
              {{ props.row.detail.replace(/<\/?[^>]+(>|$)/g, '') || '-' }}
            </span>
            <span v-else>
              {{
                typeof col.field === 'string'
                  ? props.row[col.field as keyof (Product | Service)]
                  : col.field(props.row as any)
              }}
            </span>
          </template>

          <template
            v-if="col.name === '#productName' || col.name === '#serviceName'"
          >
            <div class="row full-height items-center">
              <q-avatar size="md">
                <q-img
                  :src="getProductImageUrl(props.row)"
                  :ratio="1"
                  class="text-center"
                />
              </q-avatar>
              <span class="column q-ml-sm">
                <span class="col-6">
                  {{ props.row.name }}
                </span>
                <span class="col-6 app-text-muted">
                  {{ props.row.code }}
                </span>
              </span>
            </div>
          </template>

          <template
            v-if="
              col.name === '#priceInformation' &&
              !disabledWorkerId?.some((id) => id === props.row.id)
            "
          >
            <div
              class="row full-width q-gutter-x-md no-wrap items-center text-right"
            >
              <div
                class="tags tags-color-orange col column ellipsis-2-lines"
                :class="{
                  disable: props.row.status === 'INACTIVE',
                }"
                style="min-width: 50px"
                v-if="priceDisplay.price"
              >
                <div class="col app-text-muted-2 text-caption">
                  {{ $t('productService.product.salePrice') }}
                </div>
                <div class="col text-weight-bold">
                  ฿{{ formatNumberDecimal(props.row.price || 0, 2) }}
                </div>
              </div>
              <div
                class="tags tags-color-purple col column ellipsis-2-lines"
                :class="{
                  disable: props.row.status === 'INACTIVE',
                }"
                style="min-width: 50px"
                v-if="priceDisplay.agentPrice"
              >
                <div class="col app-text-muted-2 text-caption">
                  {{ $t('productService.product.agentPrice') }}
                </div>
                <div class="col text-weight-bold">
                  ฿{{ formatNumberDecimal(props.row.agentPrice || 0, 2) }}
                </div>
              </div>
              <div
                class="tags tags-color-pink col column ellipsis-2-lines"
                :class="{
                  disable: props.row.status === 'INACTIVE',
                }"
                style="min-width: 50px"
                v-if="priceDisplay.serviceCharge"
              >
                <div class="col app-text-muted-2 text-caption">
                  {{ $t('productService.product.processingPrice') }}
                </div>
                <div class="col">
                  ฿{{ formatNumberDecimal(props.row.serviceCharge || 0, 2) }}
                </div>
              </div>
            </div>
          </template>

          <template
            v-if="
              col.name === '#check' &&
              !disabledWorkerId?.some((id) => id === props.row.id)
            "
          >
            <q-checkbox v-model="props.selected" size="sm" />
          </template>
        </q-td>
      </q-tr>
    </template>
    <template v-slot:item="props: { row: any; rowIndex: number }">
      <slot
        name="grid"
        :item="{
          index: props.rowIndex,
          ...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;
  }
}

.tags {
  display: inline-block;
  color: hsla(var(--_color-tag) / 1);
  background: hsla(var(--_color-tag) / 0.075);
  border-radius: var(--radius-2);
  padding-inline: var(--size-2);

  &.disable {
    filter: grayscale(100%);
    opacity: 80%;
  }
}

.tags-color-green {
  --_color-tag: var(--teal-10-hsl);
}

.dark .tags-color-green {
  --_color-tag: var(--teal-8-hsl);
}

.tags-color-orange {
  --_color-tag: var(--orange-5-hsl);
}

.dark .tags-color-orange {
  --_color-tag: var(--orange-6-hsl);
}

.tags-color-purple {
  --_color-tag: var(--violet-11-hsl);
}

.dark .tags-color-purple {
  --_color-tag: var(--violet-10-hsl);
}

.tags-color-pink {
  --_color-tag: var(--pink-6-hsl);
}
</style>
