<script lang="ts" setup>
import { onMounted, ref, watch } from 'vue';
import { Icon } from '@iconify/vue/dist/iconify.js';
import { moveItemUp, moveItemDown, deleteItem } from 'src/stores/utils';
import { useI18n } from 'vue-i18n';

import useUserStore from 'src/stores/user';
import useOptionStore from 'src/stores/options';
import { baseUrl } from 'stores/utils';
import { getRole } from 'src/services/keycloak';
import {
  WorkflowUserInTable,
  WorkflowTemplatePayload,
  WorkFlowPayloadStep,
} from 'src/stores/workflow-template/types';
import { User } from 'src/stores/user/types';

import SelectMenuWithSearch from '../shared/SelectMenuWithSearch.vue';
import ToggleButton from 'src/components/button/ToggleButton.vue';
import NoData from '../NoData.vue';
import SelectBranch from '../shared/select/SelectBranch.vue';
import AddButton from '../button/AddButton.vue';

defineProps<{
  readonly?: boolean;
  onDrawer?: boolean;
}>();

const { t } = useI18n();
const userStore = useUserStore();
const optionStore = useOptionStore();

const userInTable = defineModel<WorkflowUserInTable[]>('userInTable', {
  default: [],
});
const registerBranchId = defineModel('registerBranchId', { default: '' });
const flowData = defineModel<WorkflowTemplatePayload>('flowData', {
  required: true,
  default: {
    status: 'CREATED',
    name: '',
    step: [],
  },
});

const objectOptions = [
  ...(optionStore.globalOption?.agenciesType || []),
  { label: t('flow.customer'), value: 'customer' },
  { label: t('flow.officer'), value: 'officer' },
];
const options = ref(objectOptions);
const role = ref<string[]>([]);
const userList = ref<User[]>([]);
const responsiblePersonSearch = ref('');

async function getUserList(opts?: { query: string }) {
  const resUser = await userStore.fetchList({
    query: !!opts?.query ? opts.query : undefined,
  });
  if (resUser) userList.value = resUser.result;
}

// async function getUserById(responsiblePersonId: string) {
//   const resUser = await userStore.fetchById(responsiblePersonId);
//   if (resUser) userInTable.value.push(resUser);
// }

function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
  const currStep = flowData.value.step[stepIndex];
  const existPersonIndex = currStep.responsiblePersonId?.findIndex(
    (p) => p === responsiblePerson.id,
  );

  if (existPersonIndex === -1) {
    currStep.responsiblePersonId?.push(responsiblePerson.id);

    if (!userInTable.value[stepIndex]) {
      userInTable.value[stepIndex] = {
        name: flowData.value.step[stepIndex].name,
        responsiblePerson: [],
      };
    }

    userInTable.value[stepIndex]?.responsiblePerson.push({
      id: responsiblePerson.id,
      selectedImage: responsiblePerson.selectedImage,
      gender: responsiblePerson.gender,
      namePrefix: responsiblePerson.namePrefix,
      firstName: responsiblePerson.firstName,
      lastName: responsiblePerson.lastName,
      firstNameEN: responsiblePerson.firstNameEN,
      lastNameEN: responsiblePerson.lastNameEN,
      code: responsiblePerson.code,
    });
  } else {
    currStep.responsiblePersonId?.splice(Number(existPersonIndex), 1);
    userInTable.value[stepIndex]?.responsiblePerson.splice(
      Number(existPersonIndex),
      1,
    );
  }
}

function selectItem(
  val: Record<string, unknown>,
  responsibleInstitution?: string[],
) {
  if (!responsibleInstitution) return;
  const existIndex = responsibleInstitution.findIndex((p) => p === val.value);
  if (existIndex === -1) {
    responsibleInstitution.push(val.value as string);
  } else {
    responsibleInstitution.splice(Number(existIndex), 1);
  }
}

function optionSearch(val: string | null) {
  if (val === '') {
    options.value = objectOptions;
    return;
  }

  const needle = val ? val.toLowerCase() : '';
  options.value = objectOptions.filter(
    (v: { label: string }) => v.label.toLowerCase().indexOf(needle) > -1,
  );
}

defineEmits<{
  (e: 'moveUp'): void;
  (e: 'addStep'): void;
  (e: 'moveDown'): void;
  (e: 'changeStatus'): void;
  (e: 'triggerProperties', step: WorkFlowPayloadStep): void;
}>();

watch(
  responsiblePersonSearch,
  async () => await getUserList({ query: responsiblePersonSearch.value }),
);

onMounted(async () => {
  role.value = getRole() || [];
  await getUserList();
  await userStore.fetchHqOption();
});
</script>

<template>
  <div class="row col-12">
    <section
      :id="`form-flow-template-${onDrawer ? 'drawer' : 'dialog'}`"
      class="col-12 q-pb-sm text-weight-bold text-body1 row items-center"
    >
      <q-icon
        flat
        size="xs"
        class="q-pa-sm rounded q-mr-xs"
        color="info"
        name="mdi-cogs"
        style="background-color: var(--surface-3)"
      />
      {{ $t(`general.name`, { msg: $t('flow.title') }) }}
      <span
        class="row items-center text-weight-regular text-body2"
        :class="{ 'q-ml-lg': $q.screen.gt.xs, 'q-mt-sm': $q.screen.lt.sm }"
      >
        <ToggleButton
          class="q-mr-sm"
          two-way
          :model-value="flowData.status !== 'INACTIVE'"
          @click="
            () => {
              onDrawer
                ? $emit('changeStatus')
                : flowData.status !== 'INACTIVE'
                  ? (flowData.status = 'INACTIVE')
                  : (flowData.status = 'CREATED');
            }
          "
        />
        {{ $t('status.title') }}
      </span>
    </section>

    <section class="col-12 row q-col-gutter-sm">
      <SelectBranch
        v-if="role.includes('system')"
        :label="$t('branch.form.code')"
        :readonly
        code-only
        v-model:value="registerBranchId"
        class="col-md-3 col-12"
        required
      />
      <q-input
        :readonly
        bg-color="transparent"
        outlined
        dense
        class="col"
        for="input-flow-template-name"
        v-model="flowData.name"
        hide-bottom-space
        :label="$t(`general.name`, { msg: $t('flow.step') })"
        :rules="[(val: string) => !!val || $t('form.error.required')]"
      />
    </section>

    <!-- SEC: Step -->
    <section
      :id="`form-flow-step-${onDrawer ? 'drawer' : 'dialog'}`"
      class="col-12 q-pb-sm q-pt-xl text-weight-bold text-body1 row items-center"
    >
      <q-icon
        flat
        size="xs"
        class="q-pa-sm rounded q-mr-xs"
        color="info"
        name="mdi-note-edit-outline"
        style="background-color: var(--surface-3)"
      />
      {{ $t(`flow.processStep`) }}
      <AddButton
        v-if="!readonly && $q.screen.lt.md"
        id="btn-add-work"
        icon-only
        class="q-ml-sm"
        @click="$emit('addStep')"
      />
    </section>

    <section
      v-if="flowData.step.length === 0"
      class="col-12 surface-2 rounded bordered column items-center justify-center q-pa-xl"
    >
      <NoData class="col" />
    </section>

    <section v-else class="col-12 q-gutter-y-md">
      <template v-for="(step, index) in flowData.step" :key="index">
        <div class="bordered rounded">
          <q-expansion-item
            for="item-up"
            id="item-up"
            dense
            switch-toggle-side
            default-opened
            expand-icon="mdi-chevron-down-circle"
            header-class="expansion-rounded surface-2"
            header-style="border-top-left-radius: var(--radius-2); border-top-right-radius: var(--radius-2)"
          >
            <template v-slot:header>
              <div class="column full-width" @keyup.stop @click.stop>
                <div class="row items-center q-py-sm full-width">
                  <q-btn
                    v-if="!readonly"
                    :id="`btn-work-up-product-${step.name || index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :for="`btn-work-up-product-${step.name || index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    icon="mdi-arrow-up"
                    dense
                    flat
                    round
                    :disable="index === 0"
                    style="color: hsl(var(--text-mute-2))"
                    @click.stop="
                      moveItemUp(flowData.step, index);
                      moveItemUp(userInTable, index);
                    "
                  />
                  <q-btn
                    v-if="!readonly"
                    :id="`btn-work-down-product-${step.name || index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :for="`btn-work-down-product-${step.name || index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    icon="mdi-arrow-down"
                    dense
                    flat
                    round
                    class="q-mx-sm"
                    :disable="index === flowData.step.length - 1"
                    style="color: hsl(var(--text-mute-2))"
                    @click.stop="
                      moveItemDown(flowData.step, index);
                      moveItemDown(userInTable, index);
                    "
                  />
                  <q-input
                    :bg-color="readonly ? 'transparent' : ''"
                    :prefix="`${$t('flow.stepNo')} ${index + 1}: `"
                    dense
                    outlined
                    :readonly
                    :id="`input-flow-step-name-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :for="`input-flow-step-name-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    class="col q-ml-md"
                    :placeholder="$t('general.no', { msg: $t('flow.step') })"
                    v-model="step.name"
                    hide-bottom-space
                    :rules="[
                      (val: string) => !!val || $t('form.error.required'),
                    ]"
                  />
                  <!-- <div
                    :for="`select-work-name-${index + 1}`"
                    class="col q-py-sm q-px-md"
                    style="background-color: var(--surface-1); z-index: 2"
                    @click="() => (readonly ? '' : fetchListOfWork())"
                  >
                    <span class="text-body2" style="color: var(--foreground)">
                      {{ $t('productService.service.work') }} {{ index + 1 }} :
                      <span class="app-text-muted-2">
                        {{
                          workName
                            ? workName
                            : $t('productService.service.workName')
                        }}
                      </span>
                    </span>
                    <q-menu
                      v-if="!readonly"
                      fit
                      ref="refMenu"
                      self="top left"
                      anchor="bottom left"
                    >
                      <q-item>
                        <div
                          class="full-width flex items-center justify-between"
                        >
                          {{ $t('productService.service.workName') }}
                          <q-btn
                            dense
                            unelevated
                            class="bordered q-px-sm text-capitalize"
                            style="
                              border-radius: var(--radius-2);
                              color: hsl(var(--info-bg));
                            "
                            @click.stop="
                              () => {
                                refMenu.hide();
                                $emit('manageWorkName');
                              }
                            "
                          >
                            <q-icon name="mdi-cog" size="xs" class="q-mr-sm" />
                            {{ $t('general.manage') }}
                          </q-btn>
                        </div>
                      </q-item>
                      <q-item
                        @click="workName = item.name"
                        clickable
                        v-for="(item, index) in workNameItems"
                        :key="index"
                      >
                        <div class="full-width flex items-center">
                          <q-icon
                            v-if="workName === item.name"
                            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"
                          />
                          {{ item.name }}
                        </div>
                      </q-item>
                    </q-menu>
                  </div> -->
                  <q-btn
                    v-if="!readonly"
                    :id="`btn-delete-work-${step.name || index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    icon="mdi-trash-can-outline"
                    dense
                    flat
                    round
                    padding="0"
                    class="q-ml-md"
                    color="negative"
                    @click="deleteItem(flowData.step, index)"
                  >
                    <q-tooltip>{{ $t('general.delete') }}</q-tooltip>
                  </q-btn>
                </div>
              </div>
            </template>

            <section class="q-px-md surface-2 q-py-sm">
              <div
                :class="{ 'surface-1 rounded bordered': readonly }"
                style="border: 1px solid transparent"
              >
                <div class="row q-col-gutter-sm">
                  <q-input
                    :for="`textarea-detail-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :bg-color="readonly ? 'transparent' : ''"
                    :readonly
                    class="col-md-6 col-12"
                    type="textarea"
                    dense
                    outlined
                    :label="$t('general.detail')"
                    :model-value="!readonly ? step.detail : step.detail || '-'"
                    @update:model-value="
                      (v) => (step.detail = v?.toString() || '')
                    "
                  />
                  <div class="col-md-6 col-12">
                    <div
                      class="surface-1 rounded bordered full-height"
                      style="padding-inline: 12px"
                      :style="readonly ? 'border: 1px solid transparent;' : ''"
                    >
                      <section
                        class="row items-center q-pt-xs justify-between relative-position"
                      >
                        <div
                          class="app-text-muted-2"
                          :style="
                            step.attributes?.properties &&
                            step.attributes?.properties.length > 0
                              ? 'font-size: 10px'
                              : ''
                          "
                        >
                          {{ $t('general.properties') }}
                        </div>
                        <q-btn
                          v-if="!readonly"
                          :id="`btn-add-work-product-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                          class="text-capitalize rounded absolute-top-right"
                          flat
                          dense
                          padding="4px 8px"
                          style="color: hsl(var(--info-bg)); top: 4px"
                          @click.stop="$emit('triggerProperties', step)"
                        >
                          <Icon
                            icon="basil:settings-adjust-solid"
                            width="20.08px"
                            style="color: hsl(var(--info-bg))"
                          />
                        </q-btn>
                      </section>
                      <section class="row q-gutter-sm q-pb-sm scroll">
                        <span
                          v-for="(att, i) in step.attributes?.properties"
                          :key="i"
                          class="surface-2 bordered rounded q-px-xs"
                        >
                          {{ optionStore.mapOption(att.fieldName ?? '') }}
                        </span>
                      </section>
                    </div>
                  </div>

                  <!-- RESPONSIBLE-PERSON -->
                  <q-select
                    v-if="step.responsiblePersonId"
                    behavior="menu"
                    :for="`select-responsible-person-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :bg-color="readonly ? 'transparent' : ''"
                    :readonly
                    outlined
                    dense
                    v-model="step.responsiblePersonId"
                    multiple
                    :options="[1, 2, 3]"
                    hide-bottom-space
                    option-label="label"
                    option-value="value"
                    emit-value
                    :label="$t('flow.responsiblePerson')"
                    class="col-md-6 col-12"
                    :hide-dropdown-icon="readonly"
                  >
                    <template v-slot:selected-item="scope">
                      <div class="column full-width">
                        <div
                          class="row items-center no-wrap"
                          v-for="person in userInTable[
                            index
                          ]?.responsiblePerson.filter(
                            (p) => p.id === scope.opt,
                          )"
                          :key="person.id"
                        >
                          <q-avatar class="q-ml-sm" size="md">
                            <q-img
                              class="text-center"
                              :ratio="1"
                              :src="`${baseUrl}/user/${person.id}/profile-image/${person.selectedImage}`"
                            >
                              <template #error>
                                <div
                                  class="no-padding full-width full-height flex items-center justify-center"
                                  :style="`${person.gender ? 'background: white' : 'background: linear-gradient(135deg,rgba(43, 137, 223, 1) 0%, rgba(230, 51, 81, 1) 100%);'}`"
                                >
                                  <q-img
                                    v-if="person.gender"
                                    :src="
                                      person.gender === 'male'
                                        ? '/no-img-man.png'
                                        : '/no-img-female.png'
                                    "
                                  />
                                  <q-icon
                                    v-else
                                    size="sm"
                                    name="mdi-account-outline"
                                    style="color: white"
                                  />
                                </div>
                              </template>
                            </q-img>
                          </q-avatar>
                          <div
                            class="column q-pl-md"
                            style="color: var(--foreground)"
                          >
                            <span>
                              {{
                                `${optionStore.mapOption(person.namePrefix || '')} ${
                                  $i18n.locale === 'eng'
                                    ? person.firstNameEN
                                    : person.firstName
                                } ${
                                  $i18n.locale === 'eng'
                                    ? person.lastNameEN
                                    : person.lastName
                                }`
                              }}
                            </span>
                            <span class="text-caption app-text-muted">
                              {{ person.code }}
                            </span>
                          </div>
                        </div>
                      </div>
                    </template>

                    <template v-slot:option></template>
                    <q-menu v-if="!readonly" :offset="[0, 4]">
                      <q-list>
                        <q-item>
                          <q-input
                            :for="`input-search-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                            outlined
                            dense
                            :label="$t('general.search')"
                            class="col responsible-search"
                            :bg-color="$q.dark.isActive ? 'dark' : 'white'"
                            v-model="responsiblePersonSearch"
                            debounce="200"
                          >
                            <template #prepend>
                              <q-icon name="mdi-magnify" />
                            </template>
                          </q-input>
                        </q-item>
                        <span class="text-caption app-text-muted-2 q-px-md">
                          {{ $t('general.people') }}
                        </span>

                        <q-item
                          v-if="userList.length === 0"
                          class="app-text-muted q-px-lg"
                        >
                          {{ $t('general.noData') }}
                        </q-item>
                        <q-item
                          v-for="(person, i) in userList"
                          dense
                          :key="i"
                          clickable
                          class="column"
                          @click.stop="selectResponsiblePerson(index, person)"
                        >
                          <div
                            class="row items-center no-wrap"
                            :id="`select-responsible-person-${index}-${person.firstName || person.firstNameEN}-${onDrawer ? 'drawer' : 'dialog'}`"
                          >
                            <q-checkbox
                              size="xs"
                              :model-value="
                                step.responsiblePersonId.includes(person.id)
                              "
                              @click.stop="
                                selectResponsiblePerson(index, person)
                              "
                            />
                            <q-avatar class="q-ml-sm" size="md">
                              <q-img
                                class="text-center"
                                :ratio="1"
                                :src="`${baseUrl}/user/${person.id}/profile-image/${person.selectedImage}`"
                              >
                                <template #error>
                                  <div
                                    class="no-padding full-width full-height flex items-center justify-center"
                                    :style="`${person.gender ? 'background: white' : 'background: linear-gradient(135deg,rgba(43, 137, 223, 1) 0%, rgba(230, 51, 81, 1) 100%);'}`"
                                  >
                                    <q-img
                                      v-if="person.gender"
                                      :src="
                                        person.gender === 'male'
                                          ? '/no-img-man.png'
                                          : '/no-img-female.png'
                                      "
                                    />
                                    <q-icon
                                      v-else
                                      size="sm"
                                      name="mdi-account-outline"
                                      style="color: white"
                                    />
                                  </div>
                                </template>
                              </q-img>
                            </q-avatar>
                            <div class="column q-pl-md">
                              <span>
                                {{
                                  `${optionStore.mapOption(person.namePrefix || '')} ${
                                    $i18n.locale === 'eng'
                                      ? person.firstNameEN
                                      : person.firstName
                                  } ${
                                    $i18n.locale === 'eng'
                                      ? person.lastNameEN
                                      : person.lastName
                                  }`
                                }}
                              </span>
                              <span class="text-caption app-text-muted">
                                {{ person.code }}
                              </span>
                            </div>
                          </div>
                        </q-item>

                        <span class="text-caption app-text-muted-2 q-px-md">
                          {{ $t('personnel.MESSENGER') }}
                        </span>
                        <q-item
                          clickable
                          @click="step.messengerByArea = !step.messengerByArea"
                          class="column"
                        >
                          <div class="row items-center">
                            <q-checkbox
                              :id="`select-area-${index}`"
                              v-model="step.messengerByArea"
                              size="xs"
                            ></q-checkbox>
                            <div class="column q-pl-md">
                              <span>{{ $t('general.byArea') }}</span>
                            </div>
                          </div>
                        </q-item>
                      </q-list>
                    </q-menu>
                  </q-select>

                  <!-- RESPONSIBLE-AGENCIES, RESPONSIBLE-INSTITUTION -->
                  <q-select
                    behavior="menu"
                    :for="`select-responsible-institution-${index}-${onDrawer ? 'drawer' : 'dialog'}`"
                    :bg-color="readonly ? 'transparent' : ''"
                    :readonly
                    outlined
                    dense
                    v-model="step.responsibleInstitution"
                    multiple
                    :options="options"
                    hide-bottom-space
                    option-label="label"
                    option-value="value"
                    emit-value
                    :label="
                      $t('general.select', { msg: $t('general.agencies') })
                    "
                    class="col-md-6 col-12"
                    :hide-dropdown-icon="readonly"
                  >
                    <template v-slot:selected-item="scope">
                      <q-chip
                        dense
                        :removable="!readonly"
                        @remove="scope.removeAtIndex(scope.index)"
                      >
                        <span class="text-caption">
                          {{
                            scope.opt === 'customer'
                              ? $t('flow.customer')
                              : scope.opt === 'officer'
                                ? $t('flow.officer')
                                : optionStore.mapOption(
                                    scope.opt,
                                    'agenciesType',
                                  )
                          }}
                        </span>
                      </q-chip>
                    </template>
                    <template v-slot:option></template>

                    <SelectMenuWithSearch
                      v-if="!readonly"
                      :title="
                        $t('general.select', { msg: $t('general.agencies') })
                      "
                      :option="options"
                      :separator-index="[9]"
                      width="353.66px"
                      @search="(v) => optionSearch(v as string)"
                      @select="
                        (v) => selectItem(v, step.responsibleInstitution)
                      "
                      @before-show="
                        () => {
                          objectOptions = [
                            ...(optionStore.globalOption?.agenciesType || []),
                            { label: t('flow.customer'), value: 'customer' },
                            { label: t('flow.officer'), value: 'officer' },
                          ];
                          options = objectOptions;
                        }
                      "
                    >
                      <template #prepend>
                        <q-separator></q-separator>
                      </template>
                      <template
                        #option="{ opt }"
                        v-if="step.responsibleInstitution"
                      >
                        <q-checkbox
                          :id="`select-responsible-institution-${index}-${opt.value}-${onDrawer ? 'drawer' : 'dialog'}`"
                          :model-value="
                            step.responsibleInstitution.some(
                              (v: string) => v === opt.value,
                            )
                          "
                          class="q-pr-sm"
                          size="xs"
                          @click="selectItem(opt, step.responsibleInstitution)"
                        />
                        <span
                          :class="{
                            'app-text-info': step.responsibleInstitution.some(
                              (v: string) => v === opt.value,
                            ),
                          }"
                        >
                          {{ opt.label }}
                        </span>
                      </template>
                    </SelectMenuWithSearch>
                  </q-select>
                </div>
              </div>
            </section>
          </q-expansion-item>
        </div>
      </template>
    </section>
  </div>
</template>

<style scoped>
:deep(.responsible-search .q-field__control) {
  height: 36px;
  font-size: 12px;
}

:deep(
    .q-item__section.column.q-item__section--side.justify-center.q-item__section--avatar.q-focusable.relative-position.cursor-pointer
  ) {
  justify-content: start !important;
  padding-right: 8px !important;
  padding-top: 16px;
  min-width: 0px;
}

:deep(i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon) {
  color: hsl(var(--text-mute));
}

:deep(
    i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
  ) {
  color: var(--brand-1);
}

:deep(
    .q-item.q-item-type.row.no-wrap.q-item--dense.q-item--clickable.q-link.cursor-pointer.q-focusable.q-hoverable.expansion-rounded.surface-2
      .q-focus-helper
  ) {
  visibility: hidden;
}

:deep(.q-dialog.fullscreen.no-pointer-events.q-dialog--modal) {
  visibility: hidden;
}
</style>
