<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">{{ accounts.length }} contas cadastradas</div>
          </div>
          <q-space />
          <q-btn
            v-if="canAdd"
            color="primary"
            label="Nova Conta"
            no-caps
            unelevated
            @click="handleAddItem"
          />
        </div>

        <DefaultInput
          v-model="search"
          dense
          clearable
          debounce="250"
          label="Buscar por código ou nome da conta"
          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>

        <q-list>
          <FinancialPlanAccountTreeNode
            v-for="node in filteredTree"
            :key="node.id"
            :node="node"
            :force-expanded="!!normalizedSearch"
          />
        </q-list>

        <div v-if="!loading && filteredTree.length === 0" class="text-center q-pa-lg">
          Nenhuma conta encontrada.
        </div>

        <q-inner-loading :showing="loading" color="primary" />
      </q-card>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import { useQuasar } from "quasar";
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import AddFinancialPlanAccountDialog from "src/components/financial/AddFinancialPlanAccountDialog.vue";
import FinancialPlanAccountTreeNode from "src/components/financial/FinancialPlanAccountTreeNode.vue";
import { getFinancialPlanAccounts } from "src/api/financial_plan_account";
import { permissionStore } from "src/stores/permission";

const $q = useQuasar();
const canAdd = permissionStore().getAccess("franchisor_financial", "add");

const accounts = ref([]);
const loading = ref(false);
const search = ref("");

const accountTree = computed(() => {
  const nodes = new Map(
    accounts.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 sortNodes = (items) => {
    items.sort((a, b) =>
      String(a.code).localeCompare(String(b.code), "pt-BR", { numeric: true }),
    );
    items.forEach((item) => sortNodes(item.children));
    return items;
  };

  return sortNodes(roots);
});

const normalizedSearch = computed(() => search.value?.trim().toLocaleLowerCase("pt-BR") ?? "");

const filteredTree = computed(() => {
  if (!normalizedSearch.value) return accountTree.value;

  const filterNodes = (nodes) =>
    nodes.reduce((result, node) => {
      const children = filterNodes(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 filterNodes(accountTree.value);
});

const fetchAccounts = async () => {
  loading.value = true;
  try {
    accounts.value = await getFinancialPlanAccounts();
  } catch {
    $q.notify({ type: "negative", message: "Erro ao carregar o plano de contas." });
  } finally {
    loading.value = false;
  }
};

const handleAddItem = () => {
  $q.dialog({ component: AddFinancialPlanAccountDialog }).onOk(() => {
    $q.notify({ type: "positive", message: "Conta cadastrada com sucesso." });
    fetchAccounts();
  });
};

onMounted(fetchAccounts);
</script>

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

@media (max-width: 599px) {
  .account-tree-header {
    grid-template-columns: 25% 1fr 25%;
    padding-left: 8px;
  }
}
</style>
