<script setup lang="ts">
import { ref, watch, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { onMounted } from 'vue';
import { getUserId, getRole } from 'src/services/keycloak';
import { storeToRefs } from 'pinia';
import { useQuasar, type QTableProps } from 'quasar';

import ProductCardComponent from 'components/04_product-service/ProductCardComponent.vue';
import StatCard from 'components/StatCardComponent.vue';
import DrawerInfo from 'components/DrawerInfo.vue';
import BasicInformation from 'components/04_product-service/BasicInformation.vue';
import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
import BasicInfoProduct from 'components/04_product-service/BasicInfoProduct.vue';
import PriceDataComponent from 'components/04_product-service/PriceDataComponent.vue';
import TotalProductCardComponent from 'components/04_product-service/TotalProductCardComponent.vue';
import FormServiceWork from 'components/04_product-service/FormServiceWork.vue';
import ServiceProperties from 'components/04_product-service/ServiceProperties.vue';
import WorkNameManagement from 'components/04_product-service/WorkNameManagement.vue';
import useOptionStore from 'stores/options';
import FormServiceProperties from 'components/04_product-service/FormServiceProperties.vue';
import InfoForm from 'components/02_personnel-management/InfoForm.vue';
import NoData from 'components/NoData.vue';
import PaginationComponent from 'components/PaginationComponent.vue';
import TreeComponent from 'components/TreeComponent.vue';
import DialogForm from 'components/DialogForm.vue';
import ProfileBanner from 'components/ProfileBanner.vue';
import SideMenu from 'components/SideMenu.vue';
import ImageUploadDialog from 'components/ImageUploadDialog.vue';
import KebabAction from 'src/components/shared/KebabAction.vue';
import {
  EditButton,
  DeleteButton,
  SaveButton,
  UndoButton,
  ToggleButton,
} from 'components/button';

import useFlowStore from 'stores/flow';
import useMyBranchStore from 'stores/my-branch';

import { dateFormat } from 'src/utils/datetime';
import { formatNumberDecimal, isRoleInclude } from 'stores/utils';

const userBranchStore = useMyBranchStore();

const { currentMyBranch } = storeToRefs(userBranchStore);

import { Status } from 'stores/types';

import useUtilsStore, { dialog, dialogWarningClose } from 'stores/utils';

import useProductServiceStore from 'stores/product-service';
import {
  ProductGroup,
  ProductGroupCreate,
  ProductCreate,
  ProductList,
  ServiceCreate,
  Service,
  ServiceById,
  WorkItems,
  Attributes,
} from 'stores/product-service/types';
import { computed } from 'vue';

const flowStore = useFlowStore();
const utilsStore = useUtilsStore();
const productServiceStore = useProductServiceStore();
const optionStore = useOptionStore();

const {
  fetchStatsProductGroup,
  fetchListProductService,
  createProductService,
  editProductService,
  deleteProductService,

  fetchStatsProduct,
  fetchListProduct,
  createProduct,
  editProduct,
  deleteProduct,

  fetchStatsService,
  fetchListService,
  fetchListServiceById,
  createService,
  deleteService,
  editService,

  createWork,
  editWork,
  deleteWork,
} = productServiceStore;

const { workNameItems } = storeToRefs(productServiceStore);

const allStat = ref<{ mode: string; count: number }[]>([]);
const stat = ref<
  {
    icon: string;
    count: number;
    label: string;
    mode: 'group' | 'service' | 'product';
    color: 'pink' | 'green' | 'orange';
  }[]
>([
  {
    icon: 'mdi-folder-outline',
    count: 0,
    label: 'productService.group.title',
    mode: 'group',
    color: 'pink',
  },
  {
    icon: 'mdi-server-outline',
    count: 0,
    label: 'productService.service.title',
    mode: 'service',
    color: 'orange',
  },
  {
    icon: 'mdi-shopping-outline',
    count: 0,
    label: 'productService.product.title',
    mode: 'product',
    color: 'green',
  },
]);

const { t } = useI18n();
const baseUrl = ref<string>(import.meta.env.VITE_API_BASE_URL);

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',
  ]),
}));
const actionDisplay = computed(() =>
  isRoleInclude(['admin', 'head_of_admin', 'system', 'owner', 'accountant']),
);
const holdDialog = ref(false);
const imageDialog = ref(false);
const currentNode = ref<ProductGroup & { type: string }>();
const expandedTree = ref<string[]>([]);
const editByTree = ref<'group' | 'type' | undefined>();

const treeProductTypeAndGroup = computed(
  () =>
    productGroup.value?.map((item) => ({
      ...item,
      _count: {
        service: item._count.service,
        product: item._count.product,
      },
      type: 'group',
      actionDisabled: false,
      // actionDisabled: item.status === 'INACTIVE',
      children: [
        {
          id: 'type',
          name: t('general.type'),
          type: 'type',
          actionDisabled: true,
          for: item.name,
        },
        {
          id: 'productService',
          name: t('productService.title'),
          type: 'productService',
          actionDisabled: true,
          for: item.name,
        },
      ],
    })) ?? [],
);

const profileFileImg = ref<File | null>(null);
const refImageUpload = ref<InstanceType<typeof ImageUploadDialog>>();

const inputSearch = ref('');
const inputSearchProductAndService = ref('');

const currentStatusProduct = ref(false);
const drawerInfo = ref(false);
const isEdit = ref(false);

const modeView = ref(false);
const splitterModel = ref(25);

const dialogInputForm = ref(false);
const dialogProduct = ref(false);
const dialogService = ref(false);
const dialogProductEdit = ref(false);
const dialogServiceEdit = ref(false);

const statusToggle = ref(false);
const profileSubmit = ref(false);
const infoProductEdit = ref(false);
const infoServiceEdit = ref(false);

const imageProduct = ref<File | undefined>(undefined);
const profileUrl = ref<string | null>('');

const pathGroupName = ref('');
const pathTypeName = ref('');

const dialogTotalProduct = ref(false);
const productMode = ref<'group' | 'service' | 'product'>('group');

const productTab = ref(1);
const productGroup = ref<ProductGroup[]>();
const product = ref<(ProductList & { type: 'product' })[]>();
const productIsAdd = ref<(ProductList & { type: 'product' })[]>();
const service = ref<(Service & { type: 'service' })[]>();
const resultSearchProduct = ref<ProductList[]>();

const productAndServiceTab = ref<'product' | 'service'>('service');
const manageWorkNameDialog = ref(false);
const previousValue = ref();

const propertiesOption = ref();

const formDataGroup = ref<ProductGroupCreate>({
  remark: '',
  detail: '',
  name: '',
  code: '',
  registeredBranchId: '',
});

const formDataProduct = ref<ProductCreate>({
  expenseType: '',
  vatIncluded: true,
  productGroupId: '',
  remark: '',
  serviceCharge: 0,
  agentPrice: 0,
  price: 0,
  process: 0,
  detail: '',
  name: '',
  code: '',
  image: undefined,
});

const formDataProductService = ref<ServiceCreate>({
  work: [],
  attributes: {
    additional: [],
  },
  detail: '',
  name: '',
  code: '',
  productGroupId: '',
});

const hideStat = ref(false);

const tbColumn = {
  groupAndType: [
    {
      name: 'branchLabelNo',
      align: 'center',
      label: 'general.order',
      field: 'branchNo',
    },
    {
      name: 'name',
      align: 'left',
      label: 'general.name',
      field: 'name',
    },
    {
      name: 'detail',
      align: 'left',
      label: 'general.detail',
      field: 'detail',
    },
    {
      name: 'formDialogInputRemark',
      align: 'left',
      label: 'general.remark',
      field: 'remark',
    },
    {
      name: 'createdAt',
      align: 'left',
      label: 'general.createdAt',
      field: 'createdAt',
    },
  ],

  product: [
    {
      name: 'branchLabelNo',
      align: 'center',
      label: 'general.order',
      field: 'branchNo',
    },
    {
      name: 'productName',
      align: 'left',
      label: 'general.name',
      field: 'name',
    },
    {
      name: 'productDetail',
      align: 'left',
      label: 'general.detail',
      field: 'detail',
    },
    {
      name: 'productExpenseType',
      align: 'left',
      label: 'productService.product.expenseType',
      field: 'expenseType',
    },
    {
      name: 'productProcessingTime',
      align: 'left',
      label: 'productService.product.processingTimeDay',
      field: 'process',
    },
    {
      name: 'productVat',
      align: 'left',
      label: 'productService.product.vat',
      field: 'expenseType',
    },
    {
      name: 'priceInformation',
      align: 'center',
      label: 'productService.product.priceInformation',
      field: 'name',
    },
  ],
  service: [
    {
      name: 'branchLabelNo',
      align: 'center',
      label: 'general.order',
      field: 'branchNo',
    },
    {
      name: 'serviceName',
      align: 'left',
      label: 'general.name',
      field: 'name',
    },
    {
      name: 'serviceDetail',
      align: 'left',
      label: 'general.detail',
      field: 'detail',
    },
    {
      name: 'serviceWorkTotal',
      align: 'left',
      label: 'productService.service.totalWork',
      field: (v) => v.work.length,
    },
    {
      name: 'createdAt',
      align: 'left',
      label: 'general.createdAt',
      field: 'createdAt',
    },
  ],
} satisfies {
  groupAndType: QTableProps['columns'];
  product: QTableProps['columns'];
  service: QTableProps['columns'];
};

const tbControl = reactive({
  groupAndType: {
    fieldDisplay: [
      { value: 'branchLabelNo', label: 'general.order' },
      { value: 'name', label: 'general.name' },
      { value: 'detail', label: 'general.detail' },
      { value: 'formDialogInputRemark', label: 'general.remark' },
      { value: 'createdAt', label: 'general.createdAt' },
    ],
    fieldSelected: [
      'branchLabelNo',
      'name',
      'detail',
      'formDialogInputRemark',
      'createdAt',
    ],
  },
  product: {
    fieldDisplay: [
      { value: 'branchLabelNo', label: 'general.order' },
      { value: 'productName', label: 'general.name' },
      {
        value: 'productExpenseType',
        label: 'productService.product.expenseType',
      },
      { value: 'productDetail', label: 'general.detail' },
      {
        value: 'productProcessingTime',
        label: 'productService.product.processingTimeDay',
      },
      {
        value: 'productVat',
        label: 'productService.product.vat',
      },
      {
        value: 'priceInformation',
        label: 'productService.product.priceInformation',
      },
    ],
    fieldSelected: [
      'branchLabelNo',
      'productName',
      'productExpenseType',
      'productDetail',
      'productProcessingTime',
      'productVat',
      'priceInformation',
    ],
  },
  service: {
    fieldDisplay: [
      { value: 'branchLabelNo', label: 'general.order' },
      { value: 'serviceName', label: 'general.name' },
      { value: 'serviceDetail', label: 'general.detail' },
      { value: 'serviceWorkTotal', label: 'productService.service.totalWork' },
      { value: 'createdAt', label: 'general.createdAt' },
    ],
    fieldSelected: [
      'branchLabelNo',
      'serviceName',
      'serviceDetail',
      'serviceWorkTotal',
      'createdAt',
    ],
  },
});
const $q = useQuasar();

const workItems = ref<WorkItems[]>([]);
const workNameRef = ref();
const selectProduct = ref<ProductList[]>([]);
const currentWorkIndex = ref<number>(0);

const serviceTab = ref(1);
const propertiesDialog = ref<boolean>(false);

const totalProduct = ref<number>(0);
const totalService = ref<number>(0);
const filterStat = ref<('group' | 'service' | 'product')[]>([]);

// แบ่งหน้า
const currentPageGroup = ref<number>(1);
const maxPageGroup = ref<number>(1);
const pageSizeGroup = ref<number>(30);
const maxPageServiceAndProduct = ref<number>(1);
const pageSizeServiceAndProduct = ref<number>(10);
const currentPageServiceAndProduct = ref<number>(1);
const totalGroup = ref<number>(0);
const total = ref<number>(0);

// เก็บ id ที่เข้ามา
const currentIdGrop = ref<string>('');
const currentIdType = ref<string>('');
const currentIdService = ref<string>('');
const currentIdProduct = ref<string>('');
const currentIdGropTree = ref<string>('');

const currentStatusGroupType = ref<Status>('CREATED');
const currentIdGroupType = ref('');

const branchOption = ref<{ id: string; name: string }[]>([]);

const currentStatus = ref<Status | 'All'>('All');

// img
const isImageEdit = ref<boolean>(false);
const refreshImageState = ref(false);
const imageList = ref<{ selectedImage: string; list: string[] }>();
const onCreateImageList = ref<{
  selectedImage: string;
  list: { url: string; imgFile: File | null; name: string }[];
}>({ selectedImage: '', list: [] });

async function searchProduct(isAdd: boolean = true) {
  const res = await fetchListProduct({
    query: inputSearchProductAndService.value,
  });

  if (res) {
    if (isAdd) {
      resultSearchProduct.value = res.result;
    }

    if (!isAdd) {
      product.value = res.result.map((v) => {
        return {
          ...v,
          type: 'product',
        };
      });
    }
  }
  flowStore.rotate();
}

function selectAllProduct(list: ProductList[]) {
  list
    ?.filter((i) => {
      if (i.status === 'INACTIVE') {
        return false;
      }
      return true;
    })
    .forEach((i) => {
      const productExists = selectProduct.value.some(
        (product) => product.id === i.id,
      );
      if (!productExists) {
        selectProduct.value.push({ ...i });
      }
    });
}

async function fetchListOfOptionBranch() {
  const uid = getUserId();
  const role = getRole();

  if (!uid) return;

  if (role?.includes('system')) {
    const result = await userBranchStore.fetchListOptionBranch();
    if (result && result.total > 0) branchOption.value = result.result;
  } else {
    const result = await userBranchStore.fetchListMyBranch(uid);
    if (result && result.total > 0) branchOption.value = result.result;
  }

  formDataGroup.value.registeredBranchId = currentMyBranch.value?.id || '';
}

async function fetchListGroups() {
  const res = await fetchListProductService({
    page: currentPageGroup.value,
    pageSize: pageSizeGroup.value,
    query: !!inputSearch.value ? inputSearch.value : undefined,
    status:
      currentStatus.value === 'All'
        ? undefined
        : currentStatus.value === 'ACTIVE'
          ? 'ACTIVE'
          : 'INACTIVE',
  });

  if (res) {
    currentPageGroup.value = res.page;
    totalGroup.value = res.total;
    maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value);
    productGroup.value = res.result;
  }
}

async function fetchListOfProductIsAdd(productGroupId: string) {
  const res = await fetchListProduct({
    status:
      currentStatus.value === 'INACTIVE'
        ? 'INACTIVE'
        : currentStatus.value === 'ACTIVE'
          ? 'ACTIVE'
          : undefined,
    productGroupId,
  });

  if (res) {
    productIsAdd.value = res.result.map((v) => {
      return {
        ...v,
        type: 'product',
      };
    });
  }
}

async function fetchListOfProduct() {
  const res = await fetchListProduct({
    page: currentPageServiceAndProduct.value,
    pageSize: pageSizeServiceAndProduct.value,
    query: !!inputSearchProductAndService.value
      ? inputSearchProductAndService.value
      : undefined,
    status:
      currentStatus.value === 'INACTIVE'
        ? 'INACTIVE'
        : currentStatus.value === 'ACTIVE'
          ? 'ACTIVE'
          : undefined,
    productGroupId: currentIdGrop.value,
  });

  if (res) {
    total.value = res.total;
    totalProduct.value = res.total;
    currentPageServiceAndProduct.value = res.page;
    maxPageServiceAndProduct.value = Math.ceil(
      res.total / pageSizeServiceAndProduct.value,
    );

    product.value = res.result.map((v) => {
      return {
        ...v,
        type: 'product',
      };
    });
  }
}

async function fetchListOfService() {
  const res = await fetchListService({
    page: currentPageServiceAndProduct.value,
    query: !!inputSearchProductAndService.value
      ? inputSearchProductAndService.value
      : undefined,
    pageSize: pageSizeServiceAndProduct.value,
    status:
      currentStatus.value === 'INACTIVE'
        ? 'INACTIVE'
        : currentStatus.value === 'ACTIVE'
          ? 'ACTIVE'
          : undefined,
    productGroupId: currentIdGrop.value,
  });

  if (res) {
    totalService.value = res.total;
    total.value = res.total;
    currentPageServiceAndProduct.value = res.page;
    maxPageServiceAndProduct.value = Math.ceil(
      res.total / pageSizeServiceAndProduct.value,
    );
    service.value = res.result.map((v) => {
      return {
        ...v,
        type: 'service',
      };
    });
  }
}

async function toggleStatusProduct(id: string, status: Status) {
  const res = await editProduct(id, {
    status: status === 'INACTIVE' ? 'ACTIVE' : 'INACTIVE',
  });
  if (res) formDataProduct.value.status = res.status;

  await alternativeFetch();
  flowStore.rotate();
}

async function toggleStatusService(id: string, status: Status) {
  const res = await editService(id, {
    status: status === 'INACTIVE' ? 'ACTIVE' : 'INACTIVE',
  });
  if (res) formDataProductService.value.status = res.status;

  await alternativeFetch();
  flowStore.rotate();
}

async function toggleStatusGroup(id: string, status: Status) {
  const res = await editProductService(id, {
    status: status === 'INACTIVE' ? 'ACTIVE' : 'INACTIVE',
  });
  if (res) currentStatusGroupType.value = res.status;

  await fetchListGroups();
  flowStore.rotate();
}

async function triggerChangeStatus(
  id: string,
  status: string,
  type?: 'group' | 'service' | 'product',
) {
  return await new Promise((resolve, reject) => {
    dialog({
      color: status !== 'INACTIVE' ? 'warning' : 'info',
      icon:
        status !== 'INACTIVE' ? 'mdi-alert' : 'mdi-message-processing-outline',
      title: t('dialog.title.confirmChangeStatus'),
      actionText:
        status !== 'INACTIVE' ? t('general.close') : t('general.open'),
      message:
        status !== 'INACTIVE'
          ? t('dialog.message.confirmChangeStatusOff')
          : t('dialog.message.confirmChangeStatusOn'),
      action: async () => {
        if (type === 'group' || productMode.value === 'group') {
          await toggleStatusGroup(id, status as Status)
            .then(resolve)
            .catch(reject);
        } else if (type === 'service') {
          await toggleStatusService(id, status as Status)
            .then(resolve)
            .catch(reject);
        } else if (type === 'product') {
          await toggleStatusProduct(id, status as Status)
            .then(resolve)
            .catch(reject);
        }
      },
      cancel: () => {},
    });
  });
}

async function deleteServiceConfirm(serviceId?: string) {
  dialog({
    color: 'negative',
    icon: 'mdi-alert',
    title: t('dialog.title.confirmDelete'),
    actionText: t('general.delete'),
    persistent: true,
    message: t('dialog.message.confirmDelete'),
    action: async () => {
      const res = await deleteService(serviceId ?? currentIdService.value);

      if (productAndServiceTab.value === 'service') {
        await fetchListOfService();
      }

      dialogServiceEdit.value = false;

      if (res) {
        totalService.value = totalService.value - 1;
      }
      flowStore.rotate();
      calculateStats({ reFetch: true });
    },
    cancel: () => {},
  });
}

async function deleteProductConfirm(id?: string) {
  dialog({
    color: 'negative',
    icon: 'mdi-alert',
    title: t('dialog.title.confirmDelete'),
    actionText: t('general.delete'),
    persistent: true,
    message: t('dialog.message.confirmDelete'),
    action: async () => {
      const res = await deleteProduct(id ?? currentIdProduct.value);

      if (!res) {
        flowStore.rotate();
        return;
      }

      if (productAndServiceTab.value === 'product') {
        await fetchListOfProduct();
      }

      dialogProductEdit.value = false;

      if (res) {
        totalProduct.value = totalProduct.value - 1;
      }
      flowStore.rotate();
      calculateStats({ reFetch: true });
    },
    cancel: () => {},
  });
}

// type or group
async function deleteProductById(productId?: string) {
  dialog({
    color: 'negative',
    icon: 'mdi-alert',
    title: t('dialog.title.confirmDelete'),
    actionText: t('general.delete'),
    persistent: true,
    message: t('dialog.message.confirmDelete'),
    action: async () => {
      if (editByTree.value !== undefined) {
        if (editByTree.value === 'group') {
          // Product Group
          const res = await deleteProductService(
            productId ?? currentIdGrop.value,
          );
          if (res) {
          }
          await fetchListGroups();
        }

        flowStore.rotate();
        calculateStats({ reFetch: true });
        editByTree.value = undefined;
        drawerInfo.value = false;
      } else {
        if (productMode.value === 'group') {
          // Product Group
          const res = await deleteProductService(
            productId ?? currentIdGrop.value,
          );
          if (res) {
          }
          await fetchListGroups();
        }

        flowStore.rotate();
        calculateStats({ reFetch: true });
        drawerInfo.value = false;
      }
    },
    cancel: () => {},
  });
}

function undoProductGroup() {
  formDataGroup.value = {
    remark: previousValue.value.remark,
    detail: previousValue.value.detail,
    name: previousValue.value.name,
    code: previousValue.value.code,
    registeredBranchId: previousValue.value.registeredBranchId,
  };
  isEdit.value = false;
  flowStore.rotate();
}

async function assignFormDataGroup(data: ProductGroup) {
  previousValue.value = data;
  currentStatusGroupType.value = data.status;
  currentIdGroupType.value = data.id;
  await fetchListOfOptionBranch();

  formDataGroup.value = {
    remark: data.remark,
    detail: data.detail,
    name: data.name,
    code: data.code,
    registeredBranchId: data.registeredBranchId,
  };
}

const prevService = ref<ServiceCreate>({
  work: [],
  attributes: {
    additional: [],
  },
  detail: '',
  name: '',
  code: '',
  productGroupId: '',
});

const currentService = ref<ServiceById>();

async function assignFormDataProductService(id: string) {
  const res = await fetchListServiceById(id);

  if (res) {
    await fetchImageList(res.id, res.selectedImage || '', 'service');
    serviceTab.value = 1;
    statusToggle.value = res.status === 'INACTIVE' ? false : true;
    profileUrl.value = `${baseUrl.value}/service/${res.id}/image/${res.selectedImage}`;
    profileSubmit.value = true;

    currentService.value = JSON.parse(JSON.stringify(res));

    prevService.value = {
      code: res.code,
      name: res.name,
      detail: res.detail,
      attributes: res.attributes,
      work: [],
      status: res.status,
      productGroupId: res.productGroupId,
      selectedImage: res.selectedImage,
    };

    formDataProductService.value = { ...prevService.value };

    res.work.forEach((item) => {
      prevService.value.work.push({
        name: item.name,
        attributes: item.attributes,
        productId: item.productOnWork.map(
          (productOnWorkItem) => productOnWorkItem.product.id,
        ),
      });
    });

    formDataProductService.value.work = prevService.value.work;

    workItems.value = res.work.map((item) => {
      return {
        id: item.id,
        name: item.name,
        attributes: item.attributes,
        product: item.productOnWork.map((productOnWorkItem) => {
          return {
            ...productOnWorkItem.product,
            nameEn: productOnWorkItem.product.name,
          };
        }),
      };
    });
  }
}

const currentNoAction = ref(false);
const prevProduct = ref<ProductCreate>({
  expenseType: '',
  vatIncluded: true,
  productGroupId: '',
  remark: '',
  serviceCharge: 0,
  agentPrice: 0,
  price: 0,
  process: 0,
  detail: '',
  name: '',
  code: '',
  image: undefined,
});

async function assignFormDataProduct(data: ProductList) {
  productTab.value = 1;
  statusToggle.value = data.status === 'INACTIVE' ? false : true;
  profileUrl.value = `${baseUrl.value}/product/${data?.id}/image/${data?.selectedImage}`;

  await fetchImageList(data.id, data.selectedImage || '', 'product');
  // profileSubmit.value = true;

  prevProduct.value = {
    productGroupId: data.productGroupId,
    remark: data.remark,
    serviceCharge: data.serviceCharge,
    agentPrice: data.agentPrice,
    price: data.price,
    process: data.process,
    detail: data.detail,
    name: data.name,
    code: data.code,
    image: undefined,
    status: data.status,
    expenseType: data.expenseType,
    vatIncluded: data.vatIncluded,
    selectedImage: data.selectedImage,
  };
  formDataProduct.value = { ...prevProduct.value };
}

function clearFormGroup() {
  formDataGroup.value = {
    remark: '',
    detail: '',
    name: '',
    code: '',
    registeredBranchId: '',
  };
  currentStatusGroupType.value = 'CREATED';
  dialogInputForm.value = false;
}

function clearFormProduct() {
  formDataProduct.value = {
    productGroupId: '',
    remark: '',
    serviceCharge: 0,
    agentPrice: 0,
    price: 0,
    process: 0,
    detail: '',
    name: '',
    code: '',
    image: undefined,
    expenseType: '',
    vatIncluded: true,
  };
  imageProduct.value = undefined;
  dialogProduct.value = false;
  dialogProductEdit.value = false;
  profileUrl.value = '';
  profileFileImg.value = null;
  profileSubmit.value = false;
}

function clearFormService() {
  formDataProductService.value = {
    code: '',
    name: '',
    detail: '',
    attributes: {
      additional: [],
    },
    work: [],
    status: undefined,
    productGroupId: '',
  };

  workItems.value = [];
  selectProduct.value = [];
  dialogService.value = false;
  dialogServiceEdit.value = false;
  profileUrl.value = '';
  profileSubmit.value = false;
  imageProduct.value = undefined;
  profileFileImg.value = null;
}

function assignFormDataProductServiceCreate() {
  formDataProductService.value.work = [];

  workItems.value.forEach((item) => {
    formDataProductService.value.work.push({
      name: item.name,
      attributes: item.attributes,
      productId: item.product.map((productItem) => productItem.id),
    });
  });
}

async function submitService(notClose = false) {
  assignFormDataProductServiceCreate();
  formDataProductService.value.productGroupId = currentIdGrop.value;

  if (profileFileImg.value)
    formDataProductService.value.image = profileFileImg.value;
  if (dialogService.value) {
    formDataProductService.value.productGroupId = currentIdGrop.value;

    if (
      formDataProductService.value.code === '' ||
      formDataProductService.value.name === ''
    ) {
      serviceTab.value = 1;
      return;
    }

    const res = await createService(
      formDataProductService.value,
      onCreateImageList.value,
    );
    if (res) {
      allStat.value[1].count = allStat.value[1].count + 1;
      stat.value[1].count = stat.value[1].count + 1;
    }
    totalService.value = totalService.value + 1;
    productAndServiceTab.value = 'service';
  }

  if (dialogServiceEdit.value) {
    await editService(currentIdService.value, {
      ...formDataProductService.value,
      status: statusToggle.value
        ? formDataProductService.value.status
        : 'INACTIVE',
    });
  }

  if (!notClose) clearFormService();

  if (productAndServiceTab.value === 'service') {
    await fetchListOfService();
  }

  flowStore.rotate();
}

async function submitProduct(notClose = false) {
  formDataProduct.value.productGroupId = currentIdGrop.value;
  if (profileFileImg.value) {
    formDataProduct.value.image = profileFileImg.value;
  }

  if (dialogProduct.value) {
    if (
      formDataProduct.value.name === '' ||
      formDataProduct.value.code === ''
    ) {
      productTab.value = 1;
      return;
    }
    const res = await createProduct(
      formDataProduct.value,
      onCreateImageList.value,
    );

    if (res) {
      allStat.value[2].count = allStat.value[2].count + 1;
      stat.value[2].count = stat.value[2].count + 1;
    }

    productAndServiceTab.value = 'product';
  }

  if (dialogProductEdit.value) {
    await editProduct(currentIdProduct.value, {
      ...formDataProduct.value,
      status: statusToggle.value ? 'ACTIVE' : 'INACTIVE',
    });
  }
  totalProduct.value = totalProduct.value + 1;
  if (!notClose) clearFormProduct();

  if (productAndServiceTab.value === 'product') {
    await fetchListOfProduct();
  }
  flowStore.rotate();
}

async function submitGroup() {
  if (drawerInfo.value) {
    if (currentIdGropTree.value)
      await editProductService(currentIdGropTree.value, formDataGroup.value);
    else await editProductService(currentIdGrop.value, formDataGroup.value);
  } else {
    const res = await createProductService(formDataGroup.value);

    if (res) {
      allStat.value[0].count = allStat.value[0].count + 1;
      stat.value[0].count = stat.value[0].count + 1;
    }
  }

  currentIdGropTree.value = '';
  drawerInfo.value = false;
  await fetchListGroups();
  clearFormGroup();
  flowStore.rotate();
}

function confirmDeleteWork(id: string, noDialog?: boolean) {
  if (noDialog) {
    deleteWork(id);
  } else {
    const currUseName =
      service.value?.map((v) => v.work.map((x) => x.name)).flat() || [];
    const deleteTarget = workNameItems.value.find(
      (v: { id: string }) => v.id === id,
    ).name;
    const isNameInUse = currUseName.includes(deleteTarget);

    dialog({
      color: 'negative',
      icon: 'mdi-alert',
      title: t('dialog.title.confirmDelete'),
      actionText: t('general.delete'),
      message: isNameInUse
        ? `${t('dialog.message.beingUse', { msg: deleteTarget })} ${t('dialog.message.confirmDelete')}`
        : t('dialog.message.confirmDelete'),
      action: async () => {
        deleteWork(id);
        flowStore.rotate();
      },
      cancel: () => {},
    });
  }
}

function triggerConfirmCloseWork() {
  dialogWarningClose(t, {
    action: () => {
      manageWorkNameDialog.value = false;
      if (workNameItems.value[workNameItems.value.length - 1].name === '') {
        confirmDeleteWork(
          workNameItems.value[workNameItems.value.length - 1].id,
          true,
        );
      }
    },
    cancel: () => {},
  });
}

const tempValueProperties = ref<Attributes>({
  additional: [],
});
const currentPropertiesMode = ref<'service' | 'work'>('service');

function openPropertiesDialog(type: 'service' | 'work') {
  if (type === 'service') {
    propertiesOption.value = optionStore.globalOption.servicePropertiesField;
  }

  if (type === 'work') {
    propertiesOption.value = optionStore.globalOption.workPropertiesField;
  }

  currentPropertiesMode.value = type;
  propertiesDialog.value = true;
}

async function calculateStats(opt?: {
  type?: 'service' | 'product';
  reFetch?: boolean;
}) {
  if (opt && opt.type === 'service' && productMode.value === 'service') {
    const resStatsService = await fetchStatsService({
      productGroupId: currentIdGrop.value,
    });
    stat.value[1].count = resStatsService ?? 0;
    return;
  }

  if (opt && opt.type === 'product' && productMode.value === 'product') {
    const resStatsProduct = await fetchStatsProduct({
      productGroupId: currentIdGrop.value,
    });
    stat.value[2].count = resStatsProduct ?? 0;
    return;
  }

  if (allStat.value.length === 0 || (opt && opt.reFetch)) {
    const resStatsGroup = await fetchStatsProductGroup();
    const resStatsService = await fetchStatsService();
    const resStatsProduct = await fetchStatsProduct();

    allStat.value.push({ mode: 'group', count: resStatsGroup ?? 0 });
    allStat.value.push({ mode: 'service', count: resStatsService ?? 0 });
    allStat.value.push({ mode: 'product', count: resStatsProduct ?? 0 });
  }
  stat.value[0].count = allStat.value[0].count;
  stat.value[1].count = allStat.value[1].count;
  stat.value[2].count = allStat.value[2].count;
}

async function fetchStatus() {
  if (productAndServiceTab.value === 'product') {
    await fetchListOfProduct();
    flowStore.rotate();
  }

  if (productAndServiceTab.value === 'service') {
    await fetchListOfService();
    flowStore.rotate();
  }
}

async function alternativeFetch() {
  if (productAndServiceTab.value === 'product') {
    await fetchListOfProduct();

    flowStore.rotate();
  }
  if (productAndServiceTab.value === 'service') {
    await fetchListOfService();
    flowStore.rotate();
  }
}

function cloneServiceData() {
  if (!currentService.value) return;
  const currentSelectedImage = formDataProductService.value.selectedImage;
  formDataProductService.value = {
    ...prevService.value,
    attributes: JSON.parse(JSON.stringify(currentService.value.attributes)),
  };
  formDataProductService.value.selectedImage = currentSelectedImage;

  workItems.value = currentService.value.work.map((item) => {
    return {
      id: item.id,
      name: item.name,
      attributes: JSON.parse(JSON.stringify(item.attributes)),
      product: item.productOnWork.map((productOnWorkItem) => {
        return {
          ...productOnWorkItem.product,
          nameEn: productOnWorkItem.product.name,
        };
      }),
    };
  });
}

async function enterGroup(
  id: string,
  name: string,
  status: Status,
  toService?: boolean,
) {
  expandedTree.value = [];
  filterStat.value = [];
  expandedTree.value.push(id);
  pathGroupName.value = name;
  currentIdType.value = '';
  currentIdGrop.value = id;
  currentNoAction.value = status === 'INACTIVE';
  pathTypeName.value = name;
  await fetchListOfService();
  await fetchListOfProduct();
  if (toService) await enterNext('service');
  else productMode.value = 'group';

  flowStore.rotate();
}

async function enterNext(type: 'service' | 'product') {
  currentPageServiceAndProduct.value = 1;
  inputSearchProductAndService.value = '';
  currentStatus.value = 'All';
  filterStat.value = [];

  if (
    expandedTree.value.length > 1 &&
    expandedTree.value[expandedTree.value.length - 1] !== type
  ) {
    expandedTree.value.pop();
  }

  if (type === 'service') {
    productMode.value = 'service';
    productAndServiceTab.value = 'service';
    currentIdType.value = 'type';
    pathTypeName.value = 'type';
    expandedTree.value.push('type');
    filterStat.value.push('group');
    filterStat.value.push('product');
  } else {
    productMode.value = 'product';
    productAndServiceTab.value = 'product';
    currentIdType.value = 'productService';
    pathTypeName.value = 'productService';
    expandedTree.value.push('productService');
    filterStat.value.push('group');
    filterStat.value.push('service');
  }
  flowStore.rotate();
}

function handleHold(node: ProductGroup & { type: string }) {
  if ($q.screen.gt.xs) return;
  holdDialog.value = true;
  currentNode.value = node;
}

async function fetchImageList(
  id: string,
  selectedName: string,
  type: 'product' | 'service',
) {
  const res = await productServiceStore.fetchImageListById(id, type);
  imageList.value = {
    selectedImage: selectedName,
    list: res.map((n: string) => `${type}/${id}/image/${n}`),
  };
  return res;
}

onMounted(async () => {
  utilsStore.currentTitle.title = 'productService.title';
  utilsStore.currentTitle.path = [
    {
      text: 'productService.caption',
      i18n: true,
      handler: () => {
        expandedTree.value = [];
        currentIdGrop.value = '';
        productMode.value = 'group';
      },
    },
  ];
  modeView.value = $q.screen.lt.md ? true : false;

  calculateStats();
  await fetchListGroups();

  flowStore.rotate();
});

watch(
  () => expandedTree.value,
  (v) => {
    inputSearch.value = '';
    currentStatus.value = 'All';

    let tmp: typeof utilsStore.currentTitle.path = [
      {
        text: 'productService.caption',
        i18n: true,
        handler: () => {
          productMode.value = 'group';
          expandedTree.value = [];
          currentIdGrop.value = '';
          currentIdType.value = '';
          filterStat.value = [];
        },
      },
    ];

    if (
      productMode.value === 'group' ||
      productMode.value === 'service' ||
      productMode.value === 'product'
    ) {
      tmp.push({
        text: 'productService.group.withName',
        i18n: true,
        argsi18n: { name: pathGroupName.value },
        handler: () => {
          if (
            productMode.value === 'service' ||
            productMode.value === 'product'
          ) {
            currentIdType.value = '';
            filterStat.value = [];
            productMode.value = 'group';
            expandedTree.value.pop();
            utilsStore.currentTitle.path.pop();
          }
        },
      });
      if (expandedTree.value.length === 0) {
        utilsStore.currentTitle.path = [
          { text: 'productService.caption', i18n: true },
        ];
        return;
      }
    }
    if (productMode.value === 'service' && v.length !== 1) {
      tmp.push({
        text: 'general.type',
        i18n: true,
      });
    }

    if (productMode.value === 'product' && v.length !== 1) {
      tmp.push({
        text: 'productService.title',
        i18n: true,
      });
    }

    utilsStore.currentTitle.path = tmp;
  },
  { deep: true },
);

watch(currentStatus, async () => {
  if (productMode.value === 'group') {
    await fetchListGroups();
  }
  flowStore.rotate();
});

watch(inputSearch, async () => {
  if (productMode.value === 'group') {
    await fetchListGroups();
    flowStore.rotate();
  }
});

watch(inputSearchProductAndService, async () => {
  await alternativeFetch();
});

watch(
  () => $q.screen.lt.md,
  (v) => {
    if (v) modeView.value = true;
  },
);

watch(productMode, async () => {
  if (productMode.value === 'group') {
    await calculateStats();
  }
  if (productMode.value === 'service') {
    await calculateStats({ type: 'service' });
  }
  if (productMode.value === 'product') {
    await calculateStats({ type: 'product' });
  }
});

watch(
  () => profileFileImg.value,
  () => {
    if (profileFileImg.value !== null) isImageEdit.value = true;
  },
);
</script>

<template>
  <ButtonAddComponent
    v-if="actionDisplay && !currentNoAction"
    style="z-index: 999"
  >
    <q-fab-action
      v-if="productMode === 'group'"
      id="btn-add-product-group"
      style="color: white; background-color: hsla(var(--pink-6-hsl))"
      padding="xs"
      icon="mdi-folder-multiple-plus-outline"
      :label="$t('productService.group.addTitle')"
      external-label
      label-position="left"
      @click="
        async () => {
          clearFormGroup();
          await fetchListOfOptionBranch();
          dialogInputForm = true;
        }
      "
    />
    <q-fab-action
      v-if="productMode === 'product'"
      :label="$t('productService.product.addTitle')"
      id="btn-add-product"
      external-label
      label-position="left"
      style="color: white; background-color: hsla(var(--green-11-hsl))"
      padding="xs"
      icon="mdi-folder-multiple-plus-outline"
      @click="
        async () => {
          productTab = 1;
          clearFormProduct();
          await fetchListOfOptionBranch();
          dialogProduct = true;
        }
      "
    ></q-fab-action>
    <q-fab-action
      v-if="productMode === 'service'"
      :label="$t('productService.service.addTitle')"
      id="btn-add-service"
      external-label
      label-position="left"
      style="color: white; background-color: hsla(var(--orange-6-hsl))"
      padding="xs"
      icon="mdi-server-plus-outline"
      @click="
        async () => {
          serviceTab = 1;
          clearFormGroup();
          clearFormService();
          await fetchListOfOptionBranch();
          serviceTab = 1;
          dialogService = true;
        }
      "
    ></q-fab-action>
  </ButtonAddComponent>

  <div class="full-height column no-wrap">
    <div class="text-body-2 q-mb-xs flex items-center">
      {{ $t('general.dataSum') }}
      <q-btn
        class="q-ml-xs"
        icon="mdi-pin-outline"
        color="primary"
        size="sm"
        flat
        dense
        rounded
        @click="hideStat = !hideStat"
        :style="hideStat ? 'rotate: 90deg' : ''"
        style="transition: 0.1s ease-in-out"
      />
    </div>

    <transition name="slide">
      <div v-if="!hideStat" class="scroll q-mb-md">
        <div style="display: inline-block">
          <StatCard
            label-i18n
            :branch="stat.filter((v) => !filterStat.includes(v.mode))"
            :dark="$q.dark.isActive"
            nowrap
          />
        </div>
      </div>
    </transition>

    <div
      class="column col rounded bordered"
      style="flex-wrap: nowrap; overflow: hidden"
    >
      <q-splitter
        v-model="splitterModel"
        :limits="[0, 100]"
        style="width: 100%"
        class="col"
        after-class="overflow-hidden"
      >
        <template v-slot:before>
          <div class="surface-1 column full-height">
            <div
              class="row no-wrap full-width bordered-b text-weight-bold surface-3 items-center q-px-md q-py-sm"
              :style="`min-height: ${$q.screen.gt.sm ? '57px' : '100.8px'}`"
            >
              <div class="col ellipsis-2-lines">
                {{ $t('productService.caption') }}
              </div>
            </div>

            <div class="col full-width scroll">
              <div class="q-pa-md">
                <TreeComponent
                  v-model:nodes="treeProductTypeAndGroup"
                  v-model:expanded-tree="expandedTree"
                  node-key="id"
                  label-key="name"
                  children-key="children"
                  type-tree="product"
                  :action="actionDisplay"
                  @select="
                    async (v: (typeof treeProductTypeAndGroup)[number]) => {
                      if (v.type === 'group') {
                        if (currentIdGrop !== v.id) {
                          await enterGroup(v.id, v.name, v.status);

                          return;
                        }

                        if (currentIdGrop === v.id) {
                          expandedTree = [];
                          filterStat = [];
                          expandedTree = expandedTree.filter((i) => v.id !== i);
                          currentIdGrop = '';
                          currentIdType = '';
                          productMode = 'group';
                          currentNoAction = false;
                          return;
                        }
                      }
                      if (v.type === 'type') {
                        if (currentIdType !== v.id) {
                          await enterNext('service');
                          return;
                        }
                        if (currentIdType === v.id) {
                          expandedTree.pop();
                          currentIdType = '';
                          filterStat = [];
                          productMode = 'group';
                          currentNoAction = false;
                          return;
                        }
                      }

                      if (v.type === 'productService') {
                        if (currentIdType !== v.id) {
                          await enterNext('product');

                          return;
                        }
                        if (currentIdType === v.id) {
                          expandedTree.pop();
                          currentIdType = '';
                          filterStat = [];
                          productMode = 'group';
                          currentNoAction = false;
                          return;
                        }
                      }
                    }
                  "
                  @view="
                    async (v: (typeof treeProductTypeAndGroup)[number]) => {
                      if (v.type === 'group') {
                        editByTree = 'group';
                        currentStatusProduct = v.status === 'INACTIVE';
                        clearFormGroup();
                        await assignFormDataGroup(v);
                        isEdit = false;
                        currentIdGropTree = v.id;
                        drawerInfo = true;
                      }
                    }
                  "
                  @edit="
                    async (v: (typeof treeProductTypeAndGroup)[number]) => {
                      editByTree = v.type as typeof editByTree;
                      if (v.type === 'group') {
                        clearFormGroup();
                        await assignFormDataGroup(v);
                        isEdit = true;
                        currentIdGropTree = v.id;
                        drawerInfo = true;
                      }
                    }
                  "
                  @delete="
                    (v: (typeof treeProductTypeAndGroup)[number]) => {
                      editByTree = v.type as typeof editByTree;
                      if (v.type === 'group') {
                        deleteProductById(v.id);
                      }
                    }
                  "
                  @change-status="
                    async (v: (typeof treeProductTypeAndGroup)[number]) => {
                      if (v.type === 'group') {
                        await triggerChangeStatus(v.id, v.status, v.type);
                      }
                    }
                  "
                  @handle-hold="handleHold"
                />
              </div>
            </div>
          </div>
        </template>

        <template v-slot:after>
          <div class="column no-wrap full-height">
            <!-- group/type -->
            <div
              v-if="productMode === 'group'"
              class="surface-2 items-center full-width full-height column col"
            >
              <!-- tool bar -->
              <div
                class="row q-py-sm q-px-md justify-between full-width surface-3 bordered-b"
              >
                <q-input
                  for="input-search"
                  outlined
                  :class="{ 'col-12': $q.screen.lt.md }"
                  dense
                  :label="$t('general.search')"
                  class=""
                  :bg-color="$q.dark.isActive ? 'dark' : 'white'"
                  v-model="inputSearch"
                  debounce="200"
                >
                  <template v-slot:prepend>
                    <q-icon name="mdi-magnify" />
                  </template>
                </q-input>

                <div
                  class="row col-12 col-md-6"
                  :class="{ 'q-pt-xs': $q.screen.lt.md }"
                  style="white-space: nowrap"
                >
                  <q-select
                    v-model="currentStatus"
                    for="select-status"
                    outlined
                    dense
                    option-value="value"
                    option-label="label"
                    class="col"
                    :class="{ 'offset-md-5': modeView }"
                    map-options
                    emit-value
                    :hide-dropdown-icon="$q.screen.lt.sm"
                    :options="[
                      { label: $t('general.all'), value: 'All' },
                      { label: $t('general.active'), value: 'ACTIVE' },
                      {
                        label: $t('general.inactive'),
                        value: 'INACTIVE',
                      },
                    ]"
                  ></q-select>

                  <q-select
                    v-if="modeView === false"
                    id="select-field"
                    for="select-field"
                    :options="
                      tbControl.groupAndType.fieldDisplay.map((x) => ({
                        label: $t(x.label),
                        value: x.value,
                      }))
                    "
                    :hide-dropdown-icon="$q.screen.lt.sm"
                    :display-value="$t('general.displayField')"
                    v-model="tbControl.groupAndType.fieldSelected"
                    class="col q-ml-sm"
                    option-label="label"
                    option-value="value"
                    map-options
                    emit-value
                    outlined
                    multiple
                    dense
                  />

                  <q-btn-toggle
                    v-model="modeView"
                    id="btn-mode"
                    dense
                    class="no-shadow bordered rounded surface-1 q-ml-sm"
                    :toggle-color="$q.dark.isActive ? 'grey-9' : 'grey-2'"
                    size="xs"
                    :options="[
                      { value: true, slot: 'folder' },
                      { value: false, slot: 'list' },
                    ]"
                  >
                    <template v-slot:folder>
                      <q-icon
                        name="mdi-view-grid-outline"
                        size="16px"
                        class="q-px-sm q-py-xs rounded"
                        :style="{
                          color: $q.dark.isActive
                            ? modeView
                              ? '#C9D3DB '
                              : '#787B7C'
                            : modeView
                              ? '#787B7C'
                              : '#C9D3DB',
                        }"
                      />
                    </template>
                    <template v-slot:list>
                      <q-icon
                        name="mdi-format-list-bulleted"
                        class="q-px-sm q-py-xs rounded"
                        size="16px"
                        :style="{
                          color: $q.dark.isActive
                            ? modeView === false
                              ? '#C9D3DB'
                              : '#787B7C'
                            : modeView === false
                              ? '#787B7C'
                              : '#C9D3DB',
                        }"
                      />
                    </template>
                  </q-btn-toggle>
                </div>
              </div>

              <div
                v-if="
                  productGroup?.length === 0 &&
                  productMode === 'group' &&
                  stat[0].count !== undefined
                "
                class="items-center justify-center full-width flex col"
              >
                <NoData :not-found="!!inputSearch" />
              </div>

              <template v-else>
                <div class="surface-2 q-pa-md scroll col full-width">
                  <q-table
                    flat
                    bordered
                    :grid="modeView"
                    :rows="productGroup || []"
                    :columns="tbColumn.groupAndType"
                    class="full-width"
                    card-container-class="q-col-gutter-md"
                    row-key="name"
                    :rows-per-page-options="[0]"
                    hide-pagination
                    :visible-columns="tbControl.groupAndType.fieldSelected"
                  >
                    <template v-slot:header="props">
                      <q-tr
                        style="background-color: hsla(var(--info-bg) / 0.07)"
                        :props="props"
                      >
                        <q-th
                          v-for="col in props.cols"
                          :key="col.name"
                          :props="props"
                        >
                          {{ $t(col.label) }}
                        </q-th>
                        <q-th auto-width />
                      </q-tr>
                    </template>

                    <template v-slot:body="props">
                      <q-tr
                        :style="
                          props.rowIndex % 2 !== 0
                            ? $q.dark.isActive
                              ? 'background: hsl(var(--gray-11-hsl)/0.2)'
                              : `background: #f9fafc`
                            : ''
                        "
                        :id="`enter-${props.row.name}`"
                        class="cursor-pointer"
                        :class="{
                          'app-text-muted': props.row.status === 'INACTIVE',
                          'status-active': props.row.status !== 'INACTIVE',
                          'status-inactive': props.row.status === 'INACTIVE',
                        }"
                        :props="props"
                        @click="
                          async () => {
                            filterStat.push(productMode);
                            if (productMode === 'group') {
                              await enterGroup(
                                props.row.id,
                                props.row.name,
                                props.row.status,
                                true,
                              );
                            }
                          }
                        "
                      >
                        <q-td
                          class="text-center"
                          v-if="
                            tbControl.groupAndType.fieldSelected.includes(
                              'branchLabelNo',
                            )
                          "
                        >
                          {{
                            (currentPageGroup - 1) * pageSizeGroup +
                            props.rowIndex +
                            1
                          }}
                        </q-td>
                        <q-td
                          v-if="
                            tbControl.groupAndType.fieldSelected.includes(
                              'name',
                            )
                          "
                        >
                          <div class="row items-center no-wrap">
                            <div
                              style="
                                width: 50px;
                                display: flex;
                                margin-bottom: var(--size-2);
                              "
                            >
                              <div
                                :class="`icon-color-${productMode === 'group' ? 'pink' : 'purple'}`"
                                class="table__icon"
                              >
                                <q-icon
                                  size="md"
                                  style="scale: 0.8"
                                  :name="
                                    productMode === 'group'
                                      ? 'mdi-folder-outline'
                                      : 'mdi-folder-table-outline'
                                  "
                                />
                              </div>
                            </div>
                            <div class="column">
                              <div class="ellipsis" style="max-width: 20vw">
                                {{ props.row.name }}
                                <q-tooltip>
                                  {{ props.row.name }}
                                </q-tooltip>
                              </div>
                              <div class="app-text-muted">
                                {{ props.row.code || '-' }}
                              </div>
                            </div>
                          </div>
                        </q-td>
                        <q-td
                          v-if="
                            tbControl.groupAndType.fieldSelected.includes(
                              'detail',
                            )
                          "
                        >
                          {{ props.row.detail || '-' }}
                        </q-td>

                        <q-td
                          v-if="
                            tbControl.groupAndType.fieldSelected.includes(
                              'formDialogInputRemark',
                            )
                          "
                        >
                          {{ props.row.remark || '-' }}
                        </q-td>

                        <q-td
                          v-if="
                            tbControl.groupAndType.fieldSelected.includes(
                              'createdAt',
                            )
                          "
                        >
                          {{ dateFormat(props.row.createdAt) }}
                        </q-td>

                        <q-td>
                          <q-btn
                            icon="mdi-eye-outline"
                            :id="`btn-eye-${props.row.name}`"
                            size="sm"
                            dense
                            round
                            flat
                            @click.stop="
                              async () => {
                                if (productMode === 'group') {
                                  editByTree = 'group';
                                  currentStatusProduct =
                                    props.row.status === 'INACTIVE';
                                  clearFormGroup();
                                  await assignFormDataGroup(props.row);
                                  isEdit = false;
                                  currentIdGrop = props.row.id;
                                  drawerInfo = true;
                                }
                              }
                            "
                          />

                          <KebabAction
                            :disable-delete="props.row.status !== 'CREATED'"
                            :status="props.row.status"
                            :idName="props.row.name"
                            @view="
                              async () => {
                                if (productMode === 'group') {
                                  editByTree = 'group';
                                  currentStatusProduct =
                                    props.row.status === 'INACTIVE';
                                  clearFormGroup();
                                  await assignFormDataGroup(props.row);
                                  isEdit = false;
                                  currentIdGrop = props.row.id;
                                  drawerInfo = true;
                                }
                              }
                            "
                            @edit="
                              async () => {
                                if (productMode === 'group') {
                                  editByTree = 'group';
                                  clearFormGroup();
                                  await assignFormDataGroup(props.row);
                                  isEdit = true;
                                  currentIdGrop = props.row.id;

                                  drawerInfo = true;
                                }
                              }
                            "
                            @delete="
                              () => {
                                if (productMode === 'group') {
                                  deleteProductById(props.row.id);
                                }
                              }
                            "
                            @changeStatus="
                              async () => {
                                triggerChangeStatus(
                                  props.row.id,
                                  props.row.status,
                                );
                              }
                            "
                          />
                        </q-td>
                      </q-tr>
                    </template>

                    <template v-slot:item="props">
                      <div class="col-12 col-md-6 col-lg-4">
                        <ProductCardComponent
                          :count-product="props.row._count.product"
                          :count-type="props.row._count.type"
                          :count-service="props.row._count.service"
                          :title="props.row.name"
                          :subtitle="props.row.code"
                          :date="new Date(props.row.updatedAt)"
                          :status="props.row.status"
                          :id="`enter-${props.row.name}`"
                          :for="`enter-${props.row.name}`"
                          :is-disabled="props.row.status === 'INACTIVE'"
                          :color="
                            {
                              type: $q.dark.isActive
                                ? 'var(--purple-7-hsl)'
                                : 'var(--violet-11-hsl)',
                              group: 'var(--pink-6-hsl)',
                            }[productMode] || 'var(--pink-6-hsl)'
                          "
                          :action="actionDisplay"
                          @toggleStatus="
                            triggerChangeStatus(props.row.id, props.row.status)
                          "
                          @viewCard="
                            async () => {
                              if (productMode === 'group') {
                                editByTree = 'group';
                                currentStatusProduct =
                                  props.row.status === 'INACTIVE';
                                clearFormGroup();
                                await assignFormDataGroup(props.row);
                                isEdit = false;
                                currentIdGrop = props.row.id;
                                drawerInfo = true;
                              }
                            }
                          "
                          @updateCard="
                            async () => {
                              if (productMode === 'group') {
                                clearFormGroup();
                                await assignFormDataGroup(props.row);
                                isEdit = true;
                                currentIdGrop = props.row.id;

                                drawerInfo = true;
                              }
                            }
                          "
                          @deleteCard="
                            () => {
                              if (productMode === 'group') {
                                deleteProductById(props.row.id);
                              }
                            }
                          "
                          @on-click="
                            async () => {
                              filterStat.push(productMode);
                              if (productMode === 'group') {
                                await enterGroup(
                                  props.row.id,
                                  props.row.name,
                                  props.row.status,
                                  true,
                                );
                              }
                            }
                          "
                        />
                      </div>
                    </template>
                  </q-table>
                </div>

                <div
                  v-if="productMode === 'group'"
                  class="row items-center justify-between q-px-md q-py-sm full-width"
                >
                  <div class="col-4">
                    <div class="row items-center">
                      <div
                        class="app-text-muted q-mr-sm"
                        v-if="$q.screen.gt.sm"
                      >
                        {{ $t('general.recordPerPage') }}
                      </div>
                      <div>
                        <q-btn-dropdown
                          dense
                          unelevated
                          :label="pageSizeGroup"
                          class="bordered q-pl-md"
                        >
                          <q-list>
                            <q-item
                              v-for="v in [10, 30, 50, 100, 500, 1000]"
                              :key="v"
                              clickable
                              v-close-popup
                              @click="
                                async () => {
                                  pageSizeGroup = v;
                                  await fetchListGroups();
                                }
                              "
                            >
                              <q-item-section>
                                <q-item-label>{{ v }}</q-item-label>
                              </q-item-section>
                            </q-item>
                          </q-list>
                        </q-btn-dropdown>
                      </div>
                    </div>
                  </div>

                  <div class="col-4 row justify-center app-text-muted">
                    {{
                      $t('general.recordsPage', {
                        resultcurrentPage: productGroup?.length,
                        total: totalGroup,
                      })
                    }}
                  </div>

                  <div class="col-4 row justify-end">
                    <PaginationComponent
                      v-model:current-page="currentPageGroup"
                      v-model:max-page="maxPageGroup"
                      :fetch-data="
                        async () => {
                          await fetchListGroups();
                          flowStore.rotate();
                        }
                      "
                    />
                  </div>
                </div>
              </template>
            </div>

            <!-- product/service -->
            <div
              v-else-if="productMode === 'service' || productMode === 'product'"
              class="surface-1 col column no-wrap"
              style="overflow: hidden"
            >
              <div
                class="row justify-between items-center q-px-md q-py-sm surface-3 bordered-b"
              >
                <q-input
                  :class="{ 'col-12': $q.screen.lt.md }"
                  outlined
                  dense
                  unelavated
                  :label="$t('general.search')"
                  :bg-color="$q.dark.isActive ? 'dark' : 'white'"
                  v-model="inputSearchProductAndService"
                  debounce="250"
                >
                  <template v-slot:prepend>
                    <q-icon name="mdi-magnify" />
                  </template>
                </q-input>

                <div
                  class="row col-12 col-md-6"
                  :class="{ 'q-pt-xs': $q.screen.lt.md }"
                  style="white-space: nowrap"
                >
                  <q-select
                    :for="'field-select-status'"
                    v-model="currentStatus"
                    outlined
                    dense
                    option-value="value"
                    :hide-dropdown-icon="$q.screen.lt.sm"
                    option-label="label"
                    :class="{ 'offset-md-5': modeView }"
                    class="col"
                    map-options
                    emit-value
                    :options="[
                      { label: $t('general.all'), value: 'All' },
                      { label: $t('general.active'), value: 'ACTIVE' },
                      {
                        label: $t('general.inactive'),
                        value: 'INACTIVE',
                      },
                    ]"
                    @update:model-value="fetchStatus()"
                  ></q-select>

                  <q-select
                    v-if="modeView === false"
                    :hide-dropdown-icon="$q.screen.lt.sm"
                    id="select-field"
                    for="select-field"
                    class="col q-ml-sm"
                    :options="
                      {
                        product: tbControl.product.fieldDisplay,
                        service: tbControl.service.fieldDisplay,
                      }[productAndServiceTab].map((x) => ({
                        label: $t(x.label),
                        value: x.value,
                      }))
                    "
                    :display-value="$t('general.displayField')"
                    :model-value="
                      {
                        product: tbControl.product.fieldSelected,
                        service: tbControl.service.fieldSelected,
                      }[productAndServiceTab]
                    "
                    @update:model-value="
                      (v: string[]) =>
                        (tbControl[productAndServiceTab].fieldSelected = v)
                    "
                    option-label="label"
                    option-value="value"
                    map-options
                    emit-value
                    outlined
                    multiple
                    dense
                  />

                  <q-btn-toggle
                    v-model="modeView"
                    id="btn-mode"
                    dense
                    class="no-shadow bordered rounded surface-1 q-ml-sm"
                    :toggle-color="$q.dark.isActive ? 'grey-9' : 'grey-2'"
                    size="xs"
                    :options="[
                      { value: true, slot: 'folder' },
                      { value: false, slot: 'list' },
                    ]"
                  >
                    <template v-slot:folder>
                      <q-icon
                        name="mdi-view-grid-outline"
                        size="16px"
                        class="q-px-sm q-py-xs rounded"
                        :style="{
                          color: $q.dark.isActive
                            ? modeView
                              ? '#C9D3DB '
                              : '#787B7C'
                            : modeView
                              ? '#787B7C'
                              : '#C9D3DB',
                        }"
                      />
                    </template>
                    <template v-slot:list>
                      <q-icon
                        name="mdi-format-list-bulleted"
                        class="q-px-sm q-py-xs rounded"
                        size="16px"
                        :style="{
                          color: $q.dark.isActive
                            ? modeView === false
                              ? '#C9D3DB'
                              : '#787B7C'
                            : modeView === false
                              ? '#787B7C'
                              : '#C9D3DB',
                        }"
                      />
                    </template>
                  </q-btn-toggle>
                </div>
              </div>

              <div
                v-if="
                  (productAndServiceTab === 'product' &&
                    product?.length === 0) ||
                  (productAndServiceTab === 'service' && service?.length === 0)
                "
                class="flex justify-center items-center surface-2 col"
              >
                <NoData :not-found="!!inputSearchProductAndService" />
              </div>
              <!-- tab -->
              <template v-else>
                <div
                  class="flex scroll full-width q-pa-md surface-2 column col"
                >
                  <q-table
                    class="full-width"
                    flat
                    bordered
                    :rows-per-page-options="[0]"
                    :rows="{ product, service }[productAndServiceTab] || []"
                    :columns="
                      {
                        product: tbColumn.product,
                        service: tbColumn.service,
                      }[productAndServiceTab]
                    "
                    :grid="modeView"
                    card-container-class="row q-col-gutter-md"
                    row-key="name"
                    hide-pagination
                    :visible-columns="
                      {
                        product: tbControl.product.fieldSelected,
                        service: tbControl.service.fieldSelected,
                      }[productAndServiceTab]
                    "
                  >
                    <template v-slot:header="props">
                      <q-tr
                        style="background-color: hsla(var(--info-bg) / 0.07)"
                        :props="props"
                      >
                        <q-th
                          v-for="col in props.cols"
                          :key="col.name"
                          :props="props"
                        >
                          {{ $t(col.label) }}
                        </q-th>
                        <q-th auto-width />
                      </q-tr>
                    </template>

                    <template v-slot:body="props">
                      <q-tr
                        :style="
                          props.rowIndex % 2 !== 0
                            ? $q.dark.isActive
                              ? 'background: hsl(var(--gray-11-hsl)/0.2)'
                              : `background: #f9fafc`
                            : ''
                        "
                        :class="{
                          'app-text-muted': props.row.status === 'INACTIVE',
                        }"
                        :props="props"
                      >
                        <q-td
                          class="text-center"
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,

                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'branchLabelNo',
                                service: 'branchLabelNo',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          {{
                            (currentPageServiceAndProduct - 1) *
                              pageSizeServiceAndProduct +
                            props.rowIndex +
                            1
                          }}
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,

                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'productName',
                                service: 'serviceName',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          <div class="row items-center no-wrap">
                            <div
                              :class="{
                                'status-active':
                                  props.row.status !== 'INACTIVE',
                                'status-inactive':
                                  props.row.status === 'INACTIVE',
                              }"
                              style="
                                width: 50px;
                                display: flex;
                                margin-bottom: var(--size-2);
                              "
                            >
                              <div
                                class="table__icon"
                                :class="`icon-color-${productAndServiceTab === 'product' ? 'green' : 'orange'}`"
                              >
                                <q-avatar size="md">
                                  <q-img
                                    class="text-center"
                                    :ratio="1"
                                    :src="`${baseUrl}/${productAndServiceTab}/${props.row.id}/image/${props.row.selectedImage}`"
                                  >
                                    <template #error>
                                      <q-icon
                                        size="sm"
                                        :name="
                                          productAndServiceTab === 'product'
                                            ? 'mdi-shopping-outline'
                                            : 'mdi-server-outline'
                                        "
                                        style="top: 10%"
                                        :style="`color: var(--${productAndServiceTab === 'product' ? 'teal-10' : 'orange-5'})`"
                                      />
                                    </template>
                                  </q-img>
                                </q-avatar>
                              </div>
                            </div>
                            <div class="column">
                              <div class="ellipsis" style="max-width: 20vw">
                                {{ props.row.name }}
                                <q-tooltip
                                  anchor="bottom left"
                                  self="center left"
                                  :delay="300"
                                >
                                  {{ props.row.name }}
                                </q-tooltip>
                              </div>
                              <div class="app-text-muted">
                                {{ props.row.code }}
                              </div>
                            </div>
                          </div>
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'productDetail',
                                service: 'serviceDetail',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          {{ props.row.detail || '-' }}
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'productExpenseType',
                                service: 'serviceWorkTotal',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          {{
                            optionStore.mapOption(
                              {
                                product: props.row.expenseType,
                                service: props.row.work?.length,
                              }[productAndServiceTab],
                            )
                          }}
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'productProcessingTime',
                                service: 'empty',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          {{
                            {
                              product: props.row.process,
                              service: props.row.work?.length,
                            }[productAndServiceTab]
                          }}
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'productVat',
                                service: 'empty',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          {{
                            {
                              product: props.row.vatIncluded,
                              service: props.row.work?.length,
                            }[productAndServiceTab]
                              ? $t('productService.product.vatIncluded')
                              : $t('productService.product.vatExcluded')
                          }}
                        </q-td>
                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes(
                              {
                                product: 'priceInformation',
                                service: 'empty',
                              }[productAndServiceTab],
                            )
                          "
                        >
                          <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>
                        </q-td>

                        <q-td
                          v-if="
                            {
                              product: tbControl.product.fieldSelected,
                              service: tbControl.service.fieldSelected,
                            }[productAndServiceTab].includes('createdAt')
                          "
                        >
                          {{ dateFormat(props.row.createdAt) }}
                        </q-td>
                        <q-td>
                          <q-btn
                            icon="mdi-eye-outline"
                            :id="`btn-eye-${props.row.name}`"
                            size="sm"
                            dense
                            round
                            flat
                            @click.stop="
                              async () => {
                                await fetchListOfOptionBranch();
                                if (props.row.type === 'product') {
                                  currentIdProduct = props.row.id;
                                  assignFormDataProduct(props.row);
                                  dialogProductEdit = true;
                                }
                                if (props.row.type === 'service') {
                                  currentIdService = props.row.id;
                                  infoServiceEdit = false;
                                  assignFormDataProductService(props.row.id);
                                  dialogServiceEdit = true;
                                }
                              }
                            "
                          />
                          <KebabAction
                            :status="props.row.status"
                            :idName="props.row.name"
                            @view="
                              async () => {
                                await fetchListOfOptionBranch();
                                if (props.row.type === 'product') {
                                  currentIdProduct = props.row.id;
                                  assignFormDataProduct(props.row);
                                  dialogProductEdit = true;
                                }
                                if (props.row.type === 'service') {
                                  currentIdService = props.row.id;
                                  infoServiceEdit = false;
                                  assignFormDataProductService(props.row.id);
                                  dialogServiceEdit = true;
                                }
                              }
                            "
                            @edit="
                              async () => {
                                await fetchListOfOptionBranch();
                                if (props.row.type === 'product') {
                                  currentIdProduct = props.row.id;
                                  infoProductEdit = true;
                                  assignFormDataProduct(props.row);
                                  dialogProductEdit = true;
                                }
                                if (props.row.type === 'service') {
                                  currentIdService = props.row.id;
                                  infoServiceEdit = true;
                                  assignFormDataProductService(props.row.id);
                                  dialogServiceEdit = true;
                                }
                              }
                            "
                            @delete="
                              () => {
                                if (props.row.type === 'product') {
                                  deleteProductConfirm(props.row.id);
                                }
                                if (props.row.type === 'service') {
                                  deleteServiceConfirm(props.row.id);
                                }
                              }
                            "
                            @changeStatus="
                              () => {
                                triggerChangeStatus(
                                  props.row.id,
                                  props.row.status,
                                  props.row.type,
                                );
                              }
                            "
                          />
                        </q-td>
                      </q-tr>
                    </template>

                    <template v-slot:item="{ row }">
                      <div class="col-12 col-md-6 col-lg-4">
                        <TotalProductCardComponent
                          :data="row"
                          :key="row.id"
                          :title="row.name"
                          :isDisabled="row.status === 'INACTIVE' ? true : false"
                          :action="actionDisplay"
                          :priceDisplay="priceDisplay"
                          @toggleStatus="
                            () => {
                              triggerChangeStatus(row.id, row.status, row.type);
                            }
                          "
                          @menuViewDetail="
                            async () => {
                              await fetchListOfOptionBranch();
                              if (row.type === 'product') {
                                currentIdProduct = row.id;
                                assignFormDataProduct(row);
                                dialogProductEdit = true;
                              }
                              if (row.type === 'service') {
                                currentIdService = row.id;
                                infoServiceEdit = false;
                                assignFormDataProductService(row.id);
                                dialogServiceEdit = true;
                              }
                            }
                          "
                          @menuEdit="
                            async () => {
                              await fetchListOfOptionBranch();
                              if (row.type === 'product') {
                                currentIdProduct = row.id;
                                infoProductEdit = true;
                                assignFormDataProduct(row);
                                dialogProductEdit = true;
                              }
                              if (row.type === 'service') {
                                currentIdService = row.id;
                                infoServiceEdit = true;
                                assignFormDataProductService(row.id);
                                dialogServiceEdit = true;
                              }
                            }
                          "
                          @menuDelete="
                            () => {
                              if (row.type === 'product') {
                                deleteProductConfirm(row.id);
                              }
                              if (row.type === 'service') {
                                deleteServiceConfirm(row.id);
                              }
                            }
                          "
                        />
                      </div>
                    </template>
                  </q-table>
                </div>
              </template>
              <!-- footer -->
              <div
                class="row items-center justify-between q-py-sm q-px-md surface-2"
              >
                <div class="col-4">
                  <div class="row items-center">
                    <div class="app-text-muted q-mr-sm" v-if="$q.screen.gt.sm">
                      {{ $t('general.recordPerPage') }}
                    </div>
                    <div>
                      <q-btn-dropdown
                        dense
                        unelevated
                        :label="pageSizeServiceAndProduct"
                        class="bordered q-pl-md"
                      >
                        <q-list>
                          <q-item
                            v-for="v in [10, 30, 50, 100, 500, 1000]"
                            :key="v"
                            clickable
                            v-close-popup
                            @click="
                              async () => {
                                pageSizeServiceAndProduct = v;

                                if (productAndServiceTab === 'product') {
                                  await fetchListOfProduct();
                                }
                                if (productAndServiceTab === 'service') {
                                  await fetchListOfService();
                                }
                              }
                            "
                          >
                            <q-item-section>
                              <q-item-label>{{ v }}</q-item-label>
                            </q-item-section>
                          </q-item>
                        </q-list>
                      </q-btn-dropdown>
                    </div>
                  </div>
                </div>

                <div class="col-4 row justify-center app-text-muted">
                  {{
                    $t('general.recordsPage', {
                      resultcurrentPage:
                        productAndServiceTab === 'product'
                          ? product?.length
                          : service?.length,
                      total: total,
                    })
                  }}
                </div>
                <div class="col-4 row justify-end">
                  <PaginationComponent
                    v-model:current-page="currentPageServiceAndProduct"
                    v-model:max-page="maxPageServiceAndProduct"
                    :fetch-data="
                      async () => {
                        await alternativeFetch();
                        flowStore.rotate();
                      }
                    "
                  />
                </div>
              </div>
            </div>
          </div>
        </template>
      </q-splitter>
    </div>
  </div>

  <!-- add group, add type -->
  <DialogForm
    v-model:modal="dialogInputForm"
    noAddress
    :title="$t(`productService.${productMode}.addTitle`)"
    :submit="() => submitGroup()"
    :close="clearFormGroup"
  >
    <div class="q-mx-lg q-mt-lg">
      <ProfileBanner
        readonly
        noImageAction
        active
        hideFade
        hideActive
        useToggle
        :img="`/images/product-service-${productMode}-avatar-add.png`"
        :toggleTitle="$t('status.title')"
        :icon="
          productMode === 'group'
            ? 'mdi-folder-plus-outline'
            : 'mdi-folder-table-outline'
        "
        :title="formDataGroup.name"
        :caption="formDataGroup.code"
        :menu="[
          {
            icon: 'mdi-office-building-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
        ]"
        :fallbackCover="`/images/product-service-${productMode}-banner.png`"
        :color="`hsla(var(${
          productMode === 'group'
            ? '--pink-6'
            : $q.dark.isActive
              ? '--violet-10'
              : '--violet-11'
        }-hsl)/1)`"
        :bg-color="`hsla(var(${
          productMode === 'group'
            ? '--pink-6'
            : $q.dark.isActive
              ? '--violet-10'
              : '--violet-11'
        }-hsl)/0.1)`"
        v-model:toggle-status="currentStatusGroupType"
        @update:toggle-status="
          () => {
            currentStatusGroupType =
              currentStatusGroupType === 'CREATED' ? 'INACTIVE' : 'CREATED';
          }
        "
      />
    </div>
    <div
      class="col surface-1 q-ma-lg rounded bordered scroll row relative-position"
      id="group-form"
    >
      <div
        class="col"
        style="height: 100%; max-height: 100; overflow-y: auto"
        v-if="$q.screen.gt.sm"
      >
        <div class="q-py-md q-pl-md q-pr-sm">
          <SideMenu
            :menu="[
              {
                name: $t('form.field.basicInformation'),
                anchor: 'form-group',
              },
            ]"
            background="transparent"
            :active="{
              background: 'hsla(var(--blue-6-hsl) / .2)',
              foreground: 'var(--blue-6)',
            }"
            scroll-element="#group-form"
          />
        </div>
      </div>
      <div
        class="col-12 col-md-10 q-py-md q-pr-md"
        id="customer-form-content"
        :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
        style="height: 100%; max-height: 100%; overflow-y: auto"
      >
        <!-- :isType="productMode === 'type'" -->
        <BasicInformation
          ide="form-group"
          dense
          v-model:options-branch="branchOption"
          v-model:remark="formDataGroup.remark"
          v-model:name="formDataGroup.name"
          v-model:detail="formDataGroup.detail"
          v-model:registered-branch-id="formDataGroup.registeredBranchId"
        />
      </div>
    </div>
  </DialogForm>

  <!-- edit group, edit type -->
  <DrawerInfo
    ref="formDialogRef"
    v-model:drawerOpen="drawerInfo"
    :title="
      $t(
        editByTree === 'group'
          ? 'productService.group.withName'
          : editByTree === 'type'
            ? 'productService.type.withName'
            : productMode === 'group'
              ? 'productService.group.withName'
              : 'productService.type.withName',
        {
          name: formDataGroup.code,
        },
      )
    "
    :undo="() => undoProductGroup()"
    :submit="
      () => {
        if (editByTree !== undefined) {
          if (editByTree === 'group') {
            submitGroup();
          }
          editByTree = undefined;
        } else {
          if (productMode === 'group') {
            submitGroup();
          }
        }
      }
    "
    :delete-data="() => deleteProductById()"
    :close="
      () => {
        (drawerInfo = false), (currentIdGroupType = '');
      }
    "
    hide-action
  >
    <InfoForm>
      <div class="q-mx-lg q-mt-lg">
        <ProfileBanner
          noImageAction
          :active="currentStatusGroupType !== 'INACTIVE'"
          hideFade
          :useToggle="actionDisplay"
          :readonly="!isEdit"
          :icon="
            editByTree === 'group'
              ? 'mdi-folder-outline'
              : 'mdi-folder-table-outline'
          "
          :fallbackCover="`/images/product-service-${editByTree}-banner.png`"
          v-model:toggle-status="currentStatusGroupType"
          :color="`hsla(var(${
            editByTree === 'group'
              ? '--pink-6'
              : $q.dark.isActive
                ? '--violet-10'
                : '--violet-11'
          }-hsl)/1)`"
          :bg-color="`hsla(var(${
            editByTree === 'group'
              ? '--pink-6'
              : $q.dark.isActive
                ? '--violet-10'
                : '--violet-11'
          }-hsl)/0.1)`"
          :title="formDataGroup.name"
          :caption="formDataGroup.code"
          :toggleTitle="$t('status.title')"
          :menu="[
            {
              icon: 'mdi-office-building-outline',
              color: 'hsl(var(--info-bg))',
              bgColor: 'var(--surface-1)',
            },
          ]"
          @update:toggle-status="
            async (v) => {
              await triggerChangeStatus(currentIdGroupType, v, productMode);
            }
          "
        />
      </div>

      <div class="col q-pa-lg">
        <div
          style="overflow-y: auto"
          class="row full-width full-height surface-1 rounded relative-position"
        >
          <div
            class="q-py-md q-px-lg"
            style="position: absolute; z-index: 99999; top: 0; right: 0"
            v-if="actionDisplay"
          >
            <div
              class="surface-1 row rounded"
              v-if="currentStatusGroupType !== 'INACTIVE' && !currentNoAction"
            >
              <UndoButton
                v-if="isEdit"
                icon-only
                @click="undoProductGroup()"
                type="button"
              />
              <SaveButton
                v-if="isEdit"
                id="btn-info-basic-save"
                icon-only
                type="submit"
              />
              <EditButton
                v-if="!isEdit"
                id="btn-info-basic-edit"
                icon-only
                @click="isEdit = true"
                type="button"
              />
              <DeleteButton
                v-if="!isEdit"
                id="btn-info-basic-delete"
                icon-only
                @click="deleteProductById()"
                type="button"
              />
            </div>
          </div>
          <div
            v-if="$q.screen.gt.sm"
            class="col full-height rounded scroll row q-py-md q-pl-md q-pr-sm"
          >
            <SideMenu
              :menu="[
                {
                  name: $t('form.field.basicInformation'),
                  anchor: 'info-group',
                },
              ]"
              background="transparent"
              :active="{
                background: 'hsla(var(--blue-6-hsl) / .2)',
                foreground: 'var(--blue-6)',
              }"
              scroll-element="#group-info"
              style="width: 100%"
            />
          </div>
          <div
            class="col-12 col-md-10 q-py-md q-pr-md full-height"
            id="group-info"
            :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
            style="overflow-y: auto"
          >
            <!-- :isType="productMode === 'type'" -->
            <BasicInformation
              id="info-group"
              dense
              :readonly="!isEdit"
              v-model:options-branch="branchOption"
              v-model:registered-branch-id="formDataGroup.registeredBranchId"
              v-model:remark="formDataGroup.remark"
              v-model:name="formDataGroup.name"
              v-model:code="formDataGroup.code"
              v-model:detail="formDataGroup.detail"
            />
          </div>
        </div>
      </div>
    </InfoForm>
  </DrawerInfo>

  <!-- work product, product work -->
  <DialogForm
    v-model:modal="dialogTotalProduct"
    :submitLabel="$t('general.select')"
    noAddress
    noAppBox
    :title="$t('productService.product.allProduct')"
    :saveAmount="selectProduct.length"
    :submit="
      () => {
        selectProduct.forEach((i) => {
          const productExists = workItems[currentWorkIndex].product.some(
            (product) => product.id === i.id,
          );
          if (!productExists) {
            workItems[currentWorkIndex].product.push({
              ...i,
              nameEn: '',
            });
          }
        });

        workItems[currentWorkIndex].product = workItems[
          currentWorkIndex
        ].product.filter((product) =>
          selectProduct.some((i) => i.id === product.id),
        );

        dialogTotalProduct = false;
        selectProduct = [];
      }
    "
    :close="
      () => {
        dialogTotalProduct = false;
        inputSearchProductAndService = '';
      }
    "
  >
    <div
      class="full-width q-pa-lg column"
      :class="
        resultSearchProduct?.length === 0 || productIsAdd?.length === 0
          ? 'full-height no-wrap'
          : ''
      "
    >
      <div
        class="row items-center justify-between q-mb-md"
        v-if="productIsAdd?.length !== 0"
      >
        <q-checkbox
          :label="$t('general.selectAll')"
          :model-value="
            !!inputSearchProductAndService
              ? selectProduct.length ===
                resultSearchProduct?.filter((i) => {
                  if (i.status === 'INACTIVE') {
                    return false;
                  }
                  return true;
                }).length
              : selectProduct.length ===
                productIsAdd?.filter((i) => {
                  if (i.status === 'INACTIVE') {
                    return false;
                  }
                  return true;
                }).length
          "
          @click="
            () => {
              if (
                !!inputSearchProductAndService
                  ? selectProduct.length ===
                    resultSearchProduct?.filter((i) => {
                      if (i.status === 'INACTIVE') {
                        return false;
                      }
                      return true;
                    }).length
                  : selectProduct.length ===
                    productIsAdd?.filter((i) => {
                      if (i.status === 'INACTIVE') {
                        return false;
                      }
                      return true;
                    }).length
              ) {
                selectProduct = [];
              } else {
                !!inputSearchProductAndService
                  ? resultSearchProduct && selectAllProduct(resultSearchProduct)
                  : productIsAdd && selectAllProduct(productIsAdd);
              }
            }
          "
        />
        <q-input
          id="input-search-add-product"
          outlined
          dense
          :label="$t('general.search')"
          :bg-color="$q.dark.isActive ? 'dark' : 'white'"
          v-model="inputSearchProductAndService"
          debounce="500"
          @update:model-value="searchProduct()"
        >
          <template v-slot:prepend>
            <q-icon name="mdi-magnify" />
          </template>
        </q-input>
      </div>

      <div
        class="flex col justify-center items-center col"
        v-if="resultSearchProduct?.length === 0 || productIsAdd?.length === 0"
      >
        <NoData
          :notFound="resultSearchProduct?.length === 0"
          :text="
            productIsAdd?.length === 0
              ? $t('productService.product.noProduct')
              : ''
          "
        />
      </div>
      <div v-else class="row q-col-gutter-md full-width">
        <div
          class="col-md-3 col-sm-6 col-12"
          v-for="i in (!!inputSearchProductAndService
            ? resultSearchProduct
            : productIsAdd
          )?.filter((i) => {
            if (i.status === 'INACTIVE') {
              return false;
            }
            return true;
          })"
          :key="i.id"
        >
          <TotalProductCardComponent
            no-time-img
            :index="selectProduct.findIndex((v) => v.id === i.id)"
            :isAddProduct="!!selectProduct.find((v) => v.id === i.id)"
            :action="false"
            :data="{ ...i, type: 'product' }"
            :title="i.name"
            :status="i.status === 'INACTIVE' ? true : false"
            :priceDisplay="priceDisplay"
            @menuViewDetail="
              () => {
                currentIdProduct = i.id;
                assignFormDataProduct(i);
                dialogProductEdit = true;
              }
            "
            @menuEdit="
              () => {
                currentIdProduct = i.id;
                infoProductEdit = true;
                assignFormDataProduct(i);
                dialogProductEdit = true;
              }
            "
            @viewDetail="
              () => {
                currentIdProduct = i.id;
                infoProductEdit = false;
                assignFormDataProduct(i);
                dialogProductEdit = true;
              }
            "
            @select="
              (data) => {
                const tempValue = selectProduct.find((v) => v.id === i.id);

                if (tempValue) {
                  selectProduct = selectProduct.filter((v) => v.id !== i.id);
                } else {
                  selectProduct.push(data);
                }
              }
            "
          />
        </div>
      </div>
    </div>
  </DialogForm>

  <!-- Add Product -->
  <DialogForm
    v-model:modal="dialogProduct"
    :title="$t('productService.product.addTitle')"
    :submit="
      () => {
        submitProduct();
      }
    "
    :close="
      () => {
        dialogProduct = false;
        onCreateImageList = { selectedImage: '', list: [] };
        flowStore.rotate();
      }
    "
  >
    <div class="q-mx-lg q-mt-lg">
      <ProfileBanner
        hideFade
        useToggle
        hideActive
        :toggleTitle="$t('status.title')"
        :img="profileUrl || '/images/product-avatar-add.png'"
        fallbackCover="/images/product-banner.png"
        :bgColor="`hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
        :menu="[
          {
            icon: 'mdi-office-building-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
        ]"
        @view="
          () => {
            imageDialog = true;
            isImageEdit = false;
          }
        "
        @edit="imageDialog = isImageEdit = true"
        v-model:toggle-status="formDataProduct.status"
        @update:toggle-status="
          () => {
            formDataProduct.status =
              formDataProduct.status === 'CREATED' ? 'INACTIVE' : 'CREATED';
          }
        "
        :tabsList="
          $q.screen.gt.sm
            ? []
            : [
                {
                  name: 1,
                  label: $t(`form.field.basicInformation`),
                },
                {
                  name: 2,
                  label: $t('productService.product.priceInformation'),
                },
              ]
        "
        v-model:currentTab="productTab"
      />
    </div>

    <div
      class="col surface-1 q-ma-lg rounded bordered scroll row relative-position"
      id="product-form"
    >
      <div
        class="col"
        style="height: 100%; max-height: 100; overflow-y: auto"
        v-if="$q.screen.gt.sm"
      >
        <div class="q-py-md q-pl-md q-pr-sm">
          <q-item
            v-for="v in 2"
            :key="v"
            dense
            clickable
            class="no-padding items-center rounded full-width"
            :class="{ 'q-mt-xs': v > 1 }"
            active-class="product-form-active"
            :active="productTab === v"
            @click="productTab = v"
          >
            <span class="full-width q-py-sm" style="padding-inline: 20px">
              {{
                v === 1
                  ? $t('form.field.basicInformation')
                  : $t('productService.product.priceInformation')
              }}
            </span>
          </q-item>
        </div>
      </div>
      <div
        class="col-12 col-md-10 q-py-md q-pr-md"
        id="customer-form-content"
        :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
        style="height: 100%; max-height: 100%; overflow-y: auto"
      >
        <BasicInfoProduct
          v-if="productTab === 1"
          v-model:detail="formDataProduct.detail"
          v-model:remark="formDataProduct.remark"
          v-model:name="formDataProduct.name"
          v-model:code="formDataProduct.code"
          v-model:process="formDataProduct.process"
          v-model:expense-type="formDataProduct.expenseType"
          dense
          separator
        />
        <PriceDataComponent
          v-if="productTab === 2"
          v-model:price="formDataProduct.price"
          v-model:agent-price="formDataProduct.agentPrice"
          v-model:service-charge="formDataProduct.serviceCharge"
          v-model:vat-included="formDataProduct.vatIncluded"
          dense
        />
      </div>
    </div>
  </DialogForm>

  <!-- edit product -->
  <!-- :edit="!(formDataProduct.status === 'INACTIVE')" -->
  <DialogForm
    v-model:modal="dialogProductEdit"
    noAddress
    :title="$t('productService.product.title')"
    :submit="() => submitProduct()"
    :close="
      () => {
        infoProductEdit = false;
        dialogProductEdit = false;
        flowStore.rotate();
      }
    "
    hide-footer
  >
    <div class="q-mx-lg q-mt-lg">
      <ProfileBanner
        hideFade
        :useToggle="actionDisplay"
        :active="formDataProduct.status !== 'INACTIVE'"
        :title="formDataProduct.name"
        :caption="formDataProduct.code"
        icon="mdi-shopping-outline"
        fallbackImg="/images/product-avatar.png"
        color="var(--teal-10)"
        :toggleTitle="$t('status.title')"
        :img="
          `${baseUrl}/product/${currentIdProduct}/image/${formDataProduct.selectedImage}`.concat(
            refreshImageState ? `?ts=${Date.now()}` : '',
          ) || '/images/product-avatar.png'
        "
        fallbackCover="/images/product-banner.png"
        :bgColor="`hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
        :menu="[
          {
            icon: 'mdi-office-building-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
        ]"
        v-model:toggle-status="formDataProduct.status"
        @view="
          () => {
            imageDialog = true;
            isImageEdit = false;
          }
        "
        @edit="imageDialog = isImageEdit = true"
        @update:toggle-status="
          async () => {
            if (formDataProduct.status)
              await triggerChangeStatus(
                currentIdProduct,
                formDataProduct.status,
                'product',
              );
          }
        "
        :tabsList="
          $q.screen.gt.sm
            ? []
            : [
                {
                  name: 1,
                  label: $t(`form.field.basicInformation`),
                },
                {
                  name: 2,
                  label: $t('productService.product.priceInformation'),
                },
              ]
        "
        v-model:currentTab="productTab"
      />
    </div>

    <div
      class="col surface-1 q-ma-lg rounded bordered scroll row relative-position"
      id="group-form"
    >
      <div
        class="surface-1 rounded row q-mx-lg q-my-md"
        style="position: absolute; z-index: 999; top: 0; right: 0"
        v-if="actionDisplay && !currentNoAction"
      >
        <UndoButton
          v-if="infoProductEdit"
          id="btn-info-basic-undo"
          icon-only
          @click="
            () => {
              formDataProduct = { ...prevProduct };
              infoProductEdit = false;
            }
          "
          type="button"
        />
        <SaveButton
          v-if="infoProductEdit"
          id="btn-info-basic-save"
          icon-only
          type="submit"
        />
        <EditButton
          v-if="!infoProductEdit"
          id="btn-info-basic-edit"
          icon-only
          @click="infoProductEdit = true"
          type="button"
        />
        <DeleteButton
          v-if="!infoProductEdit"
          id="btn-info-basic-delete"
          icon-only
          @click="() => deleteProductConfirm()"
          type="button"
        />
      </div>
      <div
        class="col"
        style="height: 100%; max-height: 100; overflow-y: auto"
        v-if="$q.screen.gt.sm"
      >
        <div class="q-py-md q-pl-md q-pr-sm">
          <q-item
            v-for="v in 2"
            :key="v"
            dense
            clickable
            class="no-padding items-center rounded full-width"
            :class="{ 'q-mt-xs': v > 1 }"
            active-class="product-form-active"
            :active="productTab === v"
            @click="productTab = v"
          >
            <span class="full-width q-py-sm" style="padding-inline: 20px">
              {{
                v === 1
                  ? $t('form.field.basicInformation')
                  : $t('productService.product.priceInformation')
              }}
            </span>
          </q-item>
        </div>
      </div>
      <div
        class="col-12 col-md-10 q-py-md q-pr-md"
        :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
        id="customer-form-content"
        style="height: 100%; max-height: 100%; overflow-y: auto"
      >
        <BasicInfoProduct
          v-if="productTab === 1"
          :readonly="!infoProductEdit"
          v-model:detail="formDataProduct.detail"
          v-model:remark="formDataProduct.remark"
          v-model:name="formDataProduct.name"
          v-model:code="formDataProduct.code"
          v-model:process="formDataProduct.process"
          v-model:expense-type="formDataProduct.expenseType"
          disableCode
          dense
          separator
        />
        <PriceDataComponent
          v-if="productTab === 2"
          :readonly="!infoProductEdit"
          v-model:price="formDataProduct.price"
          v-model:agent-price="formDataProduct.agentPrice"
          v-model:service-charge="formDataProduct.serviceCharge"
          v-model:vat-included="formDataProduct.vatIncluded"
          dense
          :priceDisplay="priceDisplay"
        />
      </div>
    </div>
  </DialogForm>

  <!-- add service -->
  <DialogForm
    no-address
    no-app-box
    height="95vh"
    :title="$t('productService.service.addTitle')"
    v-model:modal="dialogService"
    :submit="
      () => {
        submitService();
      }
    "
    :close="
      () => {
        clearFormService();
        dialogService = false;
        onCreateImageList = { selectedImage: '', list: [] };
        flowStore.rotate();
      }
    "
  >
    <div class="q-mx-lg q-mt-lg">
      <ProfileBanner
        hideFade
        useToggle
        hideActive
        :toggleTitle="$t('status.title')"
        :img="profileUrl || '/images/service-avatar-add.png'"
        fallbackCover="/images/service-banner.png"
        :bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
        :menu="[
          {
            icon: 'mdi-office-building-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
          {
            icon: 'mdi-briefcase-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
        ]"
        @view="
          () => {
            imageDialog = true;
            isImageEdit = false;
          }
        "
        @edit="imageDialog = isImageEdit = true"
        v-model:toggle-status="formDataProductService.status"
        @update:toggle-status="
          () => {
            formDataProductService.status =
              formDataProductService.status === 'CREATED'
                ? 'INACTIVE'
                : 'CREATED';
          }
        "
        :tabsList="
          $q.screen.gt.sm
            ? []
            : [
                {
                  name: 1,
                  label: $t('productService.service.information'),
                },
                {
                  name: 2,
                  label: $t('productService.service.workInformation'),
                },
              ]
        "
        v-model:currentTab="serviceTab"
      />
    </div>

    <div
      class="col surface-1 q-mx-lg q-mt-lg q-mb-md rounded bordered scroll row relative-position"
      id="service-form"
    >
      <div
        class="col"
        style="height: 100%; max-height: 100; overflow-y: auto"
        v-if="$q.screen.gt.sm"
      >
        <div class="q-py-md q-pl-md q-pr-sm">
          <q-item
            v-for="v in 2"
            :key="v"
            dense
            clickable
            class="no-padding items-center rounded full-width"
            :class="{ 'q-mt-xs': v > 1 }"
            active-class="product-form-active"
            :active="serviceTab === v"
            @click="serviceTab = v"
          >
            <span class="full-width q-py-sm" style="padding-inline: 20px">
              {{
                v === 1
                  ? $t('productService.service.information')
                  : $t('productService.service.workInformation')
              }}
            </span>
          </q-item>
        </div>
      </div>
      <div
        class="col-12 col-md-10 q-py-md q-pr-md"
        id="customer-form-content"
        :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
        style="height: 100%; max-height: 100%; overflow-y: auto"
      >
        <BasicInformation
          v-if="serviceTab === 1"
          dense
          service
          v-model:service-code="formDataProductService.code"
          v-model:service-description="formDataProductService.detail"
          v-model:service-name-th="formDataProductService.name"
        />

        <FormServiceWork
          v-if="serviceTab === 2"
          v-model:work-items="workItems"
          dense
          @addProduct="
            async (index) => {
              await fetchListOfProductIsAdd(currentIdGrop);
              currentWorkIndex = index;
              selectProduct = JSON.parse(
                JSON.stringify(workItems[currentWorkIndex].product),
              );
              dialogTotalProduct = true;
            }
          "
          @manage-work-name="
            () => {
              manageWorkNameDialog = true;
            }
          "
          @work-properties="
            (index) => {
              currentWorkIndex = index;
              tempValueProperties = JSON.parse(
                JSON.stringify(workItems[index].attributes),
              );
              openPropertiesDialog('work');
            }
          "
        />
      </div>
    </div>
    <div
      class="col-2 surface-1 q-mx-lg q-mb-lg rounded bordered row"
      v-if="serviceTab === 1"
      style="overflow: hidden"
    >
      <FormServiceProperties
        v-model:service-attributes="formDataProductService.attributes"
        @service-properties="
          () => {
            tempValueProperties = JSON.parse(
              JSON.stringify(formDataProductService.attributes),
            );
            openPropertiesDialog('service');
          }
        "
      />
    </div>
  </DialogForm>

  <!-- service properties -->
  <DialogForm
    no-address
    no-app-box
    height="75vh"
    width="75%"
    :title="$t('productService.service.properties')"
    v-model:modal="propertiesDialog"
    :submit="
      () => {
        if (currentPropertiesMode === 'service') {
          formDataProductService.attributes = JSON.parse(
            JSON.stringify(tempValueProperties),
          );
        }
        if (currentPropertiesMode === 'work') {
          workItems[currentWorkIndex].attributes = JSON.parse(
            JSON.stringify(tempValueProperties),
          );
        }

        propertiesDialog = false;
      }
    "
    :close="
      () => {
        propertiesDialog = false;
      }
    "
  >
    <div class="q-pa-lg full-width full-height">
      <ServiceProperties
        v-model:properties-option="propertiesOption"
        v-model:form-service-properties="tempValueProperties"
      />
    </div>
  </DialogForm>

  <!-- manage work name -->
  <DialogForm
    hideFooter
    height="65vh"
    width="65%"
    v-model:modal="manageWorkNameDialog"
    :title="$t('general.manage')"
    :before-close="
      () => {
        const isWorkNameEdit =
          workNameRef && workNameRef.isWorkNameEdit
            ? workNameRef.isWorkNameEdit()
            : false;
        if (isWorkNameEdit) {
          triggerConfirmCloseWork();
          return true;
        }
        return false;
      }
    "
  >
    <div class="q-pa-lg full-height">
      <WorkNameManagement
        ref="workNameRef"
        v-model:nameList="workNameItems"
        @delete="confirmDeleteWork"
        @edit="editWork"
        @add="createWork"
      />
    </div>
  </DialogForm>

  <!-- edit service -->
  <!-- :edit="!(formDataProductService.status === 'INACTIVE')" -->
  <DialogForm
    hide-footer
    no-address
    height="95vh"
    :title="$t('productService.service.title')"
    v-model:modal="dialogServiceEdit"
    :submit="
      () => {
        submitService();
      }
    "
    :close="
      () => {
        clearFormService();
        flowStore.rotate();
        dialogServiceEdit = false;
      }
    "
  >
    <div class="q-mx-lg q-mt-lg">
      <ProfileBanner
        hideFade
        :useToggle="actionDisplay"
        :title="formDataProductService.name"
        :caption="formDataProductService.code"
        :active="formDataProductService.status !== 'INACTIVE'"
        :toggleTitle="$t('status.title')"
        :img="
          `${baseUrl}/service/${currentIdService}/image/${formDataProductService.selectedImage}`.concat(
            refreshImageState ? `?ts=${Date.now()}` : '',
          ) || '/images/service-avatar.png'
        "
        fallbackImg="/images/service-avatar.png"
        fallbackCover="/images/service-banner.png"
        :bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
        :menu="[
          {
            icon: 'mdi-office-building-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
          {
            icon: 'mdi-briefcase-outline',
            color: 'hsl(var(--info-bg))',
            bgColor: 'var(--surface-1)',
          },
        ]"
        v-model:toggle-status="formDataProductService.status"
        @view="
          () => {
            imageDialog = true;
            isImageEdit = false;
          }
        "
        @edit="imageDialog = isImageEdit = true"
        @update:toggle-status="
          async () => {
            if (formDataProductService.status)
              await triggerChangeStatus(
                currentIdService,
                formDataProductService.status,
                'service',
              );
          }
        "
        :tabsList="
          $q.screen.gt.sm
            ? []
            : [
                {
                  name: 1,
                  label: $t('productService.service.information'),
                },
                {
                  name: 2,
                  label: $t('productService.service.workInformation'),
                },
              ]
        "
        v-model:currentTab="serviceTab"
      />
    </div>

    <div
      class="col surface-1 q-mx-lg q-mt-lg q-mb-md rounded bordered scroll row relative-position"
      id="group-form"
    >
      <div
        class="surface-1 rounded q-my-md q-mx-lg row"
        style="position: absolute; z-index: 999; top: 0; right: 0"
        v-if="actionDisplay && !currentNoAction"
      >
        <UndoButton
          v-if="infoServiceEdit"
          id="btn-info-basic-undo"
          icon-only
          @click="
            () => {
              infoServiceEdit = false;
              cloneServiceData();
              statusToggle = prevService.status === 'INACTIVE' ? false : true;
              flowStore.rotate();
            }
          "
          type="button"
        />
        <SaveButton
          v-if="infoServiceEdit"
          id="btn-info-basic-save"
          icon-only
          type="submit"
        />
        <EditButton
          v-if="!infoServiceEdit"
          id="btn-info-basic-edit"
          icon-only
          @click="infoServiceEdit = true"
          type="button"
        />
        <DeleteButton
          v-if="!infoServiceEdit"
          id="btn-info-basic-delete"
          icon-only
          @click="() => deleteServiceConfirm()"
          type="button"
        />
      </div>
      <div
        class="col"
        style="height: 100%; max-height: 100; overflow-y: auto"
        v-if="$q.screen.gt.sm"
      >
        <div class="q-py-md q-pl-md q-pr-sm">
          <q-item
            v-for="v in 2"
            :key="v"
            dense
            clickable
            class="no-padding items-center rounded full-width"
            :class="{ 'q-mt-xs': v > 1 }"
            active-class="product-form-active"
            :active="serviceTab === v"
            @click="serviceTab = v"
          >
            <span class="full-width q-py-sm" style="padding-inline: 20px">
              {{
                v === 1
                  ? $t('productService.service.information')
                  : $t('productService.service.workInformation')
              }}
            </span>
          </q-item>
        </div>
      </div>
      <div
        class="col-12 col-md-10 q-py-md q-pr-md"
        id="customer-form-content"
        :class="$q.screen.xs ? 'q-pl-md' : 'q-pl-sm'"
        style="height: 100%; max-height: 100%; overflow-y: auto"
      >
        <BasicInformation
          v-if="serviceTab === 1"
          :readonly="!infoServiceEdit"
          dense
          service
          disableCode
          v-model:service-code="formDataProductService.code"
          v-model:service-description="formDataProductService.detail"
          v-model:service-name-th="formDataProductService.name"
        />

        <FormServiceWork
          v-if="serviceTab === 2"
          :readonly="!infoServiceEdit"
          v-model:work-items="workItems"
          dense
          :priceDisplay="priceDisplay"
          @addProduct="
            async (index) => {
              await fetchListOfProductIsAdd(currentIdGrop);
              currentWorkIndex = index;
              selectProduct = JSON.parse(
                JSON.stringify(workItems[currentWorkIndex].product),
              );
              dialogTotalProduct = true;
            }
          "
          @manage-work-name="
            () => {
              manageWorkNameDialog = true;
            }
          "
          @work-properties="
            (index) => {
              currentWorkIndex = index;
              tempValueProperties = JSON.parse(
                JSON.stringify(workItems[index].attributes),
              );
              openPropertiesDialog('work');
            }
          "
        />
      </div>
    </div>
    <div
      class="col-2 surface-1 q-mx-lg q-mb-lg rounded bordered row"
      v-if="serviceTab === 1"
      style="overflow: hidden"
    >
      <FormServiceProperties
        :readonly="!infoServiceEdit"
        v-model:service-attributes="formDataProductService.attributes"
        @service-properties="
          () => {
            tempValueProperties = JSON.parse(
              JSON.stringify(formDataProductService.attributes),
            );
            openPropertiesDialog('service');
          }
        "
      />
    </div>
  </DialogForm>

  <q-dialog v-model="holdDialog" position="bottom">
    <div class="surface-1 full-width rounded column q-pb-md">
      <div class="flex q-py-sm justify-center full-width">
        <div
          class="rounded"
          style="
            width: 8%;
            height: 4px;
            background-color: hsla(0, 0%, 50%, 0.75);
          "
        ></div>
      </div>

      <q-list v-if="currentNode">
        <q-item
          clickable
          v-ripple
          v-close-popup
          @click.stop="
            async () => {
              if (!currentNode) return;

              if (currentNode.type === 'group') {
                editByTree = 'group';
                currentStatusProduct = currentNode.status === 'INACTIVE';
                clearFormGroup();
                await assignFormDataGroup(currentNode);
                isEdit = false;
                currentIdGrop = currentNode.id;
                drawerInfo = true;
              }
            }
          "
        >
          <q-item-section avatar>
            <q-icon
              name="mdi-eye-outline"
              style="color: hsl(var(--green-6-hsl))"
            />
          </q-item-section>
          <q-item-section>{{ $t('general.viewDetail') }}</q-item-section>
        </q-item>

        <q-item
          clickable
          v-ripple
          v-close-popup
          @click.stop="
            async () => {
              if (!currentNode) return;
              editByTree = currentNode.type as 'type' | 'group';
              if (currentNode.type === 'group') {
                clearFormGroup();
                await assignFormDataGroup(currentNode);
                isEdit = true;
                currentIdGrop = currentNode.id;

                drawerInfo = true;
              }
            }
          "
        >
          <q-item-section avatar>
            <q-icon
              name="mdi-pencil-outline"
              style="color: hsl(var(--cyan-6-hsl))"
            />
          </q-item-section>
          <q-item-section>{{ $t('general.edit') }}</q-item-section>
        </q-item>

        <q-item
          clickable
          v-ripple
          v-close-popup
          @click.stop="
            () => {
              if (!currentNode) return;
              editByTree = currentNode.type as 'type' | 'group';

              if (currentNode.type === 'type') {
                deleteProductById(currentNode.id);
              }
              if (currentNode.type === 'group') {
                deleteProductById(currentNode.id);
              }
            }
          "
        >
          <q-item-section avatar>
            <q-icon name="mdi-trash-can-outline" class="app-text-negative" />
          </q-item-section>
          <q-item-section>{{ $t('general.delete') }}</q-item-section>
        </q-item>

        <q-item clickable v-ripple>
          <q-item-section avatar>
            <ToggleButton
              two-way
              :id="`view-detail-btn-${currentNode.name}-status`"
              :model-value="currentNode.status !== 'INACTIVE'"
              @click="
                async () => {
                  if (!currentNode) return;
                  if (currentNode.type === 'group') {
                    triggerChangeStatus(
                      currentNode.id,
                      currentNode.status,
                      currentNode.type,
                    );
                    currentNode.status === 'ACTIVE'
                      ? (currentNode.status = 'INACTIVE')
                      : (currentNode.status = 'ACTIVE');
                  }
                }
              "
            />
          </q-item-section>
          <q-item-section>
            {{
              currentNode.status !== 'INACTIVE'
                ? $t('general.open')
                : $t('general.close')
            }}
          </q-item-section>
        </q-item>
      </q-list>
    </div>
  </q-dialog>

  <ImageUploadDialog
    ref="refImageUpload"
    v-model:dialogState="imageDialog"
    v-model:file="profileFileImg"
    v-model:image-url="profileUrl as string"
    v-model:data-list="imageList"
    v-model:on-create-data-list="onCreateImageList"
    :hidden-footer="!isImageEdit"
    :on-create="dialogProduct || dialogService"
    :change-disabled="!actionDisplay"
    @add-image="
      async (v) => {
        if (!v) return;
        if (!currentIdProduct && !currentIdService) return;
        const res = await productServiceStore.addImageList(
          v,
          dialogProductEdit ? currentIdProduct : currentIdService,
          Date.now(),
          dialogProductEdit ? 'product' : 'service',
        );
        await fetchImageList(
          dialogProductEdit ? currentIdProduct : currentIdService,
          res,
          dialogProductEdit ? 'product' : 'service',
        );
      }
    "
    @remove-image="
      async (v) => {
        if (!v) return;
        if (!currentIdProduct && !currentIdService) return;

        const name = v.split('/').pop() || '';
        const type = dialogProductEdit ? 'product' : 'service';
        await productServiceStore.deleteImageByName(
          dialogProductEdit ? currentIdProduct : currentIdService,
          name,
          type,
        );
        await fetchImageList(
          dialogProductEdit ? currentIdProduct : currentIdService,
          dialogProductEdit
            ? formDataProduct.selectedImage || ''
            : formDataProductService.selectedImage || '',
          type,
        );
      }
    "
    @submit="
      async (v) => {
        if (dialogProduct || dialogService) {
          profileUrl = v;
          imageDialog = false;
        } else {
          const type = dialogProductEdit ? 'product' : 'service';
          const id = dialogProductEdit ? currentIdProduct : currentIdService;
          refreshImageState = true;
          type === 'product'
            ? (formDataProduct.selectedImage = v)
            : (formDataProductService.selectedImage = v);
          imageList ? (imageList.selectedImage = v) : '';
          profileUrl = `${baseUrl}/${type}/${id}/image/${v}`;
          if (type === 'product') {
            const { selectedImage, ...data } = prevProduct;
            formDataProduct = {
              selectedImage: formDataProduct.selectedImage,
              ...data,
            };
            await submitProduct(true);
          } else {
            cloneServiceData();
            await submitService(true);
          }
          imageDialog = false;
          refreshImageState = false;
          infoProductEdit = false;
          infoServiceEdit = false;
        }
      }
    "
  >
    <template #title>
      <span
        v-if="!dialogProduct || !dialogService"
        class="justify-center flex text-bold"
      >
        {{ $t('general.image') }}
        {{
          dialogProductEdit ? formDataProduct.name : formDataProductService.name
        }}
      </span>
    </template>
    <template #error>
      <div class="full-height full-width" style="background: var(--surface-1)">
        <div
          class="full-height full-width flex justify-center items-center"
          :style="`background: ${
            dialogProduct || dialogProductEdit
              ? `hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`
              : `hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`
          }`"
        >
          <q-img
            :src="`/images/${dialogProduct || dialogProductEdit ? 'product' : 'service'}-avatar.png`"
            fit="contain"
            style="height: 100%"
          />
        </div>
      </div>
    </template>
  </ImageUploadDialog>
</template>

<style scoped>
.hover-underline:hover {
  cursor: pointer;
  text-decoration: underline;
}

.status-active {
  --_branch-status-color: var(--green-6-hsl);
}

.status-inactive {
  --_branch-status-color: var(--stone-5-hsl);
  --_branch-badge-bg: var(--stone-5-hsl);
  filter: grayscale(0.5);
  opacity: 0.5;
}

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

.icon-color-pink {
  --_color: var(--pink-6-hsl);
}

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

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

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

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

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

.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);
}

.table__icon {
  background-color: hsla(var(--_color) / 0.15);
  color: hsla(var(--_color) / 1);

  border-radius: 50%;
  position: relative;
  transform: rotate(45deg);

  &::after {
    content: ' ';
    display: block;
    block-size: 0.5rem;
    aspect-ratio: 1;
    position: absolute;
    border-radius: 50%;
    right: -0.1rem;
    top: calc(50% - 0.25rem);
    bottom: calc(50% - 0.25rem);
    background-color: hsla(var(--_branch-status-color) / 1);
  }

  &:deep(.q-icon) {
    transform: rotate(-45deg);
    color: hsla(var(--_branch-card-bg) / 1);
  }

  &:deep(.q-img) {
    transform: rotate(-45deg);

    &:deep(.q-icon) {
      transform: rotate(0deg);
    }
  }
}

.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%;
  }
}

* :deep(.q-icon.mdi-play) {
  display: none;
}

.product-form-active {
  background-color: hsla(var(--info-bg) / 0.2);
  color: hsl(var(--info-bg));
  font-weight: 600;
}
</style>
