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

    <div class="q-px-md">
      <q-card flat bordered class="q-pa-md q-mt-md">
        <div class="row items-center q-gutter-md q-mb-md">
          <div><div class="text-h6">Plano de Contas</div><div class="text-body2">{{ rows.length }} contas cadastradas</div></div>
          <q-space />
          <q-btn v-if="canAdd" color="secondary" label="Nova Conta" no-caps unelevated @click="openCreate" />
        </div>
        <DefaultInput v-model="search" dense clearable debounce="250" label="Buscar por código ou nome" class="q-mb-md">
          <template #prepend><q-icon name="mdi-magnify" color="grey-6" /></template>
        </DefaultInput>
        <div class="account-tree-header"><div>Código</div><div>Nome da Conta</div><div>Tipo</div><div>Ações</div></div>
        <q-list>
          <FinancialPlanAccountTreeNode
            v-for="node in filteredTree"
            :key="node.id"
            :node="node"
            :force-expanded="!!normalizedSearch"
            :can-edit="canEdit"
            :can-delete="canDelete"
            @edit="openEdit"
            @delete="onDelete"
          />
        </q-list>
        <div v-if="filteredTree.length === 0" class="text-center q-pa-lg">Nenhuma conta encontrada.</div>
        <q-inner-loading :showing="loadingParents" color="secondary" />
      </q-card>
    </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 DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import FinancialPlanAccountTreeNode from "src/components/financial/FinancialPlanAccountTreeNode.vue";
import { permissionStore } from "src/stores/permission";

const $q = useQuasar();
const permissions = permissionStore();
const canAdd = computed(() =>
  permissions.getAccess("franchisee_financial", "add"),
);
const canEdit = computed(() =>
  permissions.getAccess("franchisee_financial", "edit"),
);
const canDelete = computed(() =>
  permissions.getAccess("franchisee_financial", "delete"),
);

const rows = ref([]);
const search = 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 accountTree = computed(() => {
  const nodes = new Map(rows.value.map((account) => [account.id, { ...account, children: [] }]));
  const roots = [];
  for (const node of nodes.values()) {
    const parent = node.parent_id ? nodes.get(node.parent_id) : null;
    if (parent) parent.children.push(node); else roots.push(node);
  }
  const sort = (items) => {
    items.sort((a, b) => String(a.code).localeCompare(String(b.code), "pt-BR", { numeric: true }));
    items.forEach((item) => sort(item.children));
    return items;
  };
  return sort(roots);
});
const normalizedSearch = computed(() => search.value?.trim().toLocaleLowerCase("pt-BR") ?? "");
const filteredTree = computed(() => {
  if (!normalizedSearch.value) return accountTree.value;
  const filter = (nodes) => nodes.reduce((result, node) => {
    const children = filter(node.children);
    const matches = `${node.code} ${node.description}`.toLocaleLowerCase("pt-BR").includes(normalizedSearch.value);
    if (matches || children.length) result.push({ ...node, children });
    return result;
  }, []);
  return filter(accountTree.value);
});

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>

<style scoped>
.account-tree-header { display: grid; grid-template-columns: 15% 1fr 16% 105px; gap: 16px; padding: 12px 56px 12px 16px; border-bottom: 1px solid #c7c7c7; font-weight: 600; }
</style>
