import { useState, useEffect, useCallback } from 'react'
import { ChevronLeft, ChevronRight, Download } from 'lucide-react'
import { getActuals, getNetSales, getBudgets, downloadExport } from '../api'
import type { DeptActuals, WageBudget } from '../types'

function localStr(d: Date): string {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

function mondayOf(d: Date): string {
  const day = d.getDay()
  const r = new Date(d)
  r.setDate(d.getDate() + (day === 0 ? -6 : 1 - day))
  r.setHours(0, 0, 0, 0)
  return localStr(r)
}

function addDaysStr(dateStr: string, n: number): string {
  const d = new Date(dateStr + 'T00:00:00')
  d.setDate(d.getDate() + n)
  return localStr(d)
}

function daysInMonthFor(dateStr: string): number {
  const d = new Date(dateStr + 'T00:00:00')
  return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate()
}

function fmtDisplay(dateStr: string): string {
  return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-GB', { day: 'numeric', month: 'short' })
}

function fmtMoney(n: number): string {
  return `£${n.toLocaleString('en-GB', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}`
}

function pctClass(pct: number | null): string {
  if (pct == null) return ''
  if (pct <= 100) return 'pct-green'
  if (pct <= 110) return 'pct-amber'
  return 'pct-red'
}

export default function Weekly() {
  const [fromStr, setFromStr] = useState<string>(() => mondayOf(new Date()))

  const toStr         = addDaysStr(fromStr, 6)
  const todayStr      = localStr(new Date())
  const isCurrentWeek = fromStr === mondayOf(new Date())
  const pyFromStr     = addDaysStr(fromStr, -364)
  // For current (partial) week cap PY at equivalent elapsed day — fair WTD comparison
  const daysElapsed = isCurrentWeek
    ? Math.round((new Date(todayStr + 'T00:00:00').getTime() - new Date(fromStr + 'T00:00:00').getTime()) / 86_400_000)
    : 6
  const pyToStr = addDaysStr(fromStr, -364 + daysElapsed)

  const [depts,       setDepts]       = useState<DeptActuals[]>([])
  const [netSales,    setNetSales]    = useState(0)
  const [pySales,     setPySales]     = useState(0)
  const [pyWages,     setPyWages]     = useState<number | null>(null)
  const [budget,      setBudget]      = useState<number | null>(null)
  const [monthlyBudg, setMonthlyBudg] = useState<number | null>(null)
  const [deptPcts,    setDeptPcts]    = useState<Record<string, number>>({})
  const [showOncosts, setShowOncosts] = useState(true)
  const [loading,     setLoading]     = useState(true)
  const [error,       setError]       = useState<string | null>(null)

  const load = useCallback(async () => {
    setLoading(true); setError(null)
    try {
      const [actRes, salesRes, budgetRes, pyActRes] = await Promise.all([
        getActuals(fromStr, toStr),
        getNetSales(fromStr, toStr),
        getBudgets(),
        getActuals(pyFromStr, pyToStr),
      ])
      setDepts(actRes.departments)
      setShowOncosts(actRes.show_oncosts)
      setDeptPcts(actRes.dept_pcts)
      setNetSales(salesRes.days.reduce((s, d) => s + d.net_sales, 0))
      // For current week only sum PY sales for elapsed days (WTD = apples to apples)
      const isCurrentWk = fromStr === mondayOf(new Date())
      setPySales(
        isCurrentWk
          ? salesRes.days.filter(d => d.date <= todayStr).reduce((s, d) => s + d.py_sales, 0)
          : salesRes.days.reduce((s, d) => s + d.py_sales, 0)
      )

      const pyTotal = pyActRes.departments.reduce(
        (s, dep) => s + Object.values(dep.days).reduce((ds, d) => ds + d.cost, 0), 0
      )
      setPyWages(pyTotal > 0 ? pyTotal : null)

      const d0 = new Date(fromStr + 'T00:00:00')
      const monthKey = `${d0.getFullYear()}-${String(d0.getMonth() + 1).padStart(2, '0')}-01`
      const bRow = (budgetRes.budgets as WageBudget[]).find(b => b.month === monthKey)
      if (bRow) {
        const dim = daysInMonthFor(fromStr)
        const effectiveTo = todayStr < toStr ? todayStr : toStr
        const effectiveFrom = fromStr > todayStr ? todayStr : fromStr
        const weekDays = effectiveTo >= effectiveFrom
          ? Math.round((new Date(effectiveTo + 'T00:00:00').getTime() - new Date(effectiveFrom + 'T00:00:00').getTime()) / 86_400_000) + 1
          : 7
        const ratio = weekDays / dim
        setMonthlyBudg(bRow.budget_amount)
        setBudget(bRow.budget_amount * ratio)
      } else {
        setMonthlyBudg(null)
        setBudget(null)
      }
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Failed to load')
    } finally {
      setLoading(false)
    }
  }, [fromStr, toStr, todayStr, pyFromStr, pyToStr])

  useEffect(() => { load() }, [load])

  const prev = () => setFromStr(s => addDaysStr(s, -7))
  const next = () => setFromStr(s => addDaysStr(s, 7))

  const deptWeekBudget = (deptId: string) =>
    budget != null && monthlyBudg != null && (deptPcts[deptId] ?? 0) > 0
      ? budget * (deptPcts[deptId] / 100)
      : null

  const deptTotals = depts.map(dep => ({
    department_id:   dep.department_id,
    department_name: dep.department_name,
    cost: Object.values(dep.days).reduce((s, d) => s + d.cost, 0),
  })).sort((a, b) => b.cost - a.cost)

  const totalWages = deptTotals.reduce((s, d) => s + d.cost, 0)
  const pctBudget  = budget != null && budget > 0 ? (totalWages / budget) * 100 : null
  const pctSales   = netSales > 0 ? (totalWages / netSales) * 100 : null

  function pyPct(current: number, py: number): string {
    if (py <= 0 || current <= 0) return ''
    const p = ((current - py) / py) * 100
    return ` (${p >= 0 ? '+' : ''}${p.toFixed(1)}%)`
  }

  const weekLabel = `${fmtDisplay(fromStr)} – ${fmtDisplay(toStr)} ${new Date(toStr + 'T00:00:00').getFullYear()}`

  return (
    <div>
      <div className="page-header">
        <h1 className="page-title">Weekly Wages</h1>
        <button className="btn btn-secondary" onClick={() => downloadExport('weekly', fromStr, toStr)}>
          <Download size={14} strokeWidth={1.75} /> CSV
        </button>
      </div>

      <div className="period-nav" style={{ marginBottom: 20 }}>
        <button className="btn btn-secondary" onClick={prev}><ChevronLeft size={16} strokeWidth={1.75} /></button>
        <span className="period-label">{weekLabel}</span>
        <button className="btn btn-secondary" onClick={next} disabled={isCurrentWeek}><ChevronRight size={16} strokeWidth={1.75} /></button>
      </div>

      <div className="summary-grid">
        <div className="summary-card">
          <div className="label">Total Wages</div>
          <div className="value">{fmtMoney(totalWages)}</div>
          {pyWages != null
            ? <div className="sub">{isCurrentWeek ? 'PY WTD' : 'PY'} {fmtMoney(pyWages)}{pyPct(totalWages, pyWages)}</div>
            : <div className="sub">{showOncosts ? 'incl. on-costs' : 'base cost'}</div>}
        </div>
        <div className="summary-card">
          <div className="label">Pro-rata Budget</div>
          <div className="value">{budget != null ? fmtMoney(budget) : '—'}</div>
          <div className="sub">proportion of monthly</div>
        </div>
        <div className="summary-card">
          <div className="label">% vs Budget</div>
          <div className="value">
            {pctBudget != null
              ? <span className={`pct-badge ${pctClass(pctBudget)}`}>{pctBudget.toFixed(1)}%</span>
              : '—'}
          </div>
        </div>
        <div className="summary-card">
          <div className="label">Net Sales</div>
          <div className="value">{fmtMoney(netSales)}</div>
          {pySales > 0 && <div className="sub">{isCurrentWeek ? 'PY WTD' : 'PY'} {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
        </div>
        <div className="summary-card">
          <div className="label">% of Net Sales</div>
          <div className="value">{pctSales != null ? `${pctSales.toFixed(1)}%` : '—'}</div>
        </div>
      </div>

      {loading && <div className="state-center">Loading…</div>}
      {error   && <div className="state-center" style={{ color: '#dc2626' }}>{error}</div>}

      {!loading && !error && (
        <div className="card">
          <table className="data-table">
            <thead>
              <tr>
                <th>Department</th>
                <th className="right">Wages</th>
                <th className="right">% of Total</th>
                <th className="right">Budget (pro-rata)</th>
                <th className="right">% Budget</th>
                <th className="right">% Net Sales</th>
              </tr>
            </thead>
            <tbody>
              {deptTotals.map(dep => {
                const depBudg    = deptWeekBudget(dep.department_id)
                const depPct     = depBudg != null && depBudg > 0 ? (dep.cost / depBudg) * 100 : null
                const depOfTotal = totalWages > 0 ? (dep.cost / totalWages) * 100 : null
                const depSPct    = netSales > 0 ? (dep.cost / netSales) * 100 : null
                return (
                  <tr key={dep.department_name}>
                    <td>{dep.department_name}</td>
                    <td className="right">{fmtMoney(dep.cost)}</td>
                    <td className="right" style={{ color: 'var(--text-muted)' }}>
                      {depOfTotal != null ? `${depOfTotal.toFixed(1)}%` : '—'}
                    </td>
                    <td className="right">{depBudg != null ? fmtMoney(depBudg) : '—'}</td>
                    <td className="right">
                      {depPct != null
                        ? <span className={`pct-badge ${pctClass(depPct)}`}>{depPct.toFixed(1)}%</span>
                        : '—'}
                    </td>
                    <td className="right">{depSPct != null ? `${depSPct.toFixed(1)}%` : '—'}</td>
                  </tr>
                )
              })}
              <tr className="total-row">
                <td>Total</td>
                <td className="right">{fmtMoney(totalWages)}</td>
                <td className="right">100%</td>
                <td className="right">{budget != null ? fmtMoney(budget) : '—'}</td>
                <td className="right">
                  {pctBudget != null
                    ? <span className={`pct-badge ${pctClass(pctBudget)}`}>{pctBudget.toFixed(1)}%</span>
                    : '—'}
                </td>
                <td className="right">{pctSales != null ? `${pctSales.toFixed(1)}%` : '—'}</td>
              </tr>
            </tbody>
          </table>
          {showOncosts && (
            <p className="footnote">Includes estimated employer on-costs. Final payroll figures are in Sage.</p>
          )}
        </div>
      )}
    </div>
  )
}
