<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <div style="width: 100%; max-width: 1100px">
      <q-card
        class="dialog-form-card"
        style="height: 500px"
      >
        <DefaultDialogHeader
          :title="ticket ? 'Editar Ticket' : 'Novo Ticket'"
          @close="onDialogCancel"
        />

        <DefaultForm
          ref="formRef"
          style="
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
          "
          @submit="onOKClick"
        >
          <q-scroll-area
            ref="scrollAreaRef"
            class="dialog-form-scroll"
          >
            <q-card-section class="q-pt-sm">
              <CustomTabComponent
                v-if="ticket?.id"
                v-model:active-tab="currentTab"
                class="q-mb-md"
                :tabs="tabs"
              />

              <div v-show="currentTab === 'ticket'">
                <div class="row q-col-gutter-sm">
                  <DefaultInput
                    v-model="form.title"
                    v-model:error="validationErrors.title"
                    class="col-12"
                    label="Título da Tarefa"
                    :rules="[inputRules.required]"
                  />

                  <DefaultSelect
                    v-model="form.severity"
                    v-model:error="validationErrors.severity"
                    class="col-6"
                    emit-value
                    label="Prioridade"
                    map-options
                    :options="priorityOptions"
                    :rules="[inputRules.required]"
                  />

                  <DefaultInput
                    :model-value="user?.name"
                    class="col-6"
                    disable
                    label="Responsável"
                  />

                  <DefaultSelect
                    v-model="form.scope"
                    v-model:error="validationErrors.scope"
                    class="col-6"
                    emit-value
                    label="Destino"
                    map-options
                    :options="unitTargetOptions"
                    :rules="[inputRules.required]"
                  />

                  <DefaultInput
                    v-model="form.sector"
                    v-model:error="validationErrors.sector"
                    class="col-6"
                    label="Setor"
                  />

                  <DefaultInput
                    v-model="form.description"
                    class="col-12"
                    label="Descrição"
                    type="textarea"
                  />
                </div>
              </div>

              <div v-show="currentTab === 'comentarios'">
                <div
                  v-if="canAdd && ticket?.status === 'in_progress'"
                  class="flex justify-end q-mb-sm"
                >
                  <q-btn
                    color="primary"
                    icon="mdi-plus"
                    style="width: 40px; height: 40px"
                    unelevated
                    @click="onAddComment"
                  />
                </div>

                <div
                  style="
                    display: flex;
                    flex-direction: column;
                    gap: 8px;
                  "
                >
                  <template v-if="replies.length">
                    <TicketCommentCard
                      v-for="reply in replies"
                      :key="reply.id"
                      :created-at="reply.created_at"
                      :reply="reply.reply"
                      :user-name="reply.user_name"
                      @delete="onDeleteComment(reply)"
                      @edit="onEditComment(reply)"
                    />
                  </template>

                  <div
                    v-else
                    class="flex flex-center full-height text-grey-5 text-body2"
                  >
                    Nenhum comentário registrado.
                  </div>
                </div>
              </div>
            </q-card-section>
          </q-scroll-area>

          <q-card-actions
            align="right"
            class="q-px-md q-pb-md"
            style="flex-shrink: 0"
          >
            <q-btn
              color="primary"
              label="Cancelar"
              no-caps
              outline
              @click="onDialogCancel"
            />

            <q-btn
              v-if="
                canEdit &&
                canManage &&
                ticket?.id &&
                ticket?.status === 'in_progress'
              "
              color="negative"
              label="Encerrar"
              no-caps
              outline
              @click="onCloseTicket"
            />

            <q-btn
              v-if="
                canSave &&
                canManage &&
                (!ticket?.id || ticket?.status === 'in_progress')
              "
              color="primary"
              label="Salvar"
              no-caps
              type="submit"
              :loading="loading"
            />
          </q-card-actions>
        </DefaultForm>
      </q-card>
    </div>
  </q-dialog>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";

import {
  createSupportTicket,
  updateSupportTicket,
} from "src/api/support_ticket";

import {
  deleteSupportReply,
  getSupportReplies,
} from "src/api/support_reply";

import { permissionStore } from "src/stores/permission";
import { useDialogPluginComponent, useQuasar } from "quasar";
import { useForm } from "src/composables/useForm";
import { useInputRules } from "src/composables/useInputRules";
import { useScroll } from "src/composables/useScroll";
import { useSubmitHandler } from "src/composables/useSubmitHandler";
import { userStore } from "src/stores/user";

import AddEditReplyDialog from "./AddEditReplyDialog.vue";
import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
import CloseTicketDialog from "./CloseTicketDialog.vue";
import TicketCommentCard from "./TicketCommentCard.vue";

import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultForm from "src/components/defaults/DefaultForm.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";

defineEmits([...useDialogPluginComponent.emits]);

const { ticket } = defineProps({
  ticket: {
    type: Object,
    default: null,
  },
});

const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  useDialogPluginComponent();

const $q = useQuasar();
const { inputRules } = useInputRules();
const { scrollToComponent } = useScroll();

const permissions = permissionStore();
const { user } = userStore();

const formRef = ref(null);
const scrollAreaRef = ref(null);

const currentTab = ref("ticket");
const replies = ref([]);

const canAdd = computed(() =>
  permissions.getAccess("franchisee_support", "add"),
);

const canEdit = computed(() =>
  permissions.getAccess("franchisee_support", "edit"),
);

const canManage = computed(
  () =>
    !ticket?.id ||
    (ticket?.origin === "unit" &&
      ticket?.scope === "internal"),
);

const canSave = computed(() =>
  ticket?.id ? canEdit.value : canAdd.value,
);

const tabs = computed(() => {
  const items = [
    {
      label: "Ticket",
      name: "ticket",
    },
  ];

  if (ticket?.id) {
    items.push({
      label: "Comentários",
      name: "comentarios",
    });
  }

  return items;
});

const priorityOptions = [
  {
    label: "Alta",
    value: "alta",
  },
  {
    label: "Normal",
    value: "normal",
  },
  {
    label: "Baixa",
    value: "baixa",
  },
];

const unitTargetOptions = [
  {
    label: "Suporte à Matriz",
    value: "specific",
  },
  {
    label: "Suporte Interno",
    value: "internal",
  },
];

const { form, getUpdatedFields } = useForm({
  description: ticket?.description ?? null,
  scope: ticket?.scope ?? null,
  sector: ticket?.sector ?? null,
  severity: ticket?.severity ?? null,
  title: ticket?.title ?? null,
});

const {
  loading,
  validationErrors,
  execute,
} = useSubmitHandler({
  containerRef: scrollAreaRef,
  formRef,
  onSuccess: () => {
    onDialogOK(true);
  },
  scrollFn: scrollToComponent,
});

const buildPayload = () => ({
  description: form.description || null,
  scope: form.scope,
  sector: form.sector || null,
  severity: form.severity,
  target_unit_id: null,
  title: form.title,
});

const loadReplies = async () => {
  if (!ticket?.id) return;

  replies.value = await getSupportReplies(ticket.id);
};

const onAddComment = () => {
  $q.dialog({
    component: AddEditReplyDialog,
    componentProps: {
      ticketId: ticket.id,
    },
  }).onOk(loadReplies);
};

const onCloseTicket = () => {
  $q.dialog({
    component: CloseTicketDialog,
    componentProps: {
      ticket,
    },
  }).onOk(() => {
    onDialogOK(true);
  });
};

const onDeleteComment = (reply) => {
  $q.dialog({
    cancel: {
      color: "primary",
      label: "Cancelar",
      outline: true,
    },
    message: "Tem certeza que deseja excluir este comentário?",
    ok: {
      color: "negative",
      label: "Excluir",
    },
    title: "Excluir Comentário",
  }).onOk(async () => {
    await deleteSupportReply(ticket.id, reply.id);

    loadReplies();
  });
};

const onEditComment = (reply) => {
  $q.dialog({
    component: AddEditReplyDialog,
    componentProps: {
      replyItem: reply,
      ticketId: ticket.id,
    },
  }).onOk(loadReplies);
};

const onOKClick = async () => {
  const payload = ticket?.id
    ? { ...getUpdatedFields.value }
    : buildPayload();

  await execute(() => {
    if (ticket?.id) {
      return updateSupportTicket(ticket.id, payload);
    }

    return createSupportTicket(payload);
  });
};

onMounted(loadReplies);
</script>