import { pool } from "../db/pool.js";
import { ApiError } from "../utils/ApiError.js";
import { formatDzdAmount } from "../utils/formatters.js";
import { getFiscalCalendarData } from "../utils/fiscalDeadlines.js";
import { exportReportAsPdf } from "../utils/reportExport.js";

const MONTH_LABELS = [
  "Jan",
  "Fev",
  "Mar",
  "Avr",
  "Mai",
  "Juin",
  "Juil",
  "Aout",
  "Sept",
  "Oct",
  "Nov",
  "Dec",
];

const REPORT_MONTH_LABELS = [
  "Janvier",
  "Fevrier",
  "Mars",
  "Avril",
  "Mai",
  "Juin",
  "Juillet",
  "Aout",
  "Septembre",
  "Octobre",
  "Novembre",
  "Decembre",
];

const AUDIT_ENTITY_LABELS = {
  fiscal_profile: "Profil fiscal",
  ifu_gn12_previsionnelle: "GN°12 Prévisionnelle",
  ifu_gn12_bis_definitive: "GN°12 Bis Définitive",
  g50ter_declaration: "G50ter",
  g50_declaration: "G50",
  fiscal_penalty: "Penalite fiscale",
  fiscal_declaration_entry: "Ecriture fiscale",
  fiscal_deadlines: "Calendrier fiscal",
};

const cleanString = (value) => String(value ?? "").trim();
const roundAmount = (value) => Number(Number(value || 0).toFixed(2));

const getCompanyId = (req, source = req.query) => {
  const companyId = Number(source.company_id || source.companyId || req.user?.companyId || 0);

  if (!companyId) {
    throw new ApiError(400, "company_id is required.");
  }

  return companyId;
};

const parseYear = (value, fallback = new Date().getUTCFullYear()) => {
  const year = Number(value || 0);
  return Number.isFinite(year) && year > 0 ? year : fallback;
};

const formatDateOnly = (value) => {
  if (!value) {
    return "—";
  }

  const normalized = String(value).slice(0, 10);
  const [year, month, day] = normalized.split("-");

  if (!year || !month || !day) {
    return normalized;
  }

  return `${day}/${month}/${year}`;
};

const parseIsoDate = (value) => {
  if (!value) {
    return null;
  }

  const normalized = String(value).slice(0, 10);
  const parsed = new Date(`${normalized}T00:00:00Z`);
  return Number.isNaN(parsed.getTime()) ? null : parsed;
};

const getDiffDays = (fromDate, toDate) => {
  const from = fromDate instanceof Date ? fromDate : parseIsoDate(fromDate);
  const to = toDate instanceof Date ? toDate : parseIsoDate(toDate);

  if (!from || !to) {
    return null;
  }

  return Math.ceil((to.getTime() - from.getTime()) / (1000 * 60 * 60 * 24));
};

const getMonthsLate = (daysLate) => {
  if (!Number.isFinite(daysLate) || daysLate <= 0) {
    return 0;
  }

  return Math.max(1, Math.ceil(daysLate / 30));
};

const deriveYearFromFiscalYear = (row) => {
  const labelMatch = cleanString(row?.label).match(/(20\d{2}|19\d{2})/);

  if (labelMatch) {
    return Number(labelMatch[1]);
  }

  const startYear = Number(String(row?.start_date || "").slice(0, 4));
  return Number.isFinite(startYear) && startYear > 0 ? startYear : new Date().getUTCFullYear();
};

const hasFiledStatus = (status) => ["deposee", "validee"].includes(cleanString(status));

const buildTrend = (currentValue, previousValue) => {
  const current = Number(currentValue || 0);
  const previous = Number(previousValue || 0);
  const delta = roundAmount(current - previous);
  const deltaPercent = previous
    ? roundAmount((delta / previous) * 100)
    : current
      ? 100
      : 0;

  return {
    previous_value: previous,
    formatted_previous_value: formatDzdAmount(previous),
    delta,
    formatted_delta: formatDzdAmount(delta),
    delta_percent: deltaPercent,
    direction: delta > 0 ? "up" : delta < 0 ? "down" : "flat",
  };
};

const sumAmounts = (values) =>
  roundAmount(values.reduce((total, value) => total + Number(value || 0), 0));

const buildMonthSeries = (annee) =>
  Array.from({ length: 12 }, (_, index) => ({
    month: index + 1,
    short_label: MONTH_LABELS[index],
    label: `${REPORT_MONTH_LABELS[index]} ${annee}`,
    ifu: 0,
    tva: 0,
    irg_salaires: 0,
    tls: 0,
    total: 0,
  }));

const formatAmountOrDash = (value) =>
  value === null || value === undefined ? "—" : formatDzdAmount(value);

const fetchCompany = async (db, companyId) => {
  const { rows } = await db.query(
    `
      SELECT
        id,
        name,
        nif,
        rc,
        address,
        city,
        logo_url
      FROM companies
      WHERE id = $1
      LIMIT 1
    `,
    [companyId],
  );

  if (!rows[0]) {
    throw new ApiError(404, "Societe introuvable.");
  }

  return rows[0];
};

const fetchFiscalYears = async (db, companyId) => {
  const { rows } = await db.query(
    `
      SELECT
        id,
        label,
        TO_CHAR(start_date, 'YYYY-MM-DD') AS start_date,
        TO_CHAR(end_date, 'YYYY-MM-DD') AS end_date,
        is_current
      FROM fiscal_years
      WHERE company_id = $1
      ORDER BY start_date ASC
    `,
    [companyId],
  );

  return rows.map((row) => ({
    id: Number(row.id),
    label: row.label,
    start_date: row.start_date,
    end_date: row.end_date,
    is_current: row.is_current,
    annee: deriveYearFromFiscalYear(row),
  }));
};

const resolveYearContext = async (db, companyId, requestedYear = null) => {
  const fiscalYears = await fetchFiscalYears(db, companyId);

  if (!fiscalYears.length) {
    return {
      selectedYear: parseYear(requestedYear),
      currentFiscalYear: null,
      availableYears: [parseYear(requestedYear)].sort((left, right) => right - left),
    };
  }

  const currentFiscalYear =
    fiscalYears.find((item) => item.is_current) || fiscalYears[fiscalYears.length - 1];
  const fallbackYear = Number(currentFiscalYear?.annee || new Date().getUTCFullYear());
  const selectedYear = parseYear(requestedYear, fallbackYear);

  return {
    selectedYear,
    currentFiscalYear,
    availableYears: [...new Set(fiscalYears.map((item) => Number(item.annee)))].sort(
      (left, right) => right - left,
    ),
  };
};

const fetchFiscalProfile = async (db, companyId) => {
  const { rows } = await db.query(
    `
      SELECT
        taux_ifu_marchandises,
        taux_ifu_services,
        taux_ifu_auto_entrepreneur,
        minimum_imposition_standard,
        minimum_imposition_auto_entrepreneur
      FROM fiscal_profiles
      WHERE company_id = $1
      LIMIT 1
    `,
    [companyId],
  );

  return rows[0]
    ? {
        taux_ifu_marchandises: Number(rows[0].taux_ifu_marchandises || 5),
        taux_ifu_services: Number(rows[0].taux_ifu_services || 12),
        taux_ifu_auto_entrepreneur: Number(rows[0].taux_ifu_auto_entrepreneur || 0.5),
        minimum_imposition_standard: Number(rows[0].minimum_imposition_standard || 30000),
        minimum_imposition_auto_entrepreneur: Number(
          rows[0].minimum_imposition_auto_entrepreneur || 10000,
        ),
      }
    : {
        taux_ifu_marchandises: 5,
        taux_ifu_services: 12,
        taux_ifu_auto_entrepreneur: 0.5,
        minimum_imposition_standard: 30000,
        minimum_imposition_auto_entrepreneur: 10000,
      };
};

const fetchYearDeclarations = async (db, companyId, annee) => {
  const [gn12Result, gn12BisResult, g50terResult, g50Result] = await Promise.all([
    db.query(
      `
        SELECT
          id,
          company_id,
          fiscal_year_id,
          annee,
          total_ifu_du,
          montant_effectif_a_payer,
          minimum_imposition,
          mode_paiement,
          paiement_integral_montant,
          TO_CHAR(paiement_integral_date, 'YYYY-MM-DD') AS paiement_integral_date,
          tranche1_montant,
          TO_CHAR(tranche1_date, 'YYYY-MM-DD') AS tranche1_date,
          tranche1_quittance,
          tranche2_montant,
          TO_CHAR(tranche2_date, 'YYYY-MM-DD') AS tranche2_date,
          tranche2_quittance,
          tranche3_montant,
          TO_CHAR(tranche3_date, 'YYYY-MM-DD') AS tranche3_date,
          tranche3_quittance,
          ifu_marchandises,
          ifu_services,
          ifu_auto_entrepreneur,
          ifu_marge,
          ca_marchandises_global,
          ca_services_global,
          ca_auto_entrepreneur_global,
          ca_marge_global,
          ca_marge_imposable,
          marge_imposable,
          statut,
          TO_CHAR(date_depot, 'YYYY-MM-DD') AS date_depot
        FROM ifu_declarations_previsionnelles
        WHERE company_id = $1
          AND annee = $2
        ORDER BY id DESC
      `,
      [companyId, annee],
    ),
    db.query(
      `
        SELECT
          id,
          company_id,
          fiscal_year_id,
          annee,
          total_ifu_complementaire,
          total_ifu_exercice,
          ifu_previsionnel_acquitte,
          montant_acquitte,
          minimum_imposition,
          ca_marchandises_reel_global,
          ca_marchandises_reel_imposable,
          ifu_complementaire_marchandises,
          ca_services_reel_global,
          ca_services_reel_imposable,
          ifu_complementaire_services,
          ca_ae_reel_global,
          ca_ae_reel_imposable,
          ifu_complementaire_ae,
          ca_marge_reel_global,
          ca_marge_reel_imposable,
          marge_realisee,
          ifu_complementaire_marge,
          revenu_net_declare,
          is_nouveau_contribuable,
          quittance_numero,
          TO_CHAR(quittance_date, 'YYYY-MM-DD') AS quittance_date,
          statut,
          TO_CHAR(date_depot, 'YYYY-MM-DD') AS date_depot
        FROM ifu_declarations_definitives
        WHERE company_id = $1
          AND annee = $2
        ORDER BY id DESC
      `,
      [companyId, annee],
    ),
    db.query(
      `
        SELECT
          id,
          company_id,
          fiscal_year_id,
          trimestre,
          annee,
          salaires_imposables_t,
          montant_irg,
          statut,
          TO_CHAR(date_versement, 'YYYY-MM-DD') AS date_versement,
          TO_CHAR(quittance_date, 'YYYY-MM-DD') AS quittance_date,
          TO_CHAR(delai_limite, 'YYYY-MM-DD') AS delai_limite
        FROM g50ter_declarations
        WHERE company_id = $1
          AND annee = $2
        ORDER BY trimestre ASC
      `,
      [companyId, annee],
    ),
    db.query(
      `
        SELECT
          id,
          company_id,
          annee,
          periodicite,
          mois,
          trimestre,
          total_a_payer,
          total_cadre1,
          total_cadre2,
          total_cadre3,
          total_cadre4,
          total_cadre5,
          total_cadre6,
          total_cadre7,
          total_cadre8,
          tva_a_payer,
          tva_precompte_reporter,
          statut,
          TO_CHAR(quittance_date, 'YYYY-MM-DD') AS quittance_date,
          TO_CHAR(submitted_at AT TIME ZONE 'UTC', 'YYYY-MM-DD') AS submitted_at
        FROM g50_declarations
        WHERE company_id = $1
          AND annee = $2
        ORDER BY periodicite ASC, COALESCE(mois, trimestre) ASC
      `,
      [companyId, annee],
    ),
  ]);

  return {
    gn12: gn12Result.rows[0]
      ? {
          ...gn12Result.rows[0],
          id: Number(gn12Result.rows[0].id),
          fiscal_year_id: Number(gn12Result.rows[0].fiscal_year_id || 0),
        }
      : null,
    gn12bis: gn12BisResult.rows[0]
      ? {
          ...gn12BisResult.rows[0],
          id: Number(gn12BisResult.rows[0].id),
          fiscal_year_id: Number(gn12BisResult.rows[0].fiscal_year_id || 0),
        }
      : null,
    g50ter: g50terResult.rows.map((row) => ({
      ...row,
      id: Number(row.id),
      fiscal_year_id: Number(row.fiscal_year_id || 0),
      trimestre: Number(row.trimestre || 0),
    })),
    g50: g50Result.rows.map((row) => ({
      ...row,
      id: Number(row.id),
      mois: row.mois === null ? null : Number(row.mois),
      trimestre: row.trimestre === null ? null : Number(row.trimestre),
    })),
  };
};

const computeYearTotals = (yearData) => {
  const filedGn12 = yearData.gn12 && hasFiledStatus(yearData.gn12.statut) ? yearData.gn12 : null;
  const filedGn12Bis =
    yearData.gn12bis && hasFiledStatus(yearData.gn12bis.statut) ? yearData.gn12bis : null;
  const filedG50ter = yearData.g50ter.filter((item) => hasFiledStatus(item.statut));
  const filedG50 = yearData.g50.filter((item) => hasFiledStatus(item.statut));

  return {
    ifu_total: sumAmounts([
      filedGn12
        ? Number(filedGn12.montant_effectif_a_payer || filedGn12.total_ifu_du || 0)
        : 0,
      filedGn12Bis
        ? Number(filedGn12Bis.montant_acquitte || filedGn12Bis.total_ifu_complementaire || 0)
        : 0,
    ]),
    tva_total: sumAmounts(filedG50.map((item) => Number(item.tva_a_payer || item.total_cadre8 || 0))),
    irg_salaires_total: sumAmounts(filedG50ter.map((item) => Number(item.montant_irg || 0))),
    tls_total: sumAmounts(filedG50.map((item) => Number(item.total_cadre5 || 0))),
    ibs_total: sumAmounts(
      filedG50.map((item) => Number(item.total_cadre1 || 0) + Number(item.total_cadre2 || 0)),
    ),
    autres_total: sumAmounts(
      filedG50.map(
        (item) =>
          Number(item.total_cadre3 || 0) +
          Number(item.total_cadre4 || 0) +
          Number(item.total_cadre6 || 0) +
          Number(item.total_cadre7 || 0),
      ),
    ),
  };
};

const fetchPenaltyTotalsByYear = async (db, companyId, annee) => {
  const { rows } = await db.query(
    `
      WITH penalty_rows AS (
        SELECT fp.penalty_amount
        FROM fiscal_penalties fp
        INNER JOIN ifu_declarations_previsionnelles decl
          ON decl.id = fp.declaration_id
         AND fp.declaration_type = 'GN12'
        WHERE fp.company_id = $1
          AND decl.annee = $2

        UNION ALL

        SELECT fp.penalty_amount
        FROM fiscal_penalties fp
        INNER JOIN ifu_declarations_definitives decl
          ON decl.id = fp.declaration_id
         AND fp.declaration_type = 'GN12BIS'
        WHERE fp.company_id = $1
          AND decl.annee = $2

        UNION ALL

        SELECT fp.penalty_amount
        FROM fiscal_penalties fp
        INNER JOIN g50ter_declarations decl
          ON decl.id = fp.declaration_id
         AND fp.declaration_type = 'G50TER'
        WHERE fp.company_id = $1
          AND decl.annee = $2

        UNION ALL

        SELECT fp.penalty_amount
        FROM fiscal_penalties fp
        INNER JOIN g50_declarations decl
          ON decl.id = fp.declaration_id
         AND fp.declaration_type = 'G50'
        WHERE fp.company_id = $1
          AND decl.annee = $2
      )
      SELECT COALESCE(SUM(penalty_amount), 0)::numeric AS total_penalties
      FROM penalty_rows
    `,
    [companyId, annee],
  );

  return roundAmount(rows[0]?.total_penalties || 0);
};

const fetchDeadlineFilingDates = async (db, companyId, items) => {
  const gn12Ids = items
    .filter((item) => item.declaration_type === "GN12" && item.declaration_id)
    .map((item) => Number(item.declaration_id));
  const gn12BisIds = items
    .filter((item) => item.declaration_type === "GN12BIS" && item.declaration_id)
    .map((item) => Number(item.declaration_id));
  const g50terIds = items
    .filter((item) => item.declaration_type === "G50TER" && item.declaration_id)
    .map((item) => Number(item.declaration_id));
  const g50Ids = items
    .filter((item) => item.declaration_type === "G50" && item.declaration_id)
    .map((item) => Number(item.declaration_id));

  const lookup = new Map();

  if (gn12Ids.length) {
    const { rows } = await db.query(
      `
        SELECT id, TO_CHAR(date_depot, 'YYYY-MM-DD') AS filing_date
        FROM ifu_declarations_previsionnelles
        WHERE company_id = $1
          AND id = ANY($2::bigint[])
      `,
      [companyId, gn12Ids],
    );

    rows.forEach((row) => {
      lookup.set(`GN12:${Number(row.id)}`, row.filing_date || "");
    });
  }

  if (gn12BisIds.length) {
    const { rows } = await db.query(
      `
        SELECT id, TO_CHAR(date_depot, 'YYYY-MM-DD') AS filing_date
        FROM ifu_declarations_definitives
        WHERE company_id = $1
          AND id = ANY($2::bigint[])
      `,
      [companyId, gn12BisIds],
    );

    rows.forEach((row) => {
      lookup.set(`GN12BIS:${Number(row.id)}`, row.filing_date || "");
    });
  }

  if (g50terIds.length) {
    const { rows } = await db.query(
      `
        SELECT
          id,
          COALESCE(
            TO_CHAR(date_versement, 'YYYY-MM-DD'),
            TO_CHAR(quittance_date, 'YYYY-MM-DD')
          ) AS filing_date
        FROM g50ter_declarations
        WHERE company_id = $1
          AND id = ANY($2::bigint[])
      `,
      [companyId, g50terIds],
    );

    rows.forEach((row) => {
      lookup.set(`G50TER:${Number(row.id)}`, row.filing_date || "");
    });
  }

  if (g50Ids.length) {
    const { rows } = await db.query(
      `
        SELECT
          id,
          COALESCE(
            TO_CHAR(quittance_date, 'YYYY-MM-DD'),
            TO_CHAR(submitted_at AT TIME ZONE 'UTC', 'YYYY-MM-DD')
          ) AS filing_date
        FROM g50_declarations
        WHERE company_id = $1
          AND id = ANY($2::bigint[])
      `,
      [companyId, g50Ids],
    );

    rows.forEach((row) => {
      lookup.set(`G50:${Number(row.id)}`, row.filing_date || "");
    });
  }

  return lookup;
};

const buildComplianceData = async (db, companyId, calendarItems) => {
  const filingDates = await fetchDeadlineFilingDates(db, companyId, calendarItems);
  const totals = {
    total_expected: calendarItems.length,
    filed_on_time: 0,
    filed_late: 0,
    pending: 0,
    overdue: 0,
  };

  calendarItems.forEach((item) => {
    if (!item.declaration_id) {
      if (item.statut === "overdue") {
        totals.overdue += 1;
        return;
      }

      totals.pending += 1;
      return;
    }

    const filingDate = filingDates.get(`${item.declaration_type}:${item.declaration_id}`) || "";

    if (!filingDate) {
      if (item.statut === "overdue") {
        totals.overdue += 1;
      } else {
        totals.pending += 1;
      }
      return;
    }

    const deadlineDate = parseIsoDate(item.deadline_date);
    const actualDate = parseIsoDate(filingDate);

    if (deadlineDate && actualDate && actualDate.getTime() <= deadlineDate.getTime()) {
      totals.filed_on_time += 1;
    } else {
      totals.filed_late += 1;
    }
  });

  const rate = totals.total_expected
    ? roundAmount((totals.filed_on_time / totals.total_expected) * 100)
    : 100;

  return {
    ...totals,
    rate,
    gauge_value: Math.max(0, Math.min(100, rate)),
    breakdown: [
      {
        key: "filed_on_time",
        label: "Déposées dans les délais",
        count: totals.filed_on_time,
        tone: "success",
      },
      {
        key: "filed_late",
        label: "Déposées hors délai",
        count: totals.filed_late,
        tone: "warning",
      },
      {
        key: "pending",
        label: "En préparation",
        count: totals.pending,
        tone: "neutral",
      },
      {
        key: "overdue",
        label: "En retard",
        count: totals.overdue,
        tone: "danger",
      },
    ],
  };
};

const buildUpcomingDeadlines = (items) => {
  const today = new Date();
  const limitDate = new Date(today.getTime() + 90 * 24 * 60 * 60 * 1000);

  return items
    .filter((item) => {
      const deadlineDate = parseIsoDate(item.deadline_date);

      if (!deadlineDate) {
        return false;
      }

      return (
        deadlineDate.getTime() >= today.getTime() &&
        deadlineDate.getTime() <= limitDate.getTime()
      );
    })
    .sort((left, right) => String(left.deadline_date).localeCompare(String(right.deadline_date)))
    .map((item) => ({
      id: item.id,
      declaration_type: item.declaration_type,
      declaration_label: item.declaration_label,
      periode_label: item.periode_label,
      deadline_date: item.deadline_date,
      formatted_deadline_date: formatDateOnly(item.deadline_date),
      status: item.statut,
      status_label: item.statut_label,
      estimated_amount: item.amount,
      formatted_estimated_amount: formatAmountOrDash(item.amount),
      remaining_days: item.remaining_days,
      action: item.action,
    }));
};

const estimatePenaltyForDeadline = (item) => {
  const amount = Number(item.amount || 0);
  const daysLate = Math.max(Math.abs(Number(item.remaining_days || 0)), 0);
  const monthsLate = getMonthsLate(daysLate);

  if (item.declaration_type === "G50" && amount <= 0) {
    return {
      amount: 500,
      days_late: daysLate,
      months_late: monthsLate,
      base_amount: 0,
      rule_label: "Pénalité G50 néant",
    };
  }

  if (amount <= 0 || !daysLate) {
    return {
      amount: 0,
      days_late: daysLate,
      months_late: monthsLate,
      base_amount: amount,
      rule_label: "Aucune estimation",
    };
  }

  const penaltyRate = Math.min(0.25, 0.1 + monthsLate * 0.03);

  return {
    amount: roundAmount(amount * penaltyRate),
    days_late: daysLate,
    months_late: monthsLate,
    base_amount: amount,
    rule_label: `10% + 3%/mois (max 25%)`,
  };
};

const buildPotentialPenalties = (calendarItems) => {
  const overdueItems = calendarItems.filter((item) => item.statut === "overdue");
  const items = overdueItems
    .map((item) => {
      const estimation = estimatePenaltyForDeadline(item);

      return {
        id: item.id,
        declaration_type: item.declaration_type,
        declaration_label: item.declaration_label,
        periode_label: item.periode_label,
        deadline_date: item.deadline_date,
        days_late: estimation.days_late,
        months_late: estimation.months_late,
        estimated_penalty: estimation.amount,
        formatted_estimated_penalty: formatDzdAmount(estimation.amount),
        base_amount: estimation.base_amount,
        formatted_base_amount:
          estimation.base_amount > 0 ? formatDzdAmount(estimation.base_amount) : "—",
        rule_label: estimation.rule_label,
      };
    })
    .filter((item) => item.estimated_penalty > 0);

  const totalPenalty = sumAmounts(items.map((item) => item.estimated_penalty));

  return {
    count: overdueItems.length,
    items,
    total_penalty: totalPenalty,
    formatted_total_penalty: formatDzdAmount(totalPenalty),
  };
};

const pushAmountToMonth = (series, monthNumber, key, amount) => {
  if (!monthNumber || monthNumber < 1 || monthNumber > 12) {
    return;
  }

  const bucket = series[monthNumber - 1];
  bucket[key] = roundAmount(Number(bucket[key] || 0) + Number(amount || 0));
};

const buildMonthlyPaymentsChart = (annee, yearData) => {
  const series = buildMonthSeries(annee);

  if (yearData.gn12 && hasFiledStatus(yearData.gn12.statut)) {
    if (cleanString(yearData.gn12.mode_paiement) === "fractionne") {
      [
        {
          date: yearData.gn12.tranche1_date,
          amount: Number(yearData.gn12.tranche1_montant || 0),
        },
        {
          date: yearData.gn12.tranche2_date,
          amount: Number(yearData.gn12.tranche2_montant || 0),
        },
        {
          date: yearData.gn12.tranche3_date,
          amount: Number(yearData.gn12.tranche3_montant || 0),
        },
      ].forEach((event) => {
        const month = Number(String(event.date || "").slice(5, 7));
        pushAmountToMonth(series, month, "ifu", event.amount);
      });
    } else {
      const paymentDate = yearData.gn12.paiement_integral_date || yearData.gn12.date_depot;
      const month = Number(String(paymentDate || "").slice(5, 7));
      const amount = Number(
        yearData.gn12.paiement_integral_montant ||
          yearData.gn12.montant_effectif_a_payer ||
          yearData.gn12.total_ifu_du ||
          0,
      );

      pushAmountToMonth(series, month, "ifu", amount);
    }
  }

  if (yearData.gn12bis && hasFiledStatus(yearData.gn12bis.statut)) {
    const paymentDate = yearData.gn12bis.quittance_date || yearData.gn12bis.date_depot;
    const month = Number(String(paymentDate || "").slice(5, 7));
    const amount = Number(
      yearData.gn12bis.montant_acquitte || yearData.gn12bis.total_ifu_complementaire || 0,
    );

    pushAmountToMonth(series, month, "ifu", amount);
  }

  yearData.g50ter
    .filter((item) => hasFiledStatus(item.statut))
    .forEach((item) => {
      const paymentDate = item.date_versement || item.quittance_date || item.delai_limite;
      const month = Number(String(paymentDate || "").slice(5, 7));
      pushAmountToMonth(series, month, "irg_salaires", Number(item.montant_irg || 0));
    });

  yearData.g50
    .filter((item) => hasFiledStatus(item.statut))
    .forEach((item) => {
      const paymentDate = item.quittance_date || item.submitted_at;
      const month = Number(String(paymentDate || "").slice(5, 7));
      pushAmountToMonth(series, month, "tva", Number(item.tva_a_payer || item.total_cadre8 || 0));
      pushAmountToMonth(series, month, "tls", Number(item.total_cadre5 || 0));
    });

  return series.map((item) => ({
    ...item,
    total: sumAmounts([item.ifu, item.tva, item.irg_salaires, item.tls]),
    formatted_ifu: formatDzdAmount(item.ifu),
    formatted_tva: formatDzdAmount(item.tva),
    formatted_irg_salaires: formatDzdAmount(item.irg_salaires),
    formatted_tls: formatDzdAmount(item.tls),
    formatted_total: formatDzdAmount(
      sumAmounts([item.ifu, item.tva, item.irg_salaires, item.tls]),
    ),
  }));
};

const buildTaxBreakdown = (totals) => {
  const items = [
    { key: "ifu", label: "IFU", value: roundAmount(totals.ifu_total || 0), color: "#2563EB" },
    {
      key: "tva",
      label: "TVA",
      value: roundAmount(totals.tva_total || 0),
      color: "#7C3AED",
    },
    {
      key: "irg_salaires",
      label: "IRG Salaires",
      value: roundAmount(totals.irg_salaires_total || 0),
      color: "#10B981",
    },
    { key: "tls", label: "TLS", value: roundAmount(totals.tls_total || 0), color: "#F59E0B" },
    { key: "ibs", label: "IBS", value: roundAmount(totals.ibs_total || 0), color: "#06B6D4" },
    { key: "autres", label: "Autres", value: roundAmount(totals.autres_total || 0), color: "#64748B" },
  ].map((item) => ({
    ...item,
    formatted_value: formatDzdAmount(item.value),
  }));

  return {
    total: sumAmounts(items.map((item) => item.value)),
    items,
  };
};

const formatAuditAction = (action) =>
  cleanString(action)
    .replace(/^fiscal\./i, "")
    .replace(/^fiscal_/i, "")
    .replace(/[._]+/g, " ")
    .replace(/\b\w/g, (letter) => letter.toUpperCase()) || "Action fiscale";

const buildAuditDeclarationLabel = (row) => {
  const entityType = cleanString(row.entity_type);
  const payload = row.new_data || row.old_data || {};

  if (entityType === "ifu_gn12_previsionnelle") {
    return `GN°12 ${payload.annee || payload.label || ""}`.trim();
  }

  if (entityType === "ifu_gn12_bis_definitive") {
    return `GN°12 Bis ${payload.annee || payload.label || ""}`.trim();
  }

  if (entityType === "g50ter_declaration") {
    return `G50ter T${payload.trimestre || ""} ${payload.annee || ""}`.trim();
  }

  if (entityType === "g50_declaration") {
    if (payload.periodicite === "trimestriel") {
      return `G50 T${payload.trimestre || ""} ${payload.annee || ""}`.trim();
    }

    if (payload.mois) {
      return `G50 ${REPORT_MONTH_LABELS[Math.max(Number(payload.mois) - 1, 0)] || ""} ${
        payload.annee || ""
      }`.trim();
    }
  }

  return AUDIT_ENTITY_LABELS[entityType] || "Declaration fiscale";
};

const extractAuditAmount = (row) => {
  const payload = row.new_data || row.old_data || {};
  const candidates = [
    payload.montant_effectif_a_payer,
    payload.total_ifu_complementaire,
    payload.montant_acquitte,
    payload.montant_irg,
    payload.total_a_payer,
    payload.amount,
    payload.total_penalty,
    payload.penalty_amount,
  ];

  const match = candidates.find((value) => value !== undefined && value !== null && value !== "");

  return match === undefined ? null : roundAmount(match);
};

const fetchRecentFiscalActivity = async (db, companyId, annee) => {
  const { rows } = await db.query(
    `
      SELECT
        audit.id,
        audit.action,
        audit.entity_type,
        audit.entity_id,
        audit.old_data,
        audit.new_data,
        audit.created_at,
        users.full_name,
        users.email
      FROM audit_log audit
      LEFT JOIN users
        ON users.id = audit.user_id
      WHERE audit.company_id = $1
        AND (
          audit.entity_type IN (
            'fiscal_profile',
            'fiscal_deadlines',
            'fiscal_penalty',
            'fiscal_declaration_entry',
            'ifu_gn12_previsionnelle',
            'ifu_gn12_bis_definitive',
            'g50ter_declaration',
            'g50_declaration'
          )
          OR audit.action ILIKE 'fiscal.%'
        )
      ORDER BY audit.created_at DESC
      LIMIT 10
    `,
    [companyId],
  );

  return rows.map((row) => {
    const amount = extractAuditAmount(row);

    return {
      id: Number(row.id),
      action: formatAuditAction(row.action),
      declaration_label: buildAuditDeclarationLabel(row),
      amount,
      formatted_amount: amount === null ? "—" : formatDzdAmount(amount),
      user_name: cleanString(row.full_name) || cleanString(row.email) || "Systeme",
      created_at: row.created_at,
      created_at_label: formatDateOnly(String(row.created_at).slice(0, 10)),
      entity_type: row.entity_type,
      annee,
    };
  });
};

const buildKpis = ({
  currentTotals,
  previousTotals,
  penaltyTotal,
  previousPenaltyTotal,
}) => {
  const ifuTrend = buildTrend(currentTotals.ifu_total, previousTotals.ifu_total);
  const tvaTrend = buildTrend(currentTotals.tva_total, previousTotals.tva_total);
  const irgTrend = buildTrend(
    currentTotals.irg_salaires_total,
    previousTotals.irg_salaires_total,
  );
  const penaltyTrend = buildTrend(penaltyTotal, previousPenaltyTotal);

  return [
    {
      key: "ifu_total",
      label: "IFU Total Paye",
      value: currentTotals.ifu_total,
      formatted_value: formatDzdAmount(currentTotals.ifu_total),
      tone: "accent",
      icon: "FileCheck2",
      trend: ifuTrend,
      trend_label:
        ifuTrend.direction === "flat"
          ? "Stable vs N-1"
          : `${ifuTrend.direction === "up" ? "+" : ""}${ifuTrend.delta_percent}% vs N-1`,
    },
    {
      key: "tva_total",
      label: "TVA Nette Declaree",
      value: currentTotals.tva_total,
      formatted_value: formatDzdAmount(currentTotals.tva_total),
      tone: "violet",
      icon: "ReceiptText",
      trend: tvaTrend,
      trend_label:
        tvaTrend.direction === "flat"
          ? "Stable vs N-1"
          : `${tvaTrend.direction === "up" ? "+" : ""}${tvaTrend.delta_percent}% vs N-1`,
    },
    {
      key: "irg_salaires_total",
      label: "IRG/Salaires Total",
      value: currentTotals.irg_salaires_total,
      formatted_value: formatDzdAmount(currentTotals.irg_salaires_total),
      tone: "success",
      icon: "Users",
      trend: irgTrend,
      trend_label:
        irgTrend.direction === "flat"
          ? "Stable vs N-1"
          : `${irgTrend.direction === "up" ? "+" : ""}${irgTrend.delta_percent}% vs N-1`,
    },
    {
      key: "penalties_total",
      label: "Penalites Encourues",
      value: penaltyTotal,
      formatted_value: formatDzdAmount(penaltyTotal),
      tone: penaltyTotal > 0 ? "danger" : "gold",
      icon: "AlertTriangle",
      trend: penaltyTrend,
      trend_label:
        penaltyTotal > 0
          ? `${penaltyTrend.direction === "flat" ? "Ajuster sans delai" : `${penaltyTrend.direction === "up" ? "+" : ""}${penaltyTrend.delta_percent}% vs N-1`}`
          : "Aucune penalite enregistree",
    },
  ];
};

const buildDashboardData = async (db, { companyId, annee, userId = null, io = null }) => {
  const [company, profile, yearContext] = await Promise.all([
    fetchCompany(db, companyId),
    fetchFiscalProfile(db, companyId),
    resolveYearContext(db, companyId, annee),
  ]);
  const selectedYear = yearContext.selectedYear;
  const [calendarData, currentData, previousData, penaltyTotal, previousPenaltyTotal] =
    await Promise.all([
      getFiscalCalendarData(db, {
        companyId,
        annee: selectedYear,
        userId,
        io,
      }),
      fetchYearDeclarations(db, companyId, selectedYear),
      fetchYearDeclarations(db, companyId, selectedYear - 1),
      fetchPenaltyTotalsByYear(db, companyId, selectedYear),
      fetchPenaltyTotalsByYear(db, companyId, selectedYear - 1),
    ]);

  const currentTotals = computeYearTotals(currentData);
  const previousTotals = computeYearTotals(previousData);
  const compliance = await buildComplianceData(db, companyId, calendarData.items || []);
  const monthlyPayments = buildMonthlyPaymentsChart(selectedYear, currentData);
  const taxBreakdown = buildTaxBreakdown(currentTotals);
  const recentActivity = await fetchRecentFiscalActivity(db, companyId, selectedYear);
  const potentialPenalties = buildPotentialPenalties(calendarData.items || []);
  const overdueCount = Number(
    (calendarData.items || []).filter((item) => item.statut === "overdue").length,
  );

  return {
    company,
    profile,
    annee: selectedYear,
    meta: {
      available_years: [...new Set([selectedYear, ...yearContext.availableYears])].sort(
        (left, right) => right - left,
      ),
    },
    alert: overdueCount
      ? {
          count: overdueCount,
          message: `⚠️ ${overdueCount} declaration(s) en retard — Regularisez immediatement pour eviter les penalites`,
          href: "/fiscal/calendar",
        }
      : null,
    kpis: buildKpis({
      currentTotals,
      previousTotals,
      penaltyTotal,
      previousPenaltyTotal,
    }),
    compliance,
    upcoming_deadlines: buildUpcomingDeadlines(calendarData.items || []),
    potential_penalties: potentialPenalties,
    charts: {
      monthly_payments: monthlyPayments,
      tax_breakdown: taxBreakdown,
    },
    recent_activity: recentActivity,
  };
};

const buildIfuAnnualRows = ({ gn12, gn12bis, profile }) => {
  const rows = [
    {
      key: "marchandises",
      label: `Marchandises (${Number(profile.taux_ifu_marchandises || 5)}%)`,
      rate: Number(profile.taux_ifu_marchandises || 5),
      forecast_ca: Number(gn12?.ca_marchandises_global || 0),
      forecast_ifu: Number(gn12?.ifu_marchandises || 0),
      actual_ca: Number(gn12bis?.ca_marchandises_reel_global || 0),
      actual_ifu: 0,
      complementary_ifu: Number(gn12bis?.ifu_complementaire_marchandises || 0),
    },
    {
      key: "services",
      label: `Services (${Number(profile.taux_ifu_services || 12)}%)`,
      rate: Number(profile.taux_ifu_services || 12),
      forecast_ca: Number(gn12?.ca_services_global || 0),
      forecast_ifu: Number(gn12?.ifu_services || 0),
      actual_ca: Number(gn12bis?.ca_services_reel_global || 0),
      actual_ifu: 0,
      complementary_ifu: Number(gn12bis?.ifu_complementaire_services || 0),
    },
    {
      key: "auto_entrepreneur",
      label: `Auto-entrepreneur (${Number(profile.taux_ifu_auto_entrepreneur || 0.5)}%)`,
      rate: Number(profile.taux_ifu_auto_entrepreneur || 0.5),
      forecast_ca: Number(gn12?.ca_auto_entrepreneur_global || 0),
      forecast_ifu: Number(gn12?.ifu_auto_entrepreneur || 0),
      actual_ca: Number(gn12bis?.ca_ae_reel_global || 0),
      actual_ifu: 0,
      complementary_ifu: Number(gn12bis?.ifu_complementaire_ae || 0),
    },
    {
      key: "marge",
      label: "Marge beneficiaire",
      rate: Number(profile.taux_ifu_marchandises || 5),
      forecast_ca: Number(gn12?.ca_marge_global || 0),
      forecast_ifu: Number(gn12?.ifu_marge || 0),
      actual_ca: Number(gn12bis?.ca_marge_reel_global || 0),
      actual_ifu: 0,
      complementary_ifu: Number(gn12bis?.ifu_complementaire_marge || 0),
    },
  ].map((row) => {
    const computedActualIfu =
      row.forecast_ifu + row.complementary_ifu ||
      roundAmount(
        (Number(
          row.key === "marge"
            ? gn12bis?.marge_realisee || 0
            : row.key === "marchandises"
              ? gn12bis?.ca_marchandises_reel_imposable || 0
              : row.key === "services"
                ? gn12bis?.ca_services_reel_imposable || 0
                : gn12bis?.ca_ae_reel_imposable || 0,
        ) *
          row.rate) /
          100,
      );

    return {
      ...row,
      actual_ifu: roundAmount(computedActualIfu),
      formatted_forecast_ca: formatDzdAmount(row.forecast_ca),
      formatted_forecast_ifu: formatDzdAmount(row.forecast_ifu),
      formatted_actual_ca: formatDzdAmount(row.actual_ca),
      formatted_actual_ifu: formatDzdAmount(roundAmount(computedActualIfu)),
      formatted_complementary_ifu: formatDzdAmount(row.complementary_ifu),
    };
  });

  const totals = {
    forecast_ca: sumAmounts(rows.map((row) => row.forecast_ca)),
    forecast_ifu: sumAmounts(rows.map((row) => row.forecast_ifu)),
    actual_ca: sumAmounts(rows.map((row) => row.actual_ca)),
    actual_ifu: sumAmounts(rows.map((row) => row.actual_ifu)),
    complementary_ifu: sumAmounts(rows.map((row) => row.complementary_ifu)),
  };

  return {
    rows,
    totals: {
      ...totals,
      formatted_forecast_ca: formatDzdAmount(totals.forecast_ca),
      formatted_forecast_ifu: formatDzdAmount(totals.forecast_ifu),
      formatted_actual_ca: formatDzdAmount(totals.actual_ca),
      formatted_actual_ifu: formatDzdAmount(totals.actual_ifu),
      formatted_complementary_ifu: formatDzdAmount(totals.complementary_ifu),
    },
  };
};

const buildFractionnementTracker = (gn12) => {
  if (!gn12) {
    return {
      mode: "none",
      items: [],
      status_label: "Aucune GN°12 enregistree",
    };
  }

  if (cleanString(gn12.mode_paiement) !== "fractionne") {
    return {
      mode: cleanString(gn12.mode_paiement) || "integral",
      status_label:
        gn12.mode_paiement === "minimum"
          ? "Paiement au minimum d'imposition"
          : "Paiement integral",
      items: [
        {
          key: "single",
          label:
            gn12.mode_paiement === "minimum"
              ? "Minimum d'imposition"
              : "Paiement unique",
          amount: Number(
            gn12.paiement_integral_montant ||
              gn12.montant_effectif_a_payer ||
              gn12.minimum_imposition ||
              0,
          ),
          formatted_amount: formatDzdAmount(
            Number(
              gn12.paiement_integral_montant ||
                gn12.montant_effectif_a_payer ||
                gn12.minimum_imposition ||
                0,
            ),
          ),
          due_date: gn12.paiement_integral_date || gn12.date_depot || "",
          formatted_due_date: formatDateOnly(gn12.paiement_integral_date || gn12.date_depot || ""),
          paid: Boolean(gn12.paiement_integral_date || gn12.date_depot),
          status_label: gn12.paiement_integral_date || gn12.date_depot ? "Payee" : "En attente",
        },
      ],
    };
  }

  const items = [
    {
      key: "tranche1",
      label: "1re tranche",
      amount: Number(gn12.tranche1_montant || 0),
      due_date: gn12.tranche1_date || `${gn12.annee}-06-30`,
      paid: Boolean(gn12.tranche1_quittance || gn12.tranche1_date),
      quittance: gn12.tranche1_quittance || "",
    },
    {
      key: "tranche2",
      label: "2e tranche",
      amount: Number(gn12.tranche2_montant || 0),
      due_date: gn12.tranche2_date || `${gn12.annee}-09-15`,
      paid: Boolean(gn12.tranche2_quittance || gn12.tranche2_date),
      quittance: gn12.tranche2_quittance || "",
    },
    {
      key: "tranche3",
      label: "3e tranche",
      amount: Number(gn12.tranche3_montant || 0),
      due_date: gn12.tranche3_date || `${gn12.annee}-12-15`,
      paid: Boolean(gn12.tranche3_quittance || gn12.tranche3_date),
      quittance: gn12.tranche3_quittance || "",
    },
  ].map((item) => ({
    ...item,
    formatted_amount: formatDzdAmount(item.amount),
    formatted_due_date: formatDateOnly(item.due_date),
    status_label: item.paid ? "Payee" : "En attente",
  }));

  return {
    mode: "fractionne",
    status_label: "Paiement fractionne sur trois tranches",
    items,
  };
};

const buildIfuDocuments = ({ companyId, annee, gn12, gn12bis, g50terItems }) => {
  const documents = [];

  documents.push({
    key: `gn12-${gn12?.id || annee}`,
    label: `GN°12 ${annee}`,
    subtitle: `Serie GN°12 ${annee}`,
    endpoint: gn12?.id ? `/fiscal/gn12/${gn12.id}/pdf` : "",
    params: { company_id: companyId },
    available: Boolean(gn12?.id),
  });

  documents.push({
    key: `gn12bis-${gn12bis?.id || annee}`,
    label: `GN°12 Bis ${annee}`,
    subtitle: `Serie GN°12 Bis ${annee}`,
    endpoint: gn12bis?.id ? `/fiscal/gn12bis/${gn12bis.id}/pdf` : "",
    params: { company_id: companyId },
    available: Boolean(gn12bis?.id),
  });

  const g50terByQuarter = new Map(
    g50terItems.map((item) => [Number(item.trimestre), item]),
  );

  [1, 2, 3, 4].forEach((quarter) => {
    const item = g50terByQuarter.get(quarter);

    documents.push({
      key: `g50ter-${item?.id || quarter}`,
      label: `G50ter T${quarter} ${annee}`,
      subtitle: `Declaration trimestrielle IRG/Salaires`,
      endpoint: item?.id ? `/fiscal/g50ter/${item.id}/pdf` : "",
      params: { company_id: companyId },
      available: Boolean(item?.id),
    });
  });

  documents.push({
    key: `ifu-report-${annee}`,
    label: `Rapport IFU annuel ${annee}`,
    subtitle: "Synthese IFU et paiements",
    endpoint: `/fiscal/ifu-annual-report/pdf`,
    params: { company_id: companyId, annee },
    available: true,
  });

  return documents;
};

const buildIfuAnnualReportData = async (db, { companyId, annee }) => {
  const [company, profile, yearData, yearContext] = await Promise.all([
    fetchCompany(db, companyId),
    fetchFiscalProfile(db, companyId),
    fetchYearDeclarations(db, companyId, annee),
    resolveYearContext(db, companyId, annee),
  ]);

  const summary = buildIfuAnnualRows({
    gn12: yearData.gn12,
    gn12bis: yearData.gn12bis,
    profile,
  });
  const minimumApplied = Boolean(
    yearData.gn12 &&
      Number(yearData.gn12.montant_effectif_a_payer || 0) >
        Number(yearData.gn12.total_ifu_du || 0),
  );
  const minimumAmount = Number(
    yearData.gn12?.minimum_imposition ||
      profile.minimum_imposition_standard ||
      30000,
  );
  const ifuPrevisionnelAcquitte = Number(
    yearData.gn12?.montant_effectif_a_payer ||
      yearData.gn12?.total_ifu_du ||
      0,
  );
  const ifuComplementaire = Number(
    yearData.gn12bis?.total_ifu_complementaire || 0,
  );
  const totalIfuExercice = Number(
    yearData.gn12bis?.total_ifu_exercice ||
      ifuPrevisionnelAcquitte + ifuComplementaire,
  );

  return {
    company,
    annee,
    meta: {
      available_years: yearContext.availableYears,
    },
    summary,
    minimum_indicator: {
      applied: minimumApplied,
      amount: minimumAmount,
      formatted_amount: formatDzdAmount(minimumAmount),
      label: minimumApplied
        ? `Minimum d'imposition applique (${formatDzdAmount(minimumAmount)})`
        : "Calcul normal sans minimum d'imposition",
    },
    fractionnement: buildFractionnementTracker(yearData.gn12),
    totals: {
      ifu_previsionnel_acquitte: ifuPrevisionnelAcquitte,
      formatted_ifu_previsionnel_acquitte: formatDzdAmount(ifuPrevisionnelAcquitte),
      ifu_complementaire: ifuComplementaire,
      formatted_ifu_complementaire: formatDzdAmount(ifuComplementaire),
      total_ifu_exercice: totalIfuExercice,
      formatted_total_ifu_exercice: formatDzdAmount(totalIfuExercice),
    },
    documents: buildIfuDocuments({
      companyId,
      annee,
      gn12: yearData.gn12,
      gn12bis: yearData.gn12bis,
      g50terItems: yearData.g50ter.filter((item) => hasFiledStatus(item.statut)),
    }),
  };
};

const buildIfuAnnualReportPdfPayload = ({ company, annee, reportData, generatedBy }) => ({
  title: `Rapport IFU Annuel ${annee}`,
  description:
    "Synthese annuelle IFU comparant le previsionnel, le realise et les documents fiscaux generes.",
  company,
  generated_at: new Intl.DateTimeFormat("fr-FR", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date()),
  generated_by: generatedBy || "Systeme",
  parameters: [{ label: "Annee fiscale", value: String(annee) }],
  cards: [
    {
      label: "IFU previsionnel acquitte",
      value: reportData.totals.ifu_previsionnel_acquitte,
      type: "amount",
    },
    {
      label: "IFU complementaire",
      value: reportData.totals.ifu_complementaire,
      type: "amount",
    },
    {
      label: "Total IFU exercice",
      value: reportData.totals.total_ifu_exercice,
      type: "amount",
    },
  ],
  warnings: [
    {
      tone: reportData.minimum_indicator.applied ? "warning" : "success",
      message: reportData.minimum_indicator.label,
    },
  ],
  sections: [
    {
      title: "Synthese IFU",
      columns: [
        { key: "label", label: "Activite" },
        { key: "forecast_ca", label: "CA previsionnel", type: "amount" },
        { key: "forecast_ifu", label: "IFU previsionnel", type: "amount" },
        { key: "actual_ca", label: "CA reel", type: "amount" },
        { key: "actual_ifu", label: "IFU reel", type: "amount" },
        { key: "complementary_ifu", label: "Complementaire", type: "amount" },
      ],
      rows: [
        ...reportData.summary.rows,
        {
          row_type: "grand_total",
          label: "TOTAL",
          forecast_ca: reportData.summary.totals.forecast_ca,
          forecast_ifu: reportData.summary.totals.forecast_ifu,
          actual_ca: reportData.summary.totals.actual_ca,
          actual_ifu: reportData.summary.totals.actual_ifu,
          complementary_ifu: reportData.summary.totals.complementary_ifu,
        },
      ],
    },
    {
      title: "Documents generes",
      columns: [
        { key: "label", label: "Document" },
        { key: "subtitle", label: "Description" },
        { key: "available_label", label: "Disponibilite" },
      ],
      rows: reportData.documents.map((item) => ({
        label: item.label,
        subtitle: item.subtitle,
        available_label: item.available ? "PDF disponible" : "Non genere",
      })),
    },
  ],
  summary: [
    {
      label: "Total IFU exercice",
      value: reportData.totals.total_ifu_exercice,
      type: "amount",
    },
  ],
});

export const fiscalDashboardController = {
  getDashboard: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const data = await buildDashboardData(client, {
        companyId,
        annee: yearContext.selectedYear,
        userId: req.user?.sub || req.user?.id || null,
        io: req.app.get("io"),
      });

      await client.query("COMMIT");

      res.json({
        company_id: companyId,
        annee: data.annee,
        alert: data.alert,
        kpis: data.kpis,
        compliance: data.compliance,
        upcoming_deadlines: data.upcoming_deadlines,
        potential_penalties: data.potential_penalties,
        charts: data.charts,
        recent_activity: data.recent_activity,
        meta: data.meta,
      });
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },

  getComplianceRate: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const calendarData = await getFiscalCalendarData(client, {
        companyId,
        annee: yearContext.selectedYear,
        userId: req.user?.sub || req.user?.id || null,
        io: req.app.get("io"),
      });
      const compliance = await buildComplianceData(client, companyId, calendarData.items || []);

      await client.query("COMMIT");

      res.json({
        company_id: companyId,
        annee: yearContext.selectedYear,
        ...compliance,
      });
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },

  getIfuAnnualReport: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const reportData = await buildIfuAnnualReportData(client, {
        companyId,
        annee: yearContext.selectedYear,
      });

      await client.query("COMMIT");

      res.json({
        company_id: companyId,
        annee: reportData.annee,
        summary: reportData.summary,
        minimum_indicator: reportData.minimum_indicator,
        fractionnement: reportData.fractionnement,
        totals: reportData.totals,
        documents: reportData.documents,
        meta: reportData.meta,
      });
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },

  exportIfuAnnualReportPdf: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const reportData = await buildIfuAnnualReportData(client, {
        companyId,
        annee: yearContext.selectedYear,
      });

      await client.query("COMMIT");

      const buffer = await exportReportAsPdf(
        buildIfuAnnualReportPdfPayload({
          company: reportData.company,
          annee: reportData.annee,
          reportData,
          generatedBy: req.user?.fullName || req.user?.email || "Systeme",
        }),
      );

      res.setHeader("Content-Type", "application/pdf");
      res.setHeader(
        "Content-Disposition",
        `inline; filename="rapport-ifu-annuel-${reportData.annee}.pdf"`,
      );
      res.send(Buffer.from(buffer));
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },

  getMonthlyPaymentsChart: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const yearData = await fetchYearDeclarations(client, companyId, yearContext.selectedYear);
      const items = buildMonthlyPaymentsChart(yearContext.selectedYear, yearData);

      await client.query("COMMIT");

      res.json({
        company_id: companyId,
        annee: yearContext.selectedYear,
        items,
      });
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },

  getTaxBreakdownChart: async (req, res) => {
    const companyId = getCompanyId(req);
    const client = await pool.connect();

    try {
      await client.query("BEGIN");

      const yearContext = await resolveYearContext(client, companyId, req.query.annee);
      const yearData = await fetchYearDeclarations(client, companyId, yearContext.selectedYear);
      const totals = computeYearTotals(yearData);
      const chart = buildTaxBreakdown(totals);

      await client.query("COMMIT");

      res.json({
        company_id: companyId,
        annee: yearContext.selectedYear,
        ...chart,
      });
    } catch (error) {
      await client.query("ROLLBACK").catch(() => {});
      throw error;
    } finally {
      client.release();
    }
  },
};
