<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <div style="width: 100%; max-width: 1100px">
      <q-card
        class="dialog-form-card"
        style="height: 560px"
      >
        <DefaultDialogHeader
          :title="card ? 'Editar Atividade' : 'Adicionar Atividade'"
          @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="card?.id"
                v-model:active-tab="currentTab"
                class="q-mb-md"
                :tabs="tabs"
              />

              <div v-show="currentTab === 'atividade'">
                <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.scope"
                    v-model:error="validationErrors.scope"
                    class="col-6"
                    emit-value
                    label="Destino"
                    map-options
                    :options="scopeOptions"
                    :rules="[inputRules.required]"
                    @update:model-value="onScopeChange"
                  />

                  <DefaultInputDatePicker
                    v-model="form.due_date_display"
                    v-model:untreated-date="form.due_date"
                    class="col-6"
                    label="Prazo de Entrega"
                  />

                  <DefaultSelect
                    v-if="form.scope === 'internal'"
                    v-model="form.responsible_user_id"
                    class="col-12"
                    clearable
                    emit-value
                    label="Responsável"
                    map-options
                    :options="userOptions"
                  />

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

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

                  <DefaultInput
                    v-model="form.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"
                  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">
                    <KanbanCommentCard
                      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>

              <div v-show="currentTab === 'midias'">
                <div
                  v-if="canAdd"
                  class="flex justify-end q-mb-sm"
                >
                  <q-btn
                    color="primary"
                    icon="mdi-upload-outline"
                    style="width: 40px; height: 40px"
                    unelevated
                    :loading="uploadingMedia"
                    @click="triggerFileInput"
                  />

                  <input
                    ref="fileInputRef"
                    style="display: none"
                    type="file"
                    @change="onFileSelected"
                  />
                </div>

                <div
                  style="
                    display: flex;
                    flex-direction: column;
                    gap: 8px;
                  "
                >
                  <template v-if="medias.length">
                    <KanbanMediaCard
                      v-for="media in medias"
                      :key="media.id"
                      :created-at="media.created_at"
                      :file-name="media.file_name"
                      :file-url="media.file_url"
                      :mime-type="media.mime_type"
                      :user-name="media.user_name"
                      @delete="onDeleteMedia(media)"
                    />
                  </template>

                  <div
                    v-else
                    class="flex flex-center full-height text-grey-5 text-body2"
                  >
                    Nenhuma mídia anexada.
                  </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="canSave"
              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 { createKanban, updateKanban } from "src/api/kanban";

import {
  createKanbanReply,
  deleteKanbanReply,
  getKanbanReplies,
  updateKanbanReply,
} from "src/api/kanban_reply";

import {
  deleteKanbanMedia,
  getKanbanMedias,
  uploadKanbanMedia,
} from "src/api/kanban_media";

import { getUsersByUnit } from "src/api/user";
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 DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultForm from "src/components/defaults/DefaultForm.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import CustomTabComponent from "src/components/shared/CustomTabComponent.vue";
import KanbanCommentCard from "./KanbanCommentCard.vue";
import KanbanMediaCard from "./KanbanMediaCard.vue";

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

const { card, initialPhase } = defineProps({
  card: {
    type: Object,
    default: null,
  },
  initialPhase: {
    type: String,
    default: "a_fazer",
  },
});

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

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

const permissions = permissionStore();

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

const currentTab = ref("atividade");
const medias = ref([]);
const replies = ref([]);
const uploadingMedia = ref(false);
const userOptions = ref([]);

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

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

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

const tabs = computed(() => [
  {
    label: "Atividade",
    name: "atividade",
  },
  {
    label: "Comentários",
    name: "comentarios",
  },
  {
    label: "Mídias",
    name: "midias",
  },
]);

const phaseOptions = [
  {
    label: "A Fazer",
    value: "a_fazer",
  },
  {
    label: "Em Progresso",
    value: "em_progresso",
  },
  {
    label: "Em Revisão",
    value: "em_revisao",
  },
  {
    label: "Concluído",
    value: "concluido",
  },
  {
    label: "Demandas Especiais",
    value: "demandas_especiais",
  },
];

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

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

const formatDisplayDate = (rawDate) => {
  if (!rawDate) return null;

  const [year, month, day] = rawDate.split("-");

  return `${day}/${month}/${year}`;
};

const { form, getUpdatedFields } = useForm({
  description: card?.description ?? null,
  due_date: card?.due_date ?? null,
  due_date_display: formatDisplayDate(card?.due_date),
  phase: card?.phase ?? initialPhase,
  priority: card?.priority ?? "normal",
  responsible_user_id: card?.responsible_user_id ?? null,
  scope: card?.scope ?? "internal",
  sector: card?.sector ?? null,
  title: card?.title ?? null,
});

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

const buildPayload = () => ({
  description: form.description || null,
  due_date: form.due_date || null,
  phase: form.phase,
  priority: form.priority,

  responsible_user_id:
    form.scope === "internal"
      ? form.responsible_user_id || null
      : null,

  scope: form.scope,
  sector: form.sector || null,
  target_unit_id: null,
  title: form.title,
});

const loadMedias = async () => {
  if (!card?.id) return;

  medias.value = await getKanbanMedias(card.id);
};

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

  replies.value = await getKanbanReplies(card.id);
};

const loadUsers = async () => {
  try {
    const users = await getUsersByUnit();

    userOptions.value = users.map((user) => ({
      label: user.name,
      value: user.id,
    }));
  } catch (error) {
    console.error("Erro ao carregar usuários:", error);
  }
};

const onAddComment = () => {
  $q.dialog({
    cancel: {
      color: "primary",
      label: "Cancelar",
      outline: true,
    },
    ok: {
      color: "primary",
      label: "Salvar",
    },
    prompt: {
      label: "Comentário",
      model: "",
      type: "textarea",
    },
    title: "Adicionar Comentário",
  }).onOk(async (text) => {
    const comment = text?.trim();

    if (!comment) return;

    await createKanbanReply(card.id, {
      reply: comment,
    });

    loadReplies();
  });
};

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 deleteKanbanReply(card.id, reply.id);

    loadReplies();
  });
};

const onDeleteMedia = (media) => {
  $q.dialog({
    cancel: {
      color: "primary",
      label: "Cancelar",
      outline: true,
    },
    message: `Deseja excluir "${media.file_name}"?`,
    ok: {
      color: "negative",
      label: "Excluir",
    },
    title: "Excluir Mídia",
  }).onOk(async () => {
    await deleteKanbanMedia(card.id, media.id);

    loadMedias();
  });
};

const onEditComment = (reply) => {
  $q.dialog({
    cancel: {
      color: "primary",
      label: "Cancelar",
      outline: true,
    },
    ok: {
      color: "primary",
      label: "Salvar",
    },
    prompt: {
      label: "Comentário",
      model: reply.reply,
      type: "textarea",
    },
    title: "Editar Comentário",
  }).onOk(async (text) => {
    const comment = text?.trim();

    if (!comment) return;

    await updateKanbanReply(card.id, reply.id, {
      reply: comment,
    });

    loadReplies();
  });
};

const onFileSelected = async (event) => {
  const file = event.target.files?.[0];

  if (!file) return;

  uploadingMedia.value = true;

  try {
    await uploadKanbanMedia(card.id, file);

    await loadMedias();
  } finally {
    uploadingMedia.value = false;
    event.target.value = "";
  }
};

const onOKClick = async () => {
  const payload = buildPayload();

  await execute(() => {
    if (!card?.id) {
      return createKanban(payload);
    }

    const changedFields = getUpdatedFields.value;
    const updatePayload = {};

    for (const key of [
      "title",
      "priority",
      "phase",
      "scope",
      "sector",
      "description",
      "responsible_user_id",
    ]) {
      if (key in changedFields) {
        updatePayload[key] = payload[key];
      }
    }

    if (
      "due_date" in changedFields ||
      "due_date_display" in changedFields
    ) {
      updatePayload.due_date = payload.due_date;
    }

    return updateKanban(card.id, updatePayload);
  });
};

const onScopeChange = (value) => {
  if (value === "internal") return;

  form.responsible_user_id = null;
};

const triggerFileInput = () => {
  fileInputRef.value?.click();
};

onMounted(() => {
  loadUsers();
  loadReplies();
  loadMedias();
});
</script>
