<script lang="ts" setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Option } from 'stores/options/types';
import { Attributes } from 'stores/product-service/types';
import { moveItemUp, moveItemDown, deleteItem, dialog } from 'stores/utils';

import NoData from '../NoData.vue';

const { t } = useI18n();

const propertiesOption =
  defineModel<(Option & { type: Attributes['additional'][number]['type'] })[]>(
    'propertiesOption',
  );
const formServiceProperties = defineModel<Attributes>('formServiceProperties');

const typeOption = ref([
  {
    label: 'Text',
    value: 'string',
    color: 'var(--pink-6-hsl)',
    icon: 'mdi-alpha-t',
  },
  {
    label: 'Number',
    value: 'number',
    color: 'var(--purple-11-hsl)',
    icon: 'mdi-numeric',
  },
  {
    label: 'Date',
    value: 'date',
    color: 'var(--green-9-hsl)',
    icon: 'mdi-calendar-blank-outline',
  },
  {
    label: 'Selection',
    value: 'array',
    color: 'var(--indigo-7-hsl)',
    icon: 'mdi-code-array',
  },
]);

function manageProperties(
  property: string,
  propertyType?: Attributes['additional'][number]['type'],
) {
  if (property === 'all' && propertiesOption.value) {
    if (
      formServiceProperties.value?.additional.length ===
      propertiesOption.value.length
    ) {
      formServiceProperties.value.additional = [];
      return;
    }

    for (const ops of propertiesOption.value) {
      if (
        formServiceProperties.value?.additional.some(
          (prop) => prop.fieldName === ops.value,
        )
      ) {
        continue;
      }

      if (ops.type === 'date') {
        formServiceProperties.value?.additional.push({
          type: ops.type,
          fieldName: ops.value,
        });
      }

      if (ops.type === 'array') {
        formServiceProperties.value?.additional.push({
          type: ops.type,
          fieldName: ops.value,
          options: [''],
        });
      }

      if (ops.type === 'string') {
        formServiceProperties.value?.additional.push({
          type: ops.type,
          fieldName: ops.value,
          isPhoneNumber: false,
          phoneNumberLength: 10,
        });
      }

      if (ops.type === 'number') {
        formServiceProperties.value?.additional.push({
          type: ops.type,
          fieldName: ops.value,
          comma: false,
          decimal: false,
          decimalPlace: 2,
        });
      }
    }
    return;
  }

  if (formServiceProperties.value) {
    const propertyIndex = formServiceProperties.value.additional.findIndex(
      (prop) => prop.fieldName === property,
    );

    if (propertyIndex !== -1) {
      formServiceProperties.value.additional.splice(propertyIndex, 1);
    } else {
      if (propertyType === 'date') {
        formServiceProperties.value?.additional.push({
          type: propertyType,
          fieldName: property,
        });
      }

      if (propertyType === 'array') {
        formServiceProperties.value?.additional.push({
          type: propertyType,
          fieldName: property,
          options: [''],
        });
      }

      if (propertyType === 'string') {
        formServiceProperties.value?.additional.push({
          type: propertyType,
          fieldName: property,
          isPhoneNumber: false,
          phoneNumberLength: 10,
        });
      }

      if (propertyType === 'number') {
        formServiceProperties.value?.additional.push({
          type: propertyType,
          fieldName: property,
          comma: false,
          decimal: false,
          decimalPlace: 2,
        });
      }
    }
  }
}

function shouldShowItem(opt: Option) {
  if (formServiceProperties.value) {
    const additionalFieldNames = new Set(
      formServiceProperties.value.additional.map((o) => o.fieldName),
    );
    return !!opt && !additionalFieldNames.has(opt.value);
  }
}

function changeType(fieldName: string) {
  if (!propertiesOption.value) return;

  const defaultPropType = propertiesOption.value.find(
    (op) => op.value === fieldName,
  )?.type;

  if (!defaultPropType) return;

  const idx = formServiceProperties.value?.additional.findIndex(
    (v) => v.fieldName === fieldName,
  );

  if (!idx) return;

  if (defaultPropType === 'date') {
    formServiceProperties.value?.additional.push({
      type: defaultPropType,
      fieldName,
    });
  }

  if (defaultPropType === 'array') {
    formServiceProperties.value?.additional.push({
      type: defaultPropType,
      fieldName,
      options: [''],
    });
  }

  if (defaultPropType === 'string') {
    formServiceProperties.value?.additional.push({
      type: defaultPropType,
      fieldName,
      isPhoneNumber: false,
      phoneNumberLength: 10,
    });
  }

  if (defaultPropType === 'number') {
    formServiceProperties.value?.additional.push({
      type: defaultPropType,
      fieldName,
      comma: false,
      decimal: false,
      decimalPlace: 2,
    });
  }
}

function confirmDelete(items: unknown[], index: number) {
  dialog({
    color: 'negative',
    icon: 'mdi-alert',
    title: t('dialog.title.confirmDelete'),
    actionText: t('general.delete'),
    message: t('dialog.message.confirmDelete'),
    action: async () => {
      deleteItem(items, index);
    },
    cancel: () => {},
  });
}
</script>
<template>
  <div class="full-width full-height column no-wrap">
    <div class="row">
      <q-btn-dropdown
        id="btn-dropdow-properties"
        for="btn-dropdow-properties"
        dense
        unelevated
        color="primary"
        :label="$t('productService.service.properties')"
        class="q-px-sm q-mb-lg text-capitalize"
        menu-anchor="bottom end"
      >
        <q-list dense v-if="formServiceProperties && propertiesOption">
          <q-item
            for="list-all"
            id="list-all"
            clickable
            @click="manageProperties('all')"
          >
            <div class="full-width flex items-center">
              <q-icon
                v-if="
                  formServiceProperties.additional.length ===
                  propertiesOption.length
                "
                name="mdi-checkbox-marked"
                size="xs"
                class="q-mr-sm"
                color="primary"
              />
              <q-icon
                v-else
                name="mdi-checkbox-blank-outline"
                size="xs"
                class="q-mr-sm"
                style="color: hsl(var(--text-mute))"
              />
              {{ $t('general.selectAll') }}
            </div>
          </q-item>
          <q-separator />
          <q-item
            v-for="(ops, index) in propertiesOption"
            clickable
            :key="index"
            @click="manageProperties(ops.value, ops.type)"
            :for="`list-${ops.value}`"
            :id="`list-${ops.value}`"
          >
            <div class="full-width flex items-center no-wrap">
              <q-icon
                v-if="
                  formServiceProperties &&
                  formServiceProperties.additional.some(
                    (add) => add.fieldName === ops.value,
                  )
                "
                name="mdi-checkbox-marked"
                size="xs"
                color="primary"
                class="q-mr-sm"
              />
              <q-icon
                v-else
                name="mdi-checkbox-blank-outline"
                size="xs"
                style="color: hsl(var(--text-mute))"
                class="q-mr-sm"
              />
              {{ ops.label }}
            </div>
          </q-item>
        </q-list>
      </q-btn-dropdown>
    </div>

    <div
      v-if="formServiceProperties?.additional.length === 0"
      class="bordered rounded surface-1 flex justify-center items-center col"
    >
      <NoData use-field />
    </div>

    <div
      v-if="
        formServiceProperties?.additional &&
        formServiceProperties.additional.length > 0
      "
      class="q-gutter-y-md"
    >
      <div
        v-for="(p, index) in formServiceProperties.additional"
        :key="index"
        class="bordered surface-1 rounded q-py-sm q-px-md row items-start"
        :class="
          index === formServiceProperties.additional.length - 1 && 'q-mb-lg'
        "
      >
        <div class="col-md col-12 row items-center">
          <q-btn
            id="btn-move-up-product"
            icon="mdi-arrow-up"
            dense
            flat
            round
            :disable="index === 0"
            :size="$q.screen.xs ? 'xs' : ''"
            style="color: hsl(var(--text-mute-2))"
            @click="moveItemUp(formServiceProperties.additional, index)"
          />
          <q-btn
            id="btn-move-down-product"
            icon="mdi-arrow-down"
            dense
            flat
            round
            :size="$q.screen.xs ? 'xs' : ''"
            :disable="index === formServiceProperties.additional.length - 1"
            style="color: hsl(var(--text-mute-2))"
            @click="moveItemDown(formServiceProperties.additional, index)"
          />

          <q-avatar
            :size="$q.screen.xs ? 'sm' : 'md'"
            class="q-mx-lg"
            style="background-color: var(--surface-3)"
          >
            {{ index + 1 }}
          </q-avatar>

          <!-- field name -->
          <q-select
            dense
            outlined
            emit-value
            map-options
            hide-bottom-space
            for="input-properties-name"
            class="col-md col-12 q-mr-md"
            :class="{ 'q-my-sm': $q.screen.lt.md }"
            :label="$t('productService.service.propertiesName')"
            option-label="label"
            option-value="value"
            :options="propertiesOption"
            v-model="p.fieldName"
            @update:model-value="changeType"
          >
            <template v-slot:option="scope">
              <q-item
                v-if="scope.opt && shouldShowItem(scope.opt)"
                v-bind="scope.itemProps"
                class="row items-center col-12"
              >
                {{ scope.opt.label }}
              </q-item>
            </template>
          </q-select>
        </div>

        <!-- type -->
        <div class="col-md col-12">
          <q-select
            dense
            outlined
            emit-value
            map-options
            hide-bottom-space
            for="input-properties-type"
            id="input-properties-type"
            :label="$t('general.type')"
            option-value="value"
            @update:model-value="
              (t: 'string' | 'number' | 'date' | 'array') => {
                if (!formServiceProperties) return;
                if (t === 'date') {
                  formServiceProperties.additional[index] = {
                    type: t,
                    fieldName: p.fieldName,
                  };
                }

                if (t === 'array') {
                  formServiceProperties.additional[index] = {
                    type: t,
                    fieldName: p.fieldName,
                    options: [''],
                  };
                }

                if (t === 'string') {
                  formServiceProperties.additional[index] = {
                    type: t,
                    fieldName: p.fieldName,
                    isPhoneNumber: false,
                    phoneNumberLength: 10,
                  };
                }

                if (t === 'number') {
                  formServiceProperties.additional[index] = {
                    type: t,
                    fieldName: p.fieldName,
                    comma: false,
                    decimal: false,
                    decimalPlace: 2,
                  };
                }
              }
            "
            :options="typeOption"
            v-model="p.type"
          >
            <template v-slot:option="scope">
              <q-item
                v-if="scope.opt"
                v-bind="scope.itemProps"
                class="row items-center col-12"
                :id="`type-${scope.itemProps}`"
              >
                <q-avatar
                  size="sm"
                  class="q-mr-md"
                  :style="`background-color: hsla(${scope.opt.color}/0.2)`"
                >
                  <q-icon
                    size="20px"
                    :name="scope.opt.icon"
                    :style="`color: hsl(${scope.opt.color})`"
                  />
                </q-avatar>
                {{ scope.opt.label }}
              </q-item>
            </template>

            <template v-slot:selected-item="scope">
              <div v-if="scope.opt" class="row items-center col-12">
                <q-avatar
                  size="xs"
                  class="q-mr-sm"
                  :style="`background-color: hsla(${scope.opt.color}/0.2)`"
                >
                  <q-icon
                    size="14px"
                    :name="scope.opt.icon"
                    :style="`color: hsl(${scope.opt.color})`"
                  />
                </q-avatar>
                {{ scope.opt.label }}
              </div>
            </template>
          </q-select>

          <div v-if="p.type !== 'date' && p.type">
            <q-item class="no-padding" style="font-size: 11px">
              <q-item-section
                class="column q-py-sm"
                :style="{ 'padding-left: 12px': $q.screen.gt.xs }"
              >
                <span class="app-text-muted-2">
                  {{ $t('general.additional') }}
                </span>

                <div v-if="p.type === 'string'" class="q-gutter-y-sm">
                  <div class="row items-center">
                    <div class="col-7 surface-3 rounded q-mr-sm q-py-xs">
                      <q-checkbox
                        :for="`checkbox-is-phone-number-${p.fieldName}`"
                        v-if="p.type === 'string'"
                        v-model="p.isPhoneNumber"
                        size="xs"
                      />
                      {{ $t('general.telephone') }}
                    </div>
                    <q-input
                      v-if="p.type === 'string'"
                      :for="`input-max-length-${p.fieldName}`"
                      v-model="p.phoneNumberLength"
                      input-class="text-caption"
                      class="col additional-label"
                      dense
                      outlined
                      :label="$t('form.maxLength')"
                    />
                  </div>
                </div>

                <div v-if="p.type === 'number'" class="q-gutter-y-sm">
                  <div class="row items-center">
                    <div class="col-md-4 col-12 surface-3 rounded">
                      <q-checkbox
                        v-model="p.comma"
                        size="xs"
                        class="q-py-xs"
                        :for="`checkbox-is-comma-${p.fieldName}`"
                      />
                      {{ $t('form.useComma') }}
                    </div>
                    <div
                      class="col-md-4 col-7 surface-3 rounded"
                      :class="{
                        'q-mx-sm': $q.screen.gt.sm,
                        'q-mr-sm q-mt-xs': $q.screen.lt.md,
                      }"
                    >
                      <q-checkbox
                        v-model="p.decimal"
                        size="xs"
                        class="q-py-xs"
                        :for="`checkbox-is-decimal-${p.fieldName}`"
                      />
                      {{ $t('form.decimal') }}
                    </div>
                    <q-input
                      :for="`input-decimal-place-${p.fieldName}`"
                      v-model="p.decimalPlace"
                      class="col additional-label"
                      :class="{ 'q-mt-xs': $q.screen.lt.md }"
                      input-class="text-caption"
                      dense
                      outlined
                      :label="$t('form.decimalPlace')"
                    />
                  </div>
                </div>

                <div v-if="p.type === 'array'" class="q-gutter-y-sm">
                  <div
                    class="row items-center justify-between"
                    v-for="(_, i) in p.options"
                    :key="i"
                  >
                    <div class="col rounded">
                      <q-input
                        v-model="p.options[i]"
                        :for="`input-selection-${p.fieldName}-${i}`"
                        class="col additional-label"
                        dense
                        outlined
                        input-class="text-caption"
                        :label="$t('form.selection')"
                        :rules="[(val) => !!val || $t('form.error.required')]"
                        hide-bottom-space
                      />
                    </div>
                    <div class="col-1 q-pl-sm">
                      <q-btn
                        :id="`btn-delete-selection-${p.fieldName}-${i}`"
                        :for="`btn-delete-selection-${p.fieldName}-${i}`"
                        @click="
                          () => {
                            p.options.splice(i, 1);
                          }
                        "
                        dense
                        flat
                        icon="mdi-trash-can-outline"
                        class="bordered"
                        text-color="negative"
                        style="border-radius: 6px"
                      />
                    </div>
                  </div>
                  <div class="row">
                    <q-btn
                      :for="`btn-add-selection-${p.fieldName}`"
                      :id="`btn-add-selection-${p.fieldName}`"
                      @click="
                        () => {
                          p.options.push('');
                        }
                      "
                      dense
                      flat
                      icon="mdi-plus"
                      class="bordered col-11"
                      text-color="grey"
                      style="border-radius: 6px"
                    />
                  </div>
                </div>
              </q-item-section>
            </q-item>
          </div>
        </div>

        <q-btn
          id="btn-delete-work-product"
          icon="mdi-trash-can-outline"
          dense
          flat
          round
          color="negative"
          class="q-ml-sm"
          @click="confirmDelete(formServiceProperties.additional, index)"
        />
      </div>
    </div>
  </div>
</template>
<style scoped lang="scss">
.menu-border {
  border-left: 1px solid var(--border-color);
  border-right: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
  border-bottom-left-radius: var(--radius-2);
  border-bottom-right-radius: var(--radius-2);
}

.additional-label:deep(.q-field__label.no-pointer-events.absolute.ellipsis) {
  font-size: 11px !important;
}
</style>
