const { useEffect, useRef } = React;

function FundingForecastSection({ fundFlow, programme, onNav, hasActiveProject }) {
  const barRef = useRef(null);
  const barChartRef = useRef(null);
  const isPhone = useIsPhone();
  const ff = window.ConstructProData.formatCurrency;
  const forecast = fundFlow?.fundingForecast;

  useEffect(() => {
    if (!forecast || !window.Chart) return undefined;

    const barCtx = barRef.current?.getContext("2d");
    if (!barCtx) return undefined;

    const buildChart = window.ConstructProChartPlugins?.buildFundingStackedBarChart;
    barChartRef.current?.destroy();
    barChartRef.current = buildChart
      ? buildChart(barCtx, { chartMonths: forecast.chartMonths || [], isPhone, showYTitle: true })
      : null;

    return () => {
      barChartRef.current?.destroy();
      barChartRef.current = null;
    };
  }, [forecast, isPhone]);

  if (!hasActiveProject || !forecast) return null;

  const { windows, peakMonth, nextMonthLabel, asOnDate } = forecast;
  const asOnLabel = asOnDate || programme?.asOnDate || "today";
  const timeline = forecast.timeline || [];

  return (
    <Card className="mb-6 border-primary/15 bg-gradient-to-br from-white via-surface-container-low to-primary-fixed/20">
      <div className="mb-5 flex flex-wrap items-start justify-between gap-3">
        <SectionTitle
          title="Future funding outlook"
          subtitle={`From ${nextMonthLabel} · as on ${asOnLabel} · ${windows.throughCompletion.monthCount} months · ${ff(windows.throughCompletion.planned)} total`}
        />
        <div className="flex flex-wrap items-center gap-2">
          {peakMonth ? (
            <Badge tone="warning">Peak {peakMonth.label} · {ff(peakMonth.planned)}</Badge>
          ) : null}
          {onNav ? (
            <Button variant="secondary" className="!px-3 !py-2 !text-xs" onClick={() => onNav("schedule")}>
              View programme
            </Button>
          ) : null}
        </div>
      </div>

      <div className="finance-forecast__canvas-wrap mb-6">
        <canvas ref={barRef} aria-label="Monthly funding need chart" />
      </div>

      <div className="finance-forecast__mobile-cards md:hidden">
        {timeline.slice(0, 12).map((row) => (
          <article key={row.monthKey} className="finance-forecast__mobile-card">
            <div className="finance-forecast__mobile-card-header">
              <span className="finance-forecast__mobile-card-month">{row.label}</span>
              <span className="finance-forecast__mobile-card-total">{ff(row.planned)}</span>
            </div>
            <div className="finance-forecast__mobile-card-grid">
              <div>
                Materials
                <strong>{ff(row.material)}</strong>
              </div>
              <div>
                Labour
                <strong>{ff(row.labor)}</strong>
              </div>
              <div>
                Other
                <strong>{ff(row.other || 0)}</strong>
              </div>
              <div className="col-span-2">
                Cumulative
                <strong className="text-primary">{ff(row.cumulative)}</strong>
              </div>
            </div>
          </article>
        ))}
        {timeline.length ? (
          <>
            <article className="finance-forecast__mobile-card border-primary/20 bg-primary-fixed/20">
              <div className="finance-forecast__mobile-card-header">
                <span className="finance-forecast__mobile-card-month">Next month · {nextMonthLabel}</span>
                <span className="finance-forecast__mobile-card-total">{ff(windows.nextMonth.planned)}</span>
              </div>
            </article>
            <article className="finance-forecast__mobile-card border-primary/20 bg-primary-fixed/20">
              <div className="finance-forecast__mobile-card-header">
                <span className="finance-forecast__mobile-card-month">Next 6 months · {windows.next6Months.monthCount} month runway</span>
                <span className="finance-forecast__mobile-card-total">{ff(windows.next6Months.planned)}</span>
              </div>
            </article>
          </>
        ) : null}
      </div>

      <div className="finance-forecast__table-wrap hidden md:block">
        <table className="finance-forecast__table">
          <thead>
            <tr>
              <th>Month</th>
              <th>Total</th>
              <th>Materials</th>
              <th>Labour</th>
              <th>Other</th>
              <th>Cumulative</th>
            </tr>
          </thead>
          <tbody>
            {timeline.slice(0, 12).map((row) => (
              <tr key={row.monthKey}>
                <td>{row.label}</td>
                <td><strong>{ff(row.planned)}</strong></td>
                <td>{ff(row.material)}</td>
                <td>{ff(row.labor)}</td>
                <td>{ff(row.other || 0)}</td>
                <td className="finance-forecast__cumulative">{ff(row.cumulative)}</td>
              </tr>
            ))}
          </tbody>
          {timeline.length ? (
            <tfoot>
              <tr className="finance-forecast__summary-row">
                <td>Next month</td>
                <td><strong>{ff(windows.nextMonth.planned)}</strong></td>
                <td colSpan={3}>{nextMonthLabel}</td>
                <td />
              </tr>
              <tr className="finance-forecast__summary-row">
                <td>Next 6 months</td>
                <td><strong>{ff(windows.next6Months.planned)}</strong></td>
                <td colSpan={3}>{windows.next6Months.monthCount} month runway</td>
                <td />
              </tr>
            </tfoot>
          ) : null}
        </table>
      </div>
      {timeline.length > 12 ? (
        <p className="finance-forecast__table-note">
          Showing next 12 of {timeline.length} remaining months.
        </p>
      ) : null}
    </Card>
  );
}

function Finance({ snapshot, onNav }) {
  const phases = snapshot.projectTree || [];
  const fundFlow = snapshot.fundFlow;
  const ff = window.ConstructProData.formatCurrency;
  const hasActiveProject = Boolean(snapshot.project?.id);

  const totalPlanned = phases.reduce((sum, p) => sum + (p.rollup?.budgetPlanned || p.budgetPlanned || 0), 0);
  const totalActual = phases.reduce((sum, p) => sum + (p.rollup?.budgetActual || p.budgetActual || 0), 0);
  const variance = totalPlanned - totalActual;
  const headroomLabel = variance >= 0 ? "Under budget" : "Over budget";

  let materialActTotal = 0;
  let laborActTotal = 0;
  let otherActTotal = 0;

  snapshot.workItems.forEach((item) => {
    if (item.type === "phase") return;

    if (item.labor) {
      const actVal = item.dprHistory?.reduce((sum, d) => sum + (d.laborCost || 0), 0) || 0;
      const planVal = (item.labor.estCount || 0) * (item.labor.estDailyCost || 0) || (item.budgetPlanned * 0.4);
      laborActTotal += actVal || (item.status === "approved" ? planVal : 0);
    }

    if (item.materials && item.materials.length > 0) {
      item.materials.forEach((m) => {
        const estM = m.quantity * m.estUnitCost;
        const actM = (m.actualQuantity || 0) * (m.actualUnitCost || m.estUnitCost);
        const value = actM || (item.status === "approved" ? estM : 0);
        if (String(m.name || "").trim().toLowerCase() === "other") {
          otherActTotal += value;
        } else {
          materialActTotal += value;
        }
      });
    } else {
      const planVal = item.budgetPlanned * 0.6;
      const actVal = item.dprHistory?.reduce((sum, d) => sum + d.materialsUsed?.reduce((mSum, m) => mSum + (m.cost || 0), 0), 0) || 0;
      materialActTotal += actVal || (item.status === "approved" ? planVal : 0);
    }
  });

  if (materialActTotal === 0 && laborActTotal === 0 && otherActTotal === 0) {
    materialActTotal = totalActual * 0.6 || 0;
    laborActTotal = totalActual * 0.4 || 0;
  }

  const mixTotal = Math.max(1, materialActTotal + laborActTotal + otherActTotal);
  const matPct = Math.round((materialActTotal / mixTotal) * 100) || 0;
  const labPct = Math.round((laborActTotal / mixTotal) * 100) || 0;
  const otherPct = Math.max(0, 100 - matPct - labPct);

  const allDprs = snapshot.workItems
    .flatMap((item) => (item.dprHistory || []).map((dpr) => ({ ...dpr, taskTitle: item.title })))
    .sort((a, b) => b.date.localeCompare(a.date))
    .slice(0, 5);

  return (
    <div className="fade-in">
      <div className="mb-6 grid grid-cols-1 gap-4 md:grid-cols-3">
        <StatCard
          title="Planned Budget"
          value={ff(totalPlanned)}
          trend={`${ff(totalActual)} spent to date`}
          icon={<Icons.finance/>}
        />
        <StatCard
          title="Budget Headroom"
          value={ff(Math.abs(variance))}
          trend={headroomLabel}
          icon={<Icons.quality/>}
          tone={variance >= 0 ? "success" : "warning"}
        />
        <StatCard
          title="Next Month Need"
          value={ff(fundFlow?.fundingForecast?.windows?.nextMonth?.planned || 0)}
          trend={hasActiveProject ? (fundFlow?.fundingForecast?.nextMonthLabel || "Forward plan") : "Create a project"}
          icon={<Icons.schedule/>}
          tone="info"
        />
      </div>

      <FundingForecastSection fundFlow={fundFlow} programme={snapshot.programme} onNav={onNav} hasActiveProject={hasActiveProject} />

      <div className="grid grid-cols-1 gap-6 xl:grid-cols-[1.2fr_.8fr]">
        <Card>
          <SectionTitle title="Spend by Block" subtitle="Planned vs actual by block." />
          <div className="space-y-4">
            {phases.map((phase) => {
              const planned = phase.rollup?.budgetPlanned || phase.budgetPlanned || 0;
              const actual = phase.rollup?.budgetActual || phase.budgetActual || 0;
              const diff = planned - actual;
              const spendPct = planned > 0 ? Math.min(100, Math.round((actual / planned) * 100)) : 0;
              return (
                <div key={phase.id} className="rounded-xl border border-border-light bg-white p-4 space-y-2">
                  <div className="flex items-start justify-between">
                    <div>
                      <h4 className="font-bold text-sm text-text-primary">{phase.title}</h4>
                      <p className="text-xs text-text-muted">{ff(planned)} planned · {ff(actual)} spent</p>
                    </div>
                    <Badge tone={diff >= 0 ? "success" : "danger"}>
                      {diff >= 0 ? `Under ${ff(diff)}` : `Over ${ff(Math.abs(diff))}`}
                    </Badge>
                  </div>
                  <div className="flex items-center gap-3">
                    <ProgressBar value={spendPct} tone={spendPct > 90 ? "danger" : spendPct > 50 ? "orange" : "success"}/>
                    <span className="text-xs font-bold text-text-muted">{spendPct}%</span>
                  </div>
                </div>
              );
            })}
            {phases.length === 0 && (
              <p className="text-sm text-text-muted italic text-center py-6">No blocks active.</p>
            )}
          </div>
        </Card>

        <div className="space-y-6">
          <Card>
            <SectionTitle title="Actual Cost Mix" subtitle={`${matPct}% materials · ${labPct}% labour · ${otherPct}% other`} />
            <div className="space-y-4">
              <div className="flex items-center gap-3">
                <span className="w-20 text-xs font-bold text-text-muted">Materials</span>
                <ProgressBar value={matPct} tone="orange"/>
                <span className="text-xs font-bold text-text-primary">{ff(materialActTotal)}</span>
              </div>
              <div className="flex items-center gap-3">
                <span className="w-20 text-xs font-bold text-text-muted">Labour</span>
                <ProgressBar value={labPct} tone="success"/>
                <span className="text-xs font-bold text-text-primary">{ff(laborActTotal)}</span>
              </div>
              <div className="flex items-center gap-3">
                <span className="w-20 text-xs font-bold text-text-muted">Other</span>
                <ProgressBar value={otherPct} tone="info"/>
                <span className="text-xs font-bold text-text-primary">{ff(otherActTotal)}</span>
              </div>
            </div>
          </Card>

          <Card>
            <SectionTitle title="Recent DPR Outlays" subtitle="Latest daily contractor spend." />
            <div className="space-y-3">
              {allDprs.map((dpr) => {
                const matCost = dpr.materialsUsed?.reduce((sum, m) => sum + (m.cost || 0), 0) || 0;
                return (
                  <div key={dpr.id} className="rounded-lg border border-border-light bg-gray-50 p-3 text-xs">
                    <div className="flex justify-between gap-2 font-bold">
                      <span className="truncate text-text-primary">{dpr.taskTitle}</span>
                      <span className="shrink-0 text-primary">{ff(dpr.laborCost + matCost)}</span>
                    </div>
                    <p className="mt-1 text-[10px] text-text-muted">{dpr.date}</p>
                  </div>
                );
              })}
              {allDprs.length === 0 && (
                <p className="text-xs text-text-muted italic text-center py-4">No outlays reported yet.</p>
              )}
            </div>
          </Card>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Finance });
