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

    <div class="row justify-end items-center q-px-md q-mb-sm">
      <q-btn
        color="primary"
        label="Nova conta"
        icon="mdi-plus"
        unelevated
        no-caps
        @click="openCreate"
      />
    </div>

    <div class="q-px-md">
      <DefaultTable
        v-model:rows="rows"
        no-api-call
        :add-item="false"
        title="Plano de Contas"
        descricao="contas"
        :feminino="true"
        :columns="columns"
        :delete-function="onDelete"
      >
        <template #body-cell-parent="{ row }">
          <q-td class="text-left">
            {{ row.parent ? `${row.parent.code} — ${row.parent.description}` : "—" }}
          </q-td>
        </template>

        <template #body-cell-chart_type="{ row }">
          <q-td class="text-left">
            <q-chip
              :color="row.chart_type === 'receita' ? 'positive' : 'blue-grey-5'"
              text-color="white"
              dense
              square
              :label="chartTypeLabel(row.chart_type)"
            />
          </q-td>
        </template>

        <template #body-cell-actions="{ row }">
          <q-td auto-width>
            <q-btn
              v-if="row.unit_id"
              color="primary-2"
              label="Editar"
              dense
              no-caps
              outline
              class="q-px-sm"
              @click="openEdit(row)"
            />
            <q-chip
              v-else
              dense
              square
              color="blue-grey-1"
              text-color="blue-grey-7"
              icon="mdi-lock-outline"
              label="Matriz"
            />
          </q-td>
        </template>
      </DefaultTable>
    </div>

    <q-dialog v-model="dialog">
      <q-card style="min-width: 360px; max-width: 460px">
        <DefaultDialogHeader
          :title="editing ? 'Editar conta' : 'Nova conta'"
          @close="dialog = false"
        />

        <q-form ref="formRef">
          <q-card-section class="q-gutter-sm">
            <q-option-group
              v-model="accountKind"
              :options="kindOptions"
              color="primary"
              inline
              dense
            />
            <div class="row q-col-gutter-sm">
              <DefaultInput
                v-model="form.code"
                label="Código (ex.: 1.1.01)"
                :class="accountKind === 'parent' ? 'col-5' : 'col-12'"
                outlined
                :rules="[(v) => !!v || 'Informe o código']"
              />
              <DefaultSelect
                v-if="accountKind === 'parent'"
                v-model="form.chart_type"
                label="Tipo"
                :options="chartTypeOptions"
                class="col-7"
                outlined
                emit-value
                map-options
                :rules="[(v) => !!v || 'Selecione o tipo']"
              />
            </div>
            <DefaultSelect
              v-if="accountKind === 'child'"
              v-model="form.parent_id"
              label="Conta Pai"
              :options="parentOptions"
              option-value="id"
              option-label="label"
              outlined
              emit-value
              map-options
              :loading="loadingParents"
              :rules="[(v) => !!v || 'Selecione a conta pai']"
            />
            <DefaultInput
              v-model="form.description"
              label="Descrição"
              outlined
              :rules="[(v) => !!v || 'Informe a descrição']"
            />
            <div
              v-if="accountKind === 'child' && selectedParent"
              class="text-caption text-grey-7"
            >
              Tipo herdado do pai:
              <b>{{ chartTypeLabel(selectedParent.chart_type) }}</b>
            </div>
          </q-card-section>

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

<script setup>
import { onMounted, ref, computed } from "vue";
import { useQuasar } from "quasar";
import {
  getPlanAccountsMe,
  createPlanAccountMe,
  updatePlanAccountMe,
  deletePlanAccountMe,
} from "src/api/financial_plan_account";

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

const $q = useQuasar();

const rows = ref([]);
const dialog = ref(false);
const saving = ref(false);
const editing = ref(false);
const editingId = ref(null);
const formRef = ref(null);

const defaultForm = () => ({
  code: "",
  description: "",
  chart_type: "despesa",
  parent_id: null,
});
const form = ref(defaultForm());

const accountKind = ref("parent");
const kindOptions = [
  { label: "Conta Pai", value: "parent" },
  { label: "Conta Filho", value: "child" },
];

const chartTypeOptions = [
  { label: "Receita", value: "receita" },
  { label: "Despesa", value: "despesa" },
];

function chartTypeLabel(type) {
  return chartTypeOptions.find((o) => o.value === type)?.label ?? type;
}

const loadingParents = ref(false);
const parentOptions = computed(() =>
  rows.value
    .filter((a) => a.id !== editingId.value)
    .map((a) => ({
      id: a.id,
      label: `${a.code} — ${a.description}`,
      chart_type: a.chart_type,
    })),
);
const selectedParent = computed(() =>
  parentOptions.value.find((o) => o.id === form.value.parent_id),
);

const columns = [
  { name: "code", label: "Código", field: "code", align: "left", sortable: true },
  { name: "description", label: "Descrição", field: "description", align: "left" },
  { name: "parent", label: "Conta Pai", field: "parent", align: "left" },
  { name: "chart_type", label: "Tipo", field: "chart_type", align: "left" },
  { name: "actions", label: "Ações", field: "actions", align: "right" },
];

async function loadData() {
  loadingParents.value = true;
  try {
    rows.value = await getPlanAccountsMe();
  } catch (e) {
    console.error("Erro ao carregar plano de contas:", e);
  } finally {
    loadingParents.value = false;
  }
}

function openCreate() {
  editing.value = false;
  editingId.value = null;
  accountKind.value = "parent";
  form.value = defaultForm();
  dialog.value = true;
}

function openEdit(row) {
  editing.value = true;
  editingId.value = row.id;
  accountKind.value = row.parent_id ? "child" : "parent";
  form.value = {
    code: row.code,
    description: row.description,
    chart_type: row.chart_type,
    parent_id: row.parent_id ?? null,
  };
  dialog.value = true;
}

async function onSave() {
  const valid = await formRef.value?.validate();
  if (!valid) return;

  const payload = {
    code: form.value.code,
    description: form.value.description,
  };
  if (accountKind.value === "child") {
    payload.parent_id = form.value.parent_id;
  } else {
    payload.chart_type = form.value.chart_type;
    payload.parent_id = null;
  }

  saving.value = true;
  try {
    if (editing.value) {
      await updatePlanAccountMe(editingId.value, payload);
    } else {
      await createPlanAccountMe(payload);
    }
    dialog.value = false;
    await loadData();
  } catch (e) {
    console.error(e);
  } finally {
    saving.value = false;
  }
}

function onDelete(id) {
  const row = rows.value.find((r) => r.id === id);
  if (row && !row.unit_id) {
    $q.notify({
      type: "negative",
      message: "O plano de contas da Matriz não pode ser excluído pela unidade.",
    });
    return;
  }
  $q.dialog({
    title: "Excluir conta",
    message: "Tem certeza que deseja excluir esta conta do plano?",
    cancel: true,
    persistent: true,
  }).onOk(async () => {
    try {
      await deletePlanAccountMe(id);
      await loadData();
    } catch (e) {
      console.error(e);
    }
  });
}

onMounted(loadData);
</script>
