<template>
  <div>
    <DefaultHeaderPage title="Contas a Receber" :show-filter-icon="false" />

    <div class="row q-pa-md q-gutter-md">
      <FinancialCard
        title="Recebido"
        icon="mdi-check-circle-outline"
        :financial-value="totals.received"
        :integer="totals.receivedCount"
        integer-label="recebimentos"
      />
      <FinancialCard
        title="A Receber"
        icon="mdi-cash-plus"
        :financial-value="totals.pending"
        :integer="totals.pendingCount"
        integer-label="pendentes"
      />
      <FinancialCard
        title="Vencidas"
        icon="mdi-alert-circle-outline"
        :financial-value="totals.overdue"
        :integer="totals.overdueCount"
        integer-label="em atraso"
      />
    </div>

    <div class="q-px-md">
      <DefaultTable
        v-model:rows="rows"
        no-api-call
        :add-item="canAdd"
        title="Contas a Receber"
        description="contas"
        :female="true"
        :columns="columns"
        @on-add-item="openCreate"
      >
        <template #body-cell-value="{ row }">
          <q-td class="text-left">{{ formatCurrency(row.value) }}</q-td>
        </template>

        <template #body-cell-status="{ row }">
          <q-td class="text-left">
            <q-btn
              :color="row.status === 'paid' ? 'positive' : 'secondary'"
              :label="row.status === 'paid' ? 'Pago' : 'Não pago'"
              dense
              no-caps
              unelevated
              :disable="!canEdit"
              :loading="reopeningId === row.id"
              @click.stop="changeStatus(row)"
            >
              <q-tooltip v-if="canEdit">Clique para alterar o status</q-tooltip>
            </q-btn>
          </q-td>
        </template>

        <template #body-cell-actions="{ row }">
          <q-td auto-width>
            <div class="row no-wrap justify-end items-center" style="gap: 6px">
              <q-btn
                v-if="row.invoice_url"
                color="teal-7"
                label="Ver boleto"
                icon="mdi-barcode"
                dense
                no-caps
                outline
                class="q-px-sm"
                @click="openInvoice(row)"
              />
              <q-btn
                v-else-if="
                  canEdit &&
                  row.source !== 'manual' &&
                  row.status !== 'paid' &&
                  row.status !== 'cancelled'
                "
                color="deep-purple-5"
                label="Gerar cobrança"
                icon="mdi-cash-fast"
                dense
                no-caps
                outline
                class="q-px-sm"
                :loading="chargingId === row.id"
                @click="onCharge(row)"
              />
            </div>
          </q-td>
        </template>
      </DefaultTable>
    </div>

    <!-- Diálogo de novo recebível avulso -->
    <q-dialog v-model="createDialog">
      <q-card style="min-width: 380px; max-width: 480px">
        <DefaultDialogHeader
          title="Nova conta a receber"
          @close="createDialog = false"
        />

        <q-form ref="createFormRef">
          <q-card-section class="q-gutter-sm">
            <DefaultInput
              v-model="createForm.history"
              label="Descrição"
              outlined
              :rules="[(v) => !!v || 'Informe a descrição']"
            />
            <div class="row q-col-gutter-sm">
              <DefaultCurrencyInput
                v-model="createForm.value"
                label="Valor"
                class="col-6"
                outlined
                :rules="[() => Number(createForm.value) > 0 || 'Informe o valor']"
              />
              <DefaultInputDatePicker
                v-model="createForm.due_date"
                v-model:untreated-date="createForm.due_date_iso"
                label="Vencimento"
                class="col-6"
                :rules="[(v) => !!v || 'Informe o vencimento']"
              />
            </div>
            <DefaultSelect
              v-if="canViewStudents"
              v-model="createForm.student_id"
              label="Aluno (opcional)"
              :options="studentOptions"
              outlined
              clearable
              emit-value
              map-options
              :loading="loadingAux"
            />
            <DefaultSelect
              v-model="createForm.financial_plan_account_id"
              label="Plano de contas (opcional)"
              :options="planAccountOptions"
              outlined
              clearable
              emit-value
              map-options
              :loading="loadingAux"
            />
            <DefaultInput
              v-model="createForm.obs"
              label="Observação (opcional)"
              type="textarea"
              autogrow
              outlined
            />
          </q-card-section>

          <q-card-actions align="right" class="q-pa-md">
            <q-btn flat label="Cancelar" color="grey-7" @click="createDialog = false" />
            <q-btn
              color="primary"
              label="Salvar"
              :loading="creating"
              @click="onCreate"
            />
          </q-card-actions>
        </q-form>
      </q-card>
    </q-dialog>

    <!-- Diálogo de baixa manual -->
    <q-dialog v-model="settleDialog">
      <q-card style="min-width: 360px; max-width: 460px">
        <DefaultDialogHeader title="Dar baixa" @close="settleDialog = false" />

        <q-card-section class="q-gutter-sm">
          <div class="text-body2 text-grey-8">
            {{ selected?.student_name }} — {{ selected?.history }}
            ({{ selected?.order }})
          </div>

          <DefaultInputDatePicker
            v-model="settleForm.payment_date"
            v-model:untreated-date="settleForm.payment_date_iso"
            label="Data do pagamento"
          />

          <div class="row q-col-gutter-sm">
            <DefaultCurrencyInput
              v-model="settleForm.discount"
              label="Desconto"
              class="col-6"
              outlined
            />
            <DefaultCurrencyInput
              v-model="settleForm.fine"
              label="Multa/Juros"
              class="col-6"
              outlined
            />
          </div>

          <div class="text-caption text-grey-7">
            Valor da parcela: {{ formatCurrency(selected?.value) }} ·
            <span class="text-weight-medium">
              Recebido: {{ formatCurrency(settleNetValue) }}
            </span>
          </div>
        </q-card-section>

        <q-card-actions align="right" class="q-pa-md">
          <q-btn flat label="Cancelar" color="grey-7" @click="settleDialog = false" />
          <q-btn
            color="primary-2"
            label="Confirmar baixa"
            :loading="settling"
            @click="onSettle"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import {
  getReceivablesMe,
  settleReceivableMe,
  reopenReceivableMe,
  chargeReceivableMe,
  createManualReceivableMe,
  settleManualReceivableMe,
  reopenManualReceivableMe,
} from "src/api/unit_receivable";
import { getStudentsForSelect } from "src/api/student";
import { getPlanAccountsForSelect } from "src/api/financial_plan_account";
import { permissionStore } from "src/stores/permission";

import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import DefaultTable from "src/components/defaults/DefaultTable.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import FinancialCard from "src/components/financial/FinancialCard.vue";

const permissions = permissionStore();
const canAdd = computed(() =>
  permissions.getAccess("franchisee_financial", "add"),
);
const canEdit = computed(() =>
  permissions.getAccess("franchisee_financial", "edit"),
);

const rows = ref([]);
const settleDialog = ref(false);
const selected = ref(null);
const settling = ref(false);
const reopeningId = ref(null);
const chargingId = ref(null);

const settleForm = ref({ payment_date: null, payment_date_iso: null, discount: 0, fine: 0 });

// Novo recebível avulso
const createDialog = ref(false);
const creating = ref(false);
const createFormRef = ref(null);
const loadingAux = ref(false);
const studentOptions = ref([]);
const planAccountOptions = ref([]);
const defaultCreateForm = () => {
  const today = new Date();
  return {
    history: "",
    value: 0,
    due_date: today.toLocaleDateString("pt-BR"),
    due_date_iso: today.toISOString().slice(0, 10),
    student_id: null,
    financial_plan_account_id: null,
    obs: "",
  };
};
const createForm = ref(defaultCreateForm());

const columns = [
  { name: "student_name", label: "Aluno", field: "student_name", align: "left" },
  { name: "history", label: "Descrição", field: "history", align: "left" },
  { name: "order", label: "Parcela", field: "order", align: "left" },
  { name: "value", label: "Valor", field: "value", align: "left" },
  { name: "due_date", label: "Vencimento", field: "due_date", align: "left" },
  { name: "status", label: "Status", field: "status", align: "left" },
  { name: "actions", label: "Ações", field: "actions", align: "right" },
];

function formatCurrency(value) {
  return new Intl.NumberFormat("pt-BR", {
    style: "currency",
    currency: "BRL",
  }).format(Number(value ?? 0));
}

const settleNetValue = computed(() => {
  const base = Number(selected.value?.value ?? 0);
  return base - Number(settleForm.value.discount ?? 0) + Number(settleForm.value.fine ?? 0);
});

const totals = computed(() => {
  const acc = {
    received: 0,
    receivedCount: 0,
    pending: 0,
    pendingCount: 0,
    overdue: 0,
    overdueCount: 0,
  };
  for (const r of rows.value) {
    if (r.status === "paid") {
      acc.received += Number(r.paid_value ?? 0);
      acc.receivedCount++;
    } else if (r.status === "overdue") {
      acc.overdue += Number(r.value ?? 0);
      acc.overdueCount++;
    } else if (r.status === "pending") {
      acc.pending += Number(r.value ?? 0);
      acc.pendingCount++;
    }
  }
  return acc;
});

async function loadData() {
  try {
    const data = await getReceivablesMe();
    // Chave composta: parcelas e avulsos podem ter o mesmo id numérico.
    // realId é o id verdadeiro usado nas ações (baixa/reabrir/cobrança).
    rows.value = (data ?? []).map((r) => ({
      ...r,
      realId: r.id,
      id: `${r.source}-${r.id}`,
    }));
  } catch (e) {
    console.error("Erro ao buscar contas a receber:", e);
  }
}

async function loadAux() {
  if (studentOptions.value.length || planAccountOptions.value.length) return;
  loadingAux.value = true;
  try {
    const [students, planAccounts] = await Promise.all([
      getStudentsForSelect(),
      getPlanAccountsForSelect(),
    ]);
    studentOptions.value = (students ?? []).map((s) => ({
      label: s.name,
      value: s.id,
    }));
    planAccountOptions.value = (planAccounts ?? []).map((a) => ({
      label: `${a.code} — ${a.description}`,
      value: a.id,
    }));
  } catch (e) {
    console.error("Erro ao carregar dados auxiliares:", e);
  } finally {
    loadingAux.value = false;
  }
}

function openCreate() {
  createForm.value = defaultCreateForm();
  createDialog.value = true;
  loadAux();
}

async function onCreate() {
  const valid = await createFormRef.value?.validate();
  if (!valid) return;
  creating.value = true;
  try {
    await createManualReceivableMe({
      history: createForm.value.history,
      value: createForm.value.value,
      due_date: createForm.value.due_date_iso,
      student_id: createForm.value.student_id || null,
      financial_plan_account_id: createForm.value.financial_plan_account_id || null,
      obs: createForm.value.obs || null,
    });
    createDialog.value = false;
    await loadData();
  } catch (e) {
    console.error(e);
  } finally {
    creating.value = false;
  }
}

function openSettle(row) {
  const today = new Date();
  selected.value = row;
  settleForm.value = {
    payment_date: today.toLocaleDateString("pt-BR"),
    payment_date_iso: today.toISOString().slice(0, 10),
    discount: Number(row.discount ?? 0),
    fine: Number(row.fine ?? 0),
  };
  settleDialog.value = true;
}

function changeStatus(row) {
  if (row.status === "paid") onReopen(row);
  else openSettle(row);
}

async function onSettle() {
  if (!selected.value) return;
  settling.value = true;
  const payload = {
    payment_date: settleForm.value.payment_date_iso,
    discount: settleForm.value.discount,
    fine: settleForm.value.fine,
  };
  try {
    if (selected.value.source === "manual") {
      await settleManualReceivableMe(selected.value.realId, payload);
    } else {
      await settleReceivableMe(selected.value.realId, payload);
    }
    settleDialog.value = false;
    await loadData();
  } catch (e) {
    console.error(e);
  } finally {
    settling.value = false;
  }
}

async function onReopen(row) {
  reopeningId.value = row.id;
  try {
    if (row.source === "manual") {
      await reopenManualReceivableMe(row.realId);
    } else {
      await reopenReceivableMe(row.realId);
    }
    await loadData();
  } catch (e) {
    console.error(e);
  } finally {
    reopeningId.value = null;
  }
}

async function onCharge(row) {
  chargingId.value = row.id;
  try {
    await chargeReceivableMe(row.realId);
    await loadData();
  } catch (e) {
    console.error(e);
  } finally {
    chargingId.value = null;
  }
}

function openInvoice(row) {
  if (row.invoice_url) window.open(row.invoice_url, "_blank");
}

onMounted(loadData);
</script>
