import { Fragment, useCallback, useEffect, useState } from 'react'
import { AlertTriangle } from 'lucide-react'
import { formatMoney, formatUnits, groupByCategory, formatBasis } from '../types'
import type { Category, ConsumptionCostReport, RollupReport, MeterCostRow } from '../types'
import * as api from '../api'

function extrasFor(m: { ccl_cost_pence: number; rab_levy_cost_pence: number; metering_cost_pence: number; other_charges_cost_pence: number }): number {
  return m.ccl_cost_pence + m.rab_levy_cost_pence + m.metering_cost_pence + m.other_charges_cost_pence
}

// Sub-meters (parent_meter_id set) read a subset of their parent's own
// reading (e.g. the water softener sits inline on the main supply) — their
// row is still shown for visibility, but excluding them here avoids the
// subtotal double-counting water/energy that's already in the parent's figure.
function sumMeterCosts(rows: MeterCostRow[]) {
  return rows.filter(r => !r.parent_meter_id).reduce((acc, r) => ({
    consumption: acc.consumption + (r.consumption || 0),
    usage_cost_pence: acc.usage_cost_pence + r.usage_cost_pence,
    standing_cost_pence: acc.standing_cost_pence + r.standing_cost_pence,
    extras_cost_pence: acc.extras_cost_pence + extrasFor(r),
    vat_pence: acc.vat_pence + r.vat_pence,
    total_pence: acc.total_pence + r.total_pence,
  }), { consumption: 0, usage_cost_pence: 0, standing_cost_pence: 0, extras_cost_pence: 0, vat_pence: 0, total_pence: 0 })
}

function currentPeriod(): string {
  const now = new Date()
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
}

export default function Reports() {
  const [categories, setCategories] = useState<Category[]>([])
  const [categoryId, setCategoryId] = useState<number | ''>('')
  const [period, setPeriod] = useState(currentPeriod())
  const [report, setReport] = useState<ConsumptionCostReport | null>(null)
  const [rollup, setRollup] = useState<RollupReport | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => { api.fetchCategories().then(setCategories).catch(() => {}) }, [])

  const load = useCallback(() => {
    setLoading(true)
    setError(null)
    Promise.all([
      api.fetchConsumptionCostReport(period, categoryId || undefined),
      api.fetchRollupReport(period),
    ]).then(([r, ru]) => { setReport(r); setRollup(ru) })
      .catch(err => setError(err.message))
      .finally(() => setLoading(false))
  }, [period, categoryId])
  useEffect(() => { load() }, [load])

  return (
    <div className="page">
      <div className="page-header">
        <h1>Reports</h1>
        <div className="field" style={{ marginBottom: 0 }}>
          <input type="month" value={period} onChange={e => setPeriod(e.target.value)} />
        </div>
        <div className="field" style={{ marginBottom: 0 }}>
          <select value={categoryId} onChange={e => setCategoryId(e.target.value ? parseInt(e.target.value) : '')}>
            <option value="">All categories</option>
            {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
          </select>
        </div>
      </div>

      {error && <div className="error-banner">{error}</div>}
      {loading || !report ? (
        <div className="loading-state">Loading…</div>
      ) : (
        <>
          <div className="stats-strip">
            <div className="stat-box"><div className="stat-value">{formatMoney(report.totals.total_pence)}</div><div className="stat-label">Total cost</div></div>
            <div className="stat-box"><div className="stat-value">{formatMoney(report.totals.usage_cost_pence)}</div><div className="stat-label">Usage</div></div>
            <div className="stat-box"><div className="stat-value">{formatMoney(report.totals.standing_cost_pence)}</div><div className="stat-label">Standing</div></div>
            <div className="stat-box"><div className="stat-value">{formatMoney(extrasFor(report.totals))}</div><div className="stat-label">Extras</div></div>
            <div className="stat-box"><div className="stat-value">{formatMoney(report.totals.vat_pence)}</div><div className="stat-label">VAT</div></div>
          </div>

          <div className="section-title">Consumption &amp; cost by meter</div>
          {report.meters.length === 0 ? (
            <div className="empty-state">No meters to report on.</div>
          ) : (
            <div className="table-wrap">
              <table className="data">
                <thead>
                  <tr>
                    <th>Meter</th><th className="num">Consumption</th>
                    <th className="num">Usage</th><th className="num">Standing</th><th className="num">Extras</th>
                    <th className="num">VAT</th><th className="num">Total</th><th>Basis</th>
                  </tr>
                </thead>
                <tbody>
                  {groupByCategory(report.meters).map(group => {
                    const subtotal = sumMeterCosts(group.rows)
                    return (
                      <Fragment key={group.category_id}>
                        {group.rows.map(m => (
                          <tr key={m.meter_id}>
                            <td>
                              {m.meter_name}
                              {m.parent_meter_id && (
                                <span className="badge" style={{ marginLeft: 6 }} title="Sub-meter — reads a subset of its parent meter, excluded from the subtotal below to avoid double-counting">
                                  submeter
                                </span>
                              )}
                              {m.rate_changed_mid_period && (
                                <span className="badge badge-tou" style={{ marginLeft: 6 }} title={m.segments.map(s => `${s.tariff_name}: ${s.seg_start} – ${s.seg_end}`).join(', ')}>
                                  rate changed
                                </span>
                              )}
                            </td>
                            <td className="num">{formatUnits(m.consumption, m.unit_label)}</td>
                            <td className="num">{formatMoney(m.usage_cost_pence)}</td>
                            <td className="num">{formatMoney(m.standing_cost_pence)}</td>
                            <td className="num">{formatMoney(extrasFor(m))}</td>
                            <td className="num">{formatMoney(m.vat_pence)}</td>
                            <td className="num">{formatMoney(m.total_pence)}</td>
                            <td>{formatBasis(m.status, m.as_of_date)}</td>
                          </tr>
                        ))}
                        <tr className="subtotal-row">
                          <td>{group.category_name} subtotal</td>
                          <td className="num">{formatUnits(subtotal.consumption, group.unit_label)}</td>
                          <td className="num">{formatMoney(subtotal.usage_cost_pence)}</td>
                          <td className="num">{formatMoney(subtotal.standing_cost_pence)}</td>
                          <td className="num">{formatMoney(subtotal.extras_cost_pence)}</td>
                          <td className="num">{formatMoney(subtotal.vat_pence)}</td>
                          <td className="num">{formatMoney(subtotal.total_pence)}</td>
                          <td></td>
                        </tr>
                      </Fragment>
                    )
                  })}
                  <tr className="total-row">
                    <td>Total</td>
                    <td className="num" title="Not summed — mixes units across fuel types">—</td>
                    <td className="num">{formatMoney(report.totals.usage_cost_pence)}</td>
                    <td className="num">{formatMoney(report.totals.standing_cost_pence)}</td>
                    <td className="num">{formatMoney(extrasFor(report.totals))}</td>
                    <td className="num">{formatMoney(report.totals.vat_pence)}</td>
                    <td className="num">{formatMoney(report.totals.total_pence)}</td>
                    <td></td>
                  </tr>
                </tbody>
              </table>
            </div>
          )}

          <div className="section-title">Sub-metering rollup</div>
          {!rollup || rollup.rollups.length === 0 ? (
            <div className="empty-state">No parent/child meter relationships configured.</div>
          ) : (
            <div className="table-wrap">
              <table className="data">
                <thead><tr><th>Parent meter</th><th className="num">Parent consumption</th><th className="num">Children sum</th><th>Children</th><th></th></tr></thead>
                <tbody>
                  {rollup.rollups.map(r => (
                    <tr key={r.parent_meter_id} className={r.anomaly ? 'anomaly-row' : ''}>
                      <td>{r.parent_meter_name}</td>
                      <td className="num">{formatUnits(r.parent_consumption, r.unit_label)}</td>
                      <td className="num">{formatUnits(r.child_sum, r.unit_label)}</td>
                      <td>{r.children.map(c => c.meter_name).join(', ')}</td>
                      <td>
                        {r.anomaly && (
                          <span className="badge badge-anomaly">
                            <AlertTriangle size={11} strokeWidth={1.75} /> Children exceed parent
                          </span>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </>
      )}
    </div>
  )
}
