<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <q-card
      class="q-dialog-plugin overflow-hidden column no-wrap"
      :style="dialogCardStyle"
    >
      <DefaultDialogHeader
        :title="props.contract ? 'Editar Contrato' : 'Novo Contrato'"
        @close="onDialogCancel"
      />

      <template v-if="props.contract">
        <q-tabs
          v-model="activeTab"
          dense
          align="left"
          class="q-px-md text-grey-7"
          active-color="primary"
          indicator-color="primary"
        >
          <q-tab name="dados" label="Dados do Contrato" />
          <q-tab name="midias" label="Mídias do Contrato" />
        </q-tabs>
        <q-separator />
      </template>

      <q-card-section class="q-pt-sm col" style="overflow-y: auto">
        <div v-show="activeTab === 'dados'">
        <div class="text-subtitle1 q-mb-md">Dados do Aluno</div>

        <div class="row q-col-gutter-sm">
          <div v-if="props.selectStudent" class="col-12">
            <DefaultSelect
              v-model="selectedStudent"
              label="Aluno"
              :options="filteredStudents"
              option-label="name"
              use-input
              fill-input
              hide-selected
              input-debounce="0"
              dropdown-icon="mdi-magnify"
              @filter="filterStudents"
            />
          </div>

          <div v-if="!props.selectStudent" class="col-12">
            <DefaultInput
              :model-value="currentStudent?.name"
              label="Aluno"
              disable
            />
          </div>

          <div v-if="props.selectStudent" class="col-12 col-md-4">
            <DefaultInput
              :model-value="currentStudent?.id"
              label="ID do Aluno"
              disable
            />
          </div>

          <div :class="props.selectStudent ? 'col-12 col-md-4' : 'col-6'">
            <DefaultInput
              :model-value="currentStudent?.document_number"
              label="CPF / CNH"
              disable
            />
          </div>

          <div :class="props.selectStudent ? 'col-12 col-md-4' : 'col-6'">
            <DefaultInput
              :model-value="formattedBirthDate"
              label="Data de Nascimento"
              disable
            />
          </div>
        </div>

        <div class="text-subtitle1 q-mt-lg q-mb-md">Dados do Contrato</div>

        <div class="row q-col-gutter-sm">
          <div class="col-4">
            <DefaultInput v-model="form.protocol" label="Protocolo" />
          </div>

          <div class="col-4">
            <DefaultInputDatePicker
              v-model="form.signature_date"
              label="Data Assinatura"
            />
          </div>

          <div class="col-4">
            <DefaultInputDatePicker
              v-model="form.end_date"
              label="Data Encerramento"
            />
          </div>

          <div class="col-5">
            <DefaultSelect
              v-model="form.package_id"
              label="Pacote de Aulas"
              :options="packages"
              option-value="id"
              option-label="name"
              emit-value
              map-options
            />
          </div>

          <div class="col-7">
            <DefaultInput
              v-model="form.class_quantity"
              label="Qtd. Aulas"
              type="number"
              disable
            />
          </div>

          <div class="col-4">
            <DefaultSelect
              v-model="form.weekday"
              label="Dia da Semana"
              :options="weekdays"
              option-value="value"
              option-label="label"
              emit-value
              map-options
            />
          </div>

          <div class="col-4">
            <DefaultInput
              v-model="form.start_time"
              label="Hora de Início"
              mask="##:##"
            >
              <template #append>
                <q-icon name="mdi-clock-outline" />
              </template>
            </DefaultInput>
          </div>

          <div class="col-4">
            <DefaultInput
              v-model="form.end_time"
              label="Hora de Término"
              mask="##:##"
            >
              <template #append>
                <q-icon name="mdi-clock-outline" />
              </template>
            </DefaultInput>
          </div>

          <div class="col-4">
            <DefaultSelect
              v-model="form.second_weekday"
              label="2° Dia da Semana"
              :options="weekdays"
              option-value="value"
              option-label="label"
              emit-value
              map-options
            />
          </div>

          <div class="col-4">
            <DefaultInput
              v-model="form.second_start_time"
              label="Hora de Início"
              mask="##:##"
            >
              <template #append>
                <q-icon name="mdi-clock-outline" />
              </template>
            </DefaultInput>
          </div>

          <div class="col-4">
            <DefaultInput
              v-model="form.second_end_time"
              label="Hora de Término"
              mask="##:##"
            >
              <template #append>
                <q-icon name="mdi-clock-outline" />
              </template>
            </DefaultInput>
          </div>
        </div>

        <div class="text-subtitle1 q-mt-lg q-mb-md">Dados Financeiros</div>

        <div class="row q-col-gutter-sm">
          <div class="col-4">
            <DefaultInput
              v-model="form.due_day"
              label="Dia de Vencimento"
              type="number"
            />
          </div>
        </div>

        <div class="text-subtitle2 q-mt-md q-mb-sm text-grey-8">Matrícula</div>
        <div class="row q-col-gutter-sm">
          <div class="col-3">
            <DefaultCurrencyInput
              v-model="form.enrollment_fee"
              label="Valor da Matrícula"
              disable
            />
          </div>

          <div class="col-3">
            <DefaultSelect
              v-model="form.installments"
              label="Qtde Parcelas"
              :options="enrollmentInstallmentOptions"
              option-value="value"
              option-label="label"
              emit-value
              map-options
            />
          </div>

          <div class="col-3">
            <DefaultCurrencyInput
              :model-value="enrollmentInstallmentValue"
              label="Valor da Parcela"
              disable
            />
          </div>

          <div class="col-3">
            <DefaultInputDatePicker
              v-model="form.enrollment_due_date"
              label="Data Vencimento"
            />
          </div>
        </div>

        <div class="text-subtitle2 q-mt-md q-mb-sm text-grey-8">Pacote</div>
        <div class="row q-col-gutter-sm">
          <div class="col-3">
            <DefaultCurrencyInput
              v-model="form.package_value"
              label="Valor do Pacote"
              disable
            />
          </div>

          <div class="col-3">
            <DefaultSelect
              v-model="form.package_installments"
              label="Qtde Parcelas"
              :options="packageInstallmentOptions"
              option-value="value"
              option-label="label"
              emit-value
              map-options
            />
          </div>

          <div class="col-3">
            <DefaultCurrencyInput
              :model-value="packageInstallmentValue"
              label="Valor da Parcela"
              disable
            />
          </div>

          <div class="col-3">
            <DefaultInputDatePicker
              v-model="form.package_due_date"
              label="Data 1ª Parcela"
            />
          </div>
        </div>

        <div class="row q-col-gutter-sm q-mt-xs">
          <div class="col-6">
            <DefaultInput
              v-model="form.early_payment_discount"
              label="Desconto até o vencimento (%)"
              type="number"
            />
          </div>

          <div class="col-6">
            <DefaultSelect
              v-model="form.payment_method"
              label="Forma de Pagamento"
              :options="paymentMethods"
              option-value="value"
              option-label="label"
              emit-value
              map-options
            />
          </div>

          <div class="col-6">
            <DefaultInput
              v-model="form.interest_rate"
              label="Juros (%) a.m"
              type="number"
            />
          </div>

          <div class="col-6">
            <DefaultInput
              v-model="form.late_fee"
              label="Multa (%)"
              type="number"
            />
          </div>
        </div>
        </div>

        <div v-if="props.contract" v-show="activeTab === 'midias'">
          <DefaultTable
            v-model:rows="medias"
            title="Mídias"
            :columns="mediaColumns"
            descricao="mídias"
            :feminino="true"
            no-api-call
            :show-search-field="false"
            :loading="loadingMedias"
          >
            <template #body-cell-actions="{ row }">
              <q-td align="center">
                <q-item-section class="no-wrap" style="flex-direction: row; gap: 4px">
                  <q-btn
                    outline
                    icon="mdi-eye-outline"
                    style="width: 36px"
                    @click.prevent.stop="openFile(row.file_url)"
                  />
                  <q-btn
                    outline
                    icon="mdi-trash-can-outline"
                    style="width: 36px"
                    color="negative"
                    @click.prevent.stop="handleDeleteMedia(row)"
                  />
                </q-item-section>
              </q-td>
            </template>
          </DefaultTable>
        </div>
      </q-card-section>

      <q-separator />

      <q-card-actions align="right">
        <q-btn
          outline
          color="primary"
          label="CANCELAR"
          @click="onDialogCancel"
        />
        <q-btn
          v-if="activeTab === 'dados'"
          color="primary"
          label="SALVAR"
          :loading="saving"
          @click="handleSave"
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { computed, ref, watch, onMounted, nextTick } from "vue";
import { useDialogPluginComponent, useQuasar } from "quasar";
import { addYears, format } from "date-fns";
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import DefaultTable from "src/components/defaults/DefaultTable.vue";
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
import { useSubmitHandler } from "src/composables/useSubmitHandler";
import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
import { formatDateYMDtoDMY, formatDateDMYtoYMD } from "src/helpers/utils";
import { getUnitPackagesForSelect } from "src/api/package";
import { getFinancialMe } from "src/api/unit_financial";
import { permissionStore } from "src/stores/permission";
import {
  createStudentContract,
  updateStudentContract,
} from "src/api/studentContract";
import { getContractMedias, deleteContractMedia } from "src/api/student_media";
import { getStudentsForSelect } from "src/api/student";

const props = defineProps({
  student: {
    type: Object,
    default: null,
  },
  contract: {
    type: Object,
    default: null,
  },
  selectStudent: {
    type: Boolean,
    default: false,
  },
});

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

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

const $q = useQuasar();
const permissions = permissionStore();
const canViewFinancial = computed(() =>
  permissions.getAccess("franchisee_financial", "view"),
);
const activeTab = ref("dados");
const medias = ref([]);
const loadingMedias = ref(false);
const selectedStudent = ref(props.student);
const students = ref([]);
const filteredStudents = ref([]);
const currentStudent = computed(() => selectedStudent.value ?? props.student);
const dialogCardStyle = computed(() => ({
  width: "100%",
  maxWidth: props.selectStudent ? "1400px" : "1350px",
  height: props.selectStudent ? "95vh" : "auto",
  maxHeight: props.selectStudent ? "95vh" : "none",
}));

function filterStudents(value, update) {
  update(() => {
    const search = value.trim().toLocaleLowerCase("pt-BR");
    filteredStudents.value = search
      ? students.value.filter((student) =>
          student.name.toLocaleLowerCase("pt-BR").includes(search),
        )
      : students.value;
  });
}

const trimTime = (t) => (t ? t.slice(0, 5) : null);

function calculateEndTime(startTime, durationMinutes = 120) {
  if (!/^\d{2}:\d{2}$/.test(startTime ?? "")) return null;

  const [hours, minutes] = startTime.split(":").map(Number);
  if (hours > 23 || minutes > 59) return null;

  const endMinutes = (hours * 60 + minutes + durationMinutes) % (24 * 60);
  return `${String(Math.floor(endMinutes / 60)).padStart(2, "0")}:${String(
    endMinutes % 60,
  ).padStart(2, "0")}`;
}

const defaultContractDates = (() => {
  if (props.contract) return null;

  const start = new Date();
  return {
    signature_date: format(start, "dd/MM/yyyy"),
    end_date: format(addYears(start, 1), "dd/MM/yyyy"),
  };
})();

const { form } = useFormUpdateTracker({
  protocol: props.contract?.protocol ?? null,
  signature_date:
    props.contract?.signature_date ?? defaultContractDates?.signature_date ?? null,
  end_date: props.contract?.end_date ?? defaultContractDates?.end_date ?? null,
  package_id: props.contract?.class_package_unit_id ?? null,
  class_quantity: props.contract?.class_quantity ?? null,
  weekday: props.contract?.weekday ?? null,
  start_time: trimTime(props.contract?.start_time),
  end_time: trimTime(props.contract?.end_time),
  second_weekday: props.contract?.second_weekday ?? null,
  second_start_time: trimTime(props.contract?.second_start_time),
  second_end_time: trimTime(props.contract?.second_end_time),
  due_day: props.contract?.recurring_day ?? null,
  enrollment_fee: props.contract?.tax_register ?? null,
  total_classes: props.contract?.class_quantity ?? null,
  installments: props.contract?.installments ?? null,
  enrollment_due_date: props.contract?.enrollment_due_date ?? null,
  package_value: props.contract?.package_value ?? null,
  package_installments: props.contract?.package_installments ?? null,
  package_due_date: props.contract?.package_due_date ?? null,
  early_payment_discount: props.contract?.early_payment_discount ?? null,
  interest_rate: props.contract?.interest_rate ?? null,
  payment_method: props.contract?.payment_method ?? null,
  late_fee: props.contract?.fine_cancelled ?? null,
});

const dateOverrideConfirmed = ref(false);
const dateConfirmationOpen = ref(false);
const restoringDefaultDates = ref(false);
const completeDatePattern = /^\d{2}\/\d{2}\/\d{4}$/;

function restoreDefaultContractDates() {
  restoringDefaultDates.value = true;
  form.signature_date = defaultContractDates.signature_date;
  form.end_date = defaultContractDates.end_date;
  nextTick(() => {
    restoringDefaultDates.value = false;
    dateConfirmationOpen.value = false;
  });
}

watch(
  [() => form.signature_date, () => form.end_date],
  ([signatureDate, endDate]) => {
    if (
      props.contract ||
      dateOverrideConfirmed.value ||
      dateConfirmationOpen.value ||
      restoringDefaultDates.value
    ) {
      return;
    }

    const datesAreStillDefault =
      signatureDate === defaultContractDates.signature_date &&
      endDate === defaultContractDates.end_date;
    if (datesAreStillDefault) return;

    // Evita abrir a confirmação enquanto o usuário ainda está digitando a data.
    const datesAreComplete =
      (!signatureDate || completeDatePattern.test(signatureDate)) &&
      (!endDate || completeDatePattern.test(endDate));
    if (!datesAreComplete) return;

    dateConfirmationOpen.value = true;
    $q.dialog({
      title: "Alterar duração do contrato?",
      message:
        "As datas foram preenchidas automaticamente para a duração de um ano. Tem certeza de que deseja alterá-las?",
      ok: { color: "primary", label: "Sim" },
      cancel: { color: "primary", outline: true, label: "Não" },
      persistent: true,
    })
      .onOk(() => {
        dateOverrideConfirmed.value = true;
        dateConfirmationOpen.value = false;
      })
      .onCancel(restoreDefaultContractDates);
  },
);

const enrollmentInstallmentOptions = Array.from({ length: 12 }, (_, i) => ({
  value: i + 1,
  label: `${i + 1}x`,
}));

const packageInstallmentOptions = Array.from({ length: 13 }, (_, i) => ({
  value: i + 1,
  label: `${i + 1}x`,
}));

const enrollmentInstallmentValue = computed(() => {
  if (!form.enrollment_fee || !form.installments) return null;
  return parseFloat((form.enrollment_fee / form.installments).toFixed(2));
});

const packageInstallmentValue = computed(() => {
  if (!form.package_value || !form.package_installments) return null;
  return parseFloat((form.package_value / form.package_installments).toFixed(2));
});

// Two-way binding: due_day <-> package_due_date
const _syncingFromDay = ref(false);
const _syncingFromDate = ref(false);

function buildDateFromDay(day) {
  const d = parseInt(day);
  if (!d || d < 1 || d > 31) return null;
  const now = new Date();
  const nextMonthIndex = (now.getMonth() + 1) % 12;
  const nextYear = now.getMonth() === 11 ? now.getFullYear() + 1 : now.getFullYear();
  const lastDayOfNextMonth = new Date(nextYear, nextMonthIndex + 1, 0).getDate();
  const safeDay = Math.min(d, lastDayOfNextMonth);
  return `${String(safeDay).padStart(2, '0')}/${String(nextMonthIndex + 1).padStart(2, '0')}/${nextYear}`;
}

watch(
  () => form.due_day,
  (day) => {
    if (_syncingFromDate.value) return;
    const dateStr = buildDateFromDay(day);
    if (!dateStr) return;
    _syncingFromDay.value = true;
    form.package_due_date = dateStr;
    nextTick(() => { _syncingFromDay.value = false; });
  },
);

watch(
  () => form.package_due_date,
  (dateStr) => {
    if (_syncingFromDay.value) return;
    if (!dateStr || dateStr.length < 8) return;
    const day = parseInt(dateStr.split('/')[0]);
    if (!isNaN(day) && day !== parseInt(form.due_day)) {
      _syncingFromDate.value = true;
      form.due_day = day;
      nextTick(() => { _syncingFromDate.value = false; });
    }
  },
);

const paymentMethods = [
  { value: "pix", label: "Pix" },
  { value: "credit_card", label: "Cartão de Crédito" },
  { value: "debit_card", label: "Cartão de Débito" },
];

const weekdays = [
  { value: 1, label: "Segunda" },
  { value: 2, label: "Terça" },
  { value: 3, label: "Quarta" },
  { value: 4, label: "Quinta" },
  { value: 5, label: "Sexta" },
  { value: 6, label: "Sábado" },
  { value: 0, label: "Domingo" },
];

const packages = ref([]);

const mediaColumns = [
  { name: "created_at", label: "Data de Anexo", field: "created_at", align: "left" },
  { name: "actions", label: "Ações", field: null, align: "center" },
];

async function fetchMedias() {
  if (!props.contract) return;
  loadingMedias.value = true;
  try {
    medias.value = await getContractMedias(props.contract.id);
  } finally {
    loadingMedias.value = false;
  }
}

watch(activeTab, (tab) => {
  if (tab === "midias") fetchMedias();
});

onMounted(async () => {
  const requests = [getUnitPackagesForSelect()];
  if (props.selectStudent) requests.push(getStudentsForSelect());

  const [unitPackages, unitStudents = []] = await Promise.all(requests);
  packages.value = unitPackages;
  students.value = unitStudents;
  filteredStudents.value = unitStudents;

  // Para novo contrato, pré-preenche desconto/juros/multa com os defaults da unidade
  if (!props.contract && canViewFinancial.value) {
    try {
      const financial = await getFinancialMe();
      if (financial) {
        if (financial.default_discount != null) form.early_payment_discount = financial.default_discount;
        if (financial.default_interest != null) form.interest_rate = financial.default_interest;
        if (financial.default_fine     != null) form.late_fee      = financial.default_fine;
      }
    } catch (e) {
      console.error(e);
    }
  }
});

function openFile(url) {
  window.open(url, "_blank");
}

function handleDeleteMedia(media) {
  $q.dialog({
    title: "Excluir mídia",
    message: "Deseja excluir esta mídia permanentemente?",
    ok: { color: "negative", label: "Excluir" },
    cancel: { color: "primary", outline: true, label: "Cancelar" },
  }).onOk(async () => {
    try {
      await deleteContractMedia(media.id);
      medias.value = medias.value.filter((m) => m.id !== media.id);
    } catch (e) {
      console.error(e);
      $q.notify({ type: "negative", message: "Erro ao excluir mídia." });
    }
  });
}

watch(
  () => form.package_id,
  (id) => {
    const pkg = packages.value.find((p) => p.id === id);
    if (!pkg) return;
    form.class_quantity = pkg.quantity_classes;
    form.total_classes = pkg.quantity_classes;
    form.enrollment_fee = pkg.contract_register_value;
    form.package_value = pkg.contract_value;
    form.weekday = pkg.weekday ?? null;
    form.start_time = trimTime(pkg.start_time);
    form.end_time = calculateEndTime(
      form.start_time,
      pkg.class_duration_minutes ?? 120,
    );
    form.second_weekday = pkg.second_weekday ?? null;
    form.second_start_time = trimTime(pkg.second_start_time);
    form.second_end_time = calculateEndTime(
      form.second_start_time,
      pkg.class_duration_minutes ?? 120,
    );
  },
);

watch(
  () => form.start_time,
  (startTime) => {
    const pkg = packages.value.find((p) => p.id === form.package_id);
    const calculated = calculateEndTime(
      startTime,
      pkg?.class_duration_minutes ?? 120,
    );
    if (calculated) form.end_time = calculated;
  },
);

watch(
  () => form.second_start_time,
  (startTime) => {
    const pkg = packages.value.find((p) => p.id === form.package_id);
    const calculated = calculateEndTime(
      startTime,
      pkg?.class_duration_minutes ?? 120,
    );
    if (calculated) form.second_end_time = calculated;
  },
);

const formattedBirthDate = computed(() =>
  currentStudent.value?.birth_date
    ? formatDateYMDtoDMY(currentStudent.value.birth_date)
    : "",
);

const { loading: saving, execute } = useSubmitHandler({
  onSuccess: () => onDialogOK(true),
});

function buildPayload() {
  return {
    student_id: currentStudent.value?.id ?? null,
    protocol: form.protocol,
    signature_date: form.signature_date
      ? formatDateDMYtoYMD(form.signature_date)
      : null,
    end_date: form.end_date ? formatDateDMYtoYMD(form.end_date) : null,
    class_package_unit_id: form.package_id,
    class_quantity: form.class_quantity,
    weekday: form.weekday,
    start_time: form.start_time,
    end_time: form.end_time,
    second_weekday: form.second_weekday,
    second_start_time: form.second_start_time,
    second_end_time: form.second_end_time,
    due_day: form.due_day ? parseInt(form.due_day) : null,
    tax_register: form.enrollment_fee,
    installments: form.installments,
    enrollment_due_date: form.enrollment_due_date
      ? formatDateDMYtoYMD(form.enrollment_due_date)
      : null,
    package_value: form.package_value,
    package_installments: form.package_installments,
    package_due_date: form.package_due_date
      ? formatDateDMYtoYMD(form.package_due_date)
      : null,
    early_payment_discount: form.early_payment_discount,
    interest_rate: form.interest_rate,
    payment_method: form.payment_method,
    fine_cancelled: form.late_fee,
  };
}

async function handleSave() {
  if (!currentStudent.value) {
    $q.notify({
      type: "warning",
      message: "Selecione um aluno para criar o contrato.",
    });
    return;
  }

  const payload = buildPayload();
  await execute(() =>
    props.contract
      ? updateStudentContract(props.contract.id, payload)
      : createStudentContract(payload),
  );
}
</script>
