<script setup lang="ts">
import { ref, watch } from 'vue';
import { moveItemUp, moveItemDown, dialog, deleteItem } from 'stores/utils';
import { useI18n } from 'vue-i18n';

import useOptionStore from 'src/stores/options';
import { useWorkflowTemplate } from 'src/stores/workflow-template';
import { Option } from 'stores/options/types';
import {
  WorkFlowPayloadStep,
  WorkflowTemplate,
} from 'src/stores/workflow-template/types';

import SelectFlow from '../shared/select/SelectFlow.vue';
import NoData from '../NoData.vue';
import DialogForm from '../DialogForm.vue';

const { t } = useI18n();
const { getWorkflowTemplate } = useWorkflowTemplate();
const optionStore = useOptionStore();

const props = defineProps<{
  stepIndex?: number;

  onEdit?: boolean;
  selectFlow?: boolean;
}>();

const emit = defineEmits<{
  (e: 'submit', currWorkflow: WorkflowTemplate): void;
  (e: 'show'): void;
}>();

const model = defineModel<boolean>({ required: true, default: false });
const workflowId = defineModel<string>('workflowId', { default: '' });
const dataStep = defineModel<WorkFlowPayloadStep[]>('dataStep', {
  default: [],
});

const tempStep = ref<WorkFlowPayloadStep[]>([]);
const tempWorkflowId = ref<string>('');
const propertiesOption = ref();
const currWorkflow = ref<WorkflowTemplate>();
const typeOption = [
  {
    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 submit() {
  workflowId.value = tempWorkflowId.value;
  dataStep.value = JSON.parse(JSON.stringify(tempStep.value));
  model.value = false;

  if (props.selectFlow && currWorkflow.value) {
    emit('submit', currWorkflow.value);
  }
}

function close() {
  tempStep.value = [];
  model.value = false;
}

function manageProperties(
  stepIndex: number,
  property: string,
  propertyType?: 'date' | 'array' | 'string' | 'number',
) {
  if (property === 'all' && propertiesOption.value) {
    if (
      tempStep.value[stepIndex].attributes.properties.length ===
      propertiesOption.value.length
    ) {
      tempStep.value[stepIndex].attributes.properties = [];
      return;
    }

    for (const ops of propertiesOption.value) {
      if (
        tempStep.value[stepIndex].attributes.properties.some(
          (prop) => prop.fieldName === ops.value,
        )
      ) {
        continue;
      }

      if (ops.type === 'date') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: ops.type,
          fieldName: ops.value,
        });
      }

      if (ops.type === 'array') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: ops.type,
          fieldName: ops.value,
          options: [],
        });
      }

      if (ops.type === 'string') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: ops.type,
          fieldName: ops.value,
          isPhoneNumber: false,
          phoneNumberLength: 10,
        });
      }

      if (ops.type === 'number') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: ops.type,
          fieldName: ops.value,
          comma: false,
          decimal: false,
          decimalPlace: 2,
        });
      }
    }
    return;
  }

  if (tempStep.value[stepIndex].attributes.properties) {
    const propStep = tempStep.value[stepIndex].attributes.properties.findIndex(
      (prop) => prop.fieldName === property,
    );

    if (propStep !== -1) {
      tempStep.value[stepIndex].attributes.properties.splice(propStep, 1);
    } else {
      if (propertyType === 'date') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: propertyType,
          fieldName: property,
        });
      }

      if (propertyType === 'array') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: propertyType,
          fieldName: property,
          options: [],
        });
      }

      if (propertyType === 'string') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: propertyType,
          fieldName: property,
          isPhoneNumber: false,
          phoneNumberLength: 10,
        });
      }

      if (propertyType === 'number') {
        tempStep.value[stepIndex].attributes.properties.push({
          type: propertyType,
          fieldName: property,
          comma: false,
          decimal: false,
          decimalPlace: 2,
        });
      }
    }
  }
}

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

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

  if (!defaultPropType) return;

  const idx = tempStep.value[stepIndex].attributes.properties.findIndex(
    (p) => p.fieldName === fieldName,
  );

  if (idx < 0) return;

  if (defaultPropType === 'date') {
    tempStep.value[stepIndex].attributes.properties[idx] = {
      type: defaultPropType,
      fieldName,
    };
  }

  if (defaultPropType === 'array') {
    tempStep.value[stepIndex].attributes.properties[idx] = {
      type: defaultPropType,
      fieldName,
      options: [],
    };
  }

  if (defaultPropType === 'string') {
    tempStep.value[stepIndex].attributes.properties[idx] = {
      type: defaultPropType,
      fieldName,
      isPhoneNumber: false,
      phoneNumberLength: 10,
    };
  }

  if (defaultPropType === 'number') {
    tempStep.value[stepIndex].attributes.properties[idx] = {
      type: defaultPropType,
      fieldName,
      comma: false,
      decimal: false,
      decimalPlace: 2,
    };
  }
}

function shouldShowItem(opt: Option, stepIndex: number) {
  if (tempStep.value[stepIndex].attributes.properties) {
    const properties = new Set(
      tempStep.value[stepIndex].attributes.properties.map((p) => p.fieldName),
    );
    return !!opt && !properties.has(opt.value);
  }
}

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: () => {},
  });
}

function assignTemp() {
  propertiesOption.value = optionStore.globalOption?.servicePropertiesField;

  tempStep.value = JSON.parse(JSON.stringify(dataStep.value));
  tempWorkflowId.value = workflowId.value;
}

watch(
  () => tempWorkflowId.value,
  async (a, b) => {
    if (props.onEdit && workflowId.value === a) return;

    if (props.selectFlow && a !== b && a) {
      const ret = await getWorkflowTemplate(a);
      if (ret) {
        currWorkflow.value = JSON.parse(JSON.stringify(ret));
        tempStep.value =
          ret.step?.length > 0
            ? ret.step.map((s) => ({
                name: s.name,
                attributes: s.attributes,
              }))
            : [];
      }
    }
  },
);

watch(
  () => model.value,
  () => {
    if (model.value) {
      assignTemp();
    }
  },
);
</script>
<template>
  <DialogForm
    no-address
    no-app-box
    height="60vh"
    width="75%"
    :title="$t('general.properties')"
    v-model:modal="model"
    :submit="submit"
    :close="close"
    :show="() => $emit('show')"
  >
    <div class="column full-height no-wrap">
      <div
        v-if="selectFlow"
        class="bordered-b surface-3 row items-center no-wrap q-py-sm"
        :class="{
          'q-px-lg': $q.screen.gt.sm,
          'q-px-md': !$q.screen.gt.sm,
        }"
      >
        {{ $t('flow.title') }}
        <SelectFlow
          style="width: 18vw"
          class="q-ml-sm"
          v-model:value="tempWorkflowId"
          :label="$t('flow.title')"
          simple
        />
      </div>

      <template v-if="$slots.prepend">
        <slot name="prepend"></slot>
      </template>

      <div
        v-if="tempStep?.length === 0"
        class="row surface-1 rounded bordered items-center justify-center col"
        :class="{
          'q-ma-lg': $q.screen.gt.sm,
          'q-ma-md': !$q.screen.gt.sm,
        }"
      >
        <NoData :text="$t('general.no', { msg: $t('flow.processStep') })" />
      </div>

      <section
        v-for="(step, stepIndex) in tempStep"
        :key="stepIndex"
        class="column"
      >
        <template
          v-if="
            (props.stepIndex !== undefined && stepIndex === props.stepIndex) ||
            props.stepIndex === undefined
          "
        >
          <span
            class="row items-center q-py-sm bordered-b"
            :class="{
              'q-px-lg': $q.screen.gt.sm,
              'q-px-md ': !$q.screen.gt.sm,
            }"
          >
            {{ $t('flow.stepNo', { msg: (props.stepIndex || stepIndex) + 1 }) }}
            <span class="app-text-muted">: {{ step.name }}</span>
            <q-btn-dropdown
              unelevated
              no-icon-animation
              size="sm"
              padding="0 0"
              class="rounded q-ml-md"
              dropdown-icon="mdi-plus"
              style="color: hsl(var(--text-mute))"
            >
              <q-list dense v-if="propertiesOption">
                <q-item
                  for="list-all"
                  id="list-all"
                  clickable
                  @click="manageProperties(stepIndex, 'all')"
                >
                  <div class="full-width flex items-center">
                    <q-icon
                      v-if="
                        tempStep[stepIndex].attributes.properties?.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(stepIndex, 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="
                        tempStep[stepIndex].attributes.properties.some(
                          (p) => p.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>
          </span>

          <div
            v-if="tempStep[stepIndex].attributes?.properties?.length === 0"
            class="row surface-1 rounded bordered items-center justify-center col"
            :class="{
              'q-ma-lg': $q.screen.gt.sm,
              'q-ma-md': !$q.screen.gt.sm,
            }"
          >
            <NoData useField />
          </div>

          <div
            v-if="tempStep[stepIndex].attributes?.properties?.length > 0"
            class="q-py-sm"
            :class="{
              'q-px-lg': $q.screen.gt.sm,
              'q-px-md': !$q.screen.gt.sm,
            }"
          >
            <div
              v-for="(prop, propIndex) in tempStep[stepIndex].attributes
                .properties"
              :key="propIndex"
              class="bordered surface-1 rounded q-py-sm q-px-md row items-start q-my-sm"
            >
              <div class="col-md col-12 row items-center">
                <q-btn
                  id="btn-move-up-product"
                  icon="mdi-arrow-up"
                  dense
                  flat
                  round
                  :disable="propIndex === 0"
                  :size="$q.screen.xs ? 'xs' : ''"
                  style="color: hsl(var(--text-mute-2))"
                  @click="
                    moveItemUp(
                      tempStep[stepIndex].attributes.properties,
                      propIndex,
                    )
                  "
                />
                <q-btn
                  id="btn-move-down-product"
                  icon="mdi-arrow-down"
                  dense
                  flat
                  round
                  :size="$q.screen.xs ? 'xs' : ''"
                  :disable="
                    propIndex ===
                    tempStep[stepIndex].attributes.properties?.length - 1
                  "
                  style="color: hsl(var(--text-mute-2))"
                  @click="
                    moveItemDown(
                      tempStep[stepIndex].attributes.properties,
                      propIndex,
                    )
                  "
                />

                <q-avatar
                  :size="$q.screen.xs ? 'sm' : 'md'"
                  class="q-mx-lg"
                  style="background-color: var(--surface-3)"
                >
                  {{ propIndex + 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="prop.fieldName"
                  @update:model-value="(v) => changeType(v, stepIndex)"
                >
                  <template v-slot:option="scope">
                    <q-item
                      v-if="scope.opt && shouldShowItem(scope.opt, stepIndex)"
                      v-bind="scope.itemProps"
                      class="row items-center col-12"
                    >
                      {{ scope.opt.label }}
                    </q-item>
                  </template>
                </q-select>
              </div>

              <!-- type -->
              <div
                v-if="
                  prop.fieldName === 'documentCheck' ||
                  prop.fieldName === 'designForm' ||
                  prop.fieldName === 'messenger' ||
                  prop.fieldName === 'duty'
                "
                class="col-md col-12"
              ></div>
              <div v-else 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 (!tempStep) return;
                      if (t === 'date') {
                        tempStep[stepIndex].attributes.properties[propIndex] = {
                          type: t,
                          fieldName: prop.fieldName,
                        };
                      }

                      if (t === 'array') {
                        tempStep[stepIndex].attributes.properties[propIndex] = {
                          type: t,
                          fieldName: prop.fieldName,
                          options: [],
                        };
                      }

                      if (t === 'string') {
                        tempStep[stepIndex].attributes.properties[propIndex] = {
                          type: t,
                          fieldName: prop.fieldName,
                          isPhoneNumber: false,
                          phoneNumberLength: 10,
                        };
                      }

                      if (t === 'number') {
                        tempStep[stepIndex].attributes.properties[propIndex] = {
                          type: t,
                          fieldName: prop.fieldName,
                          comma: false,
                          decimal: false,
                          decimalPlace: 2,
                        };
                      }
                    }
                  "
                  :options="typeOption"
                  v-model="prop.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="prop.type !== 'date' && prop.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="prop.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-${prop.fieldName}`"
                              v-if="prop.type === 'string'"
                              v-model="prop.isPhoneNumber"
                              size="xs"
                            />
                            {{ $t('general.telephone') }}
                          </div>
                          <q-input
                            v-if="prop.type === 'string'"
                            :for="`input-max-length-${prop.fieldName}`"
                            v-model="prop.phoneNumberLength"
                            input-class="text-caption"
                            class="col additional-label"
                            dense
                            outlined
                            :label="$t('form.maxLength')"
                          />
                        </div>
                      </div>

                      <div v-if="prop.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="prop.comma"
                              size="xs"
                              class="q-py-xs"
                              :for="`checkbox-is-comma-${prop.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="prop.decimal"
                              size="xs"
                              class="q-py-xs"
                              :for="`checkbox-is-decimal-${prop.fieldName}`"
                            />
                            {{ $t('form.decimal') }}
                          </div>
                          <q-input
                            :for="`input-decimal-place-${prop.fieldName}`"
                            v-model="prop.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="prop.type === 'array'" class="q-gutter-y-sm">
                        <div
                          class="row items-center justify-between"
                          v-for="(_, i) in prop.options"
                          :key="i"
                        >
                          <div class="col rounded">
                            <q-input
                              v-model="prop.options[i]"
                              :for="`input-selection-${prop.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-${prop.fieldName}-${i}`"
                              :for="`btn-delete-selection-${prop.fieldName}-${i}`"
                              @click="
                                () => {
                                  prop.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-${prop.fieldName}`"
                            :id="`btn-add-selection-${prop.fieldName}`"
                            @click="
                              () => {
                                prop.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(
                    tempStep[stepIndex].attributes.properties,
                    propIndex,
                  )
                "
              />
            </div>
          </div>
        </template>
      </section>
    </div>
  </DialogForm>
</template>
<style scoped></style>
