import Link from 'next/link'
import { createClient } from '@/lib/supabase/server'
import { getAppOrg } from '@/lib/org'
import { getEffectiveUser } from '@/lib/effective-user'
import { canTransfer } from '@/lib/permissions'
import {
  defaultInvoiceDate,
  listInvoices,
  type InvoiceStatus,
} from '@/lib/invoices'
import { fmtUsd } from '@/lib/format'
import { createInvoice } from './actions'

const STATUS_BADGE: Record<InvoiceStatus, { label: string; color: string }> = {
  open: { label: 'Open', color: '#0a7d3f' },
  sent: { label: 'Sent', color: '#0369a1' },
  paid: { label: 'Paid', color: '#6b7280' },
}

export default async function InvoicesPage({
  searchParams,
}: {
  searchParams: Promise<{ error?: string; info?: string; new?: string }>
}) {
  const sp = await searchParams
  const supabase = await createClient()
  const org = await getAppOrg(supabase)

  if (!org) {
    return (
      <main>
        <h1>Invoices</h1>
        <p className="error">Bowden Works organization not found.</p>
      </main>
    )
  }

  const eu = await getEffectiveUser(supabase, org.id)
  const userCanTransfer = canTransfer(eu)
  const showNew = sp.new === '1'

  const invoices = await listInvoices(supabase, org.id)

  // Pull aggregate billout per invoice so the list shows a meaningful
  // total. One round-trip total across all invoices via PostgREST.
  const { data: aggRows } = await supabase
    .from('time_entries')
    .select('invoice_id, billout_amount_usd, billout_cost_usd')
    .eq('org_id', org.id)
    .not('invoice_id', 'is', null)
    .returns<
      {
        invoice_id: string
        billout_amount_usd: number | string | null
        billout_cost_usd: number | string | null
      }[]
    >()
  const totals = new Map<
    string,
    { count: number; billout: number; cost: number }
  >()
  for (const r of aggRows ?? []) {
    const cur = totals.get(r.invoice_id) ?? { count: 0, billout: 0, cost: 0 }
    cur.count += 1
    cur.billout += Number(r.billout_amount_usd ?? 0)
    cur.cost += Number(r.billout_cost_usd ?? 0)
    totals.set(r.invoice_id, cur)
  }

  // For the "Create invoice" form we need operator + client options.
  const [{ data: operators }, { data: clients }] = await Promise.all([
    supabase
      .from('operators')
      .select('id, name')
      .eq('org_id', org.id)
      .order('name')
      .returns<{ id: string; name: string }[]>(),
    supabase
      .from('clients')
      .select('id, name, operator_id')
      .eq('org_id', org.id)
      .order('name')
      .returns<{ id: string; name: string; operator_id: string | null }[]>(),
  ])

  return (
    <main>
      <div className="page-head">
        <div>
          <h1>Invoices</h1>
          <p className="subtitle">
            Each invoice groups time entries you&apos;ve billed for. Applying
            entries to an invoice locks them — only an owner can detach
            them again.
          </p>
        </div>
        {userCanTransfer && !showNew && (
          <Link href="/invoices?new=1" className="button-link" scroll={false}>
            + New invoice
          </Link>
        )}
      </div>

      {sp.error && <p className="error">{sp.error}</p>}
      {sp.info && <p className="info">{sp.info}</p>}

      {showNew && userCanTransfer && (
        <div className="panel" style={{ marginBottom: '1.25rem' }}>
          <div className="panel-header">
            <h3 style={{ margin: 0, fontSize: '0.95rem' }}>New invoice</h3>
          </div>
          <form action={createInvoice}>
            <div
              style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
                gap: '0.75rem 1rem',
              }}
            >
              <label style={{ gridColumn: 'span 2' }}>
                Name
                <input
                  type="text"
                  name="name"
                  placeholder="e.g. 2026-04 PlusROI"
                  required
                  autoFocus
                />
              </label>
              <label>
                Status
                <select name="status" defaultValue="open">
                  <option value="open">Open</option>
                  <option value="sent">Sent</option>
                  <option value="paid">Paid</option>
                </select>
              </label>
              <label>
                Invoice date{' '}
                <span className="muted">(defaults to end of last month)</span>
                <input
                  type="date"
                  name="invoice_date"
                  defaultValue={defaultInvoiceDate()}
                />
              </label>
              <label>
                Operator <span className="muted">(optional)</span>
                <select name="operator_id" defaultValue="">
                  <option value="">— any —</option>
                  {(operators ?? []).map((o) => (
                    <option key={o.id} value={o.id}>
                      {o.name}
                    </option>
                  ))}
                </select>
              </label>
              <label>
                Client <span className="muted">(optional)</span>
                <select name="client_id" defaultValue="">
                  <option value="">— any —</option>
                  {(clients ?? []).map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.name}
                    </option>
                  ))}
                </select>
              </label>
              <label>
                Manual total{' '}
                <span className="muted">
                  (USD; blank = use sum of entries)
                </span>
                <input
                  type="number"
                  name="manual_total_usd"
                  step="0.01"
                  min="0"
                  placeholder="e.g. 1500.00"
                />
              </label>
              <label style={{ gridColumn: 'span 3' }}>
                Notes <span className="muted">(optional)</span>
                <input type="text" name="notes" />
              </label>
            </div>
            <div
              className="flex-row"
              style={{ gap: '0.5rem', marginTop: '0.75rem' }}
            >
              <button type="submit">Create invoice</button>
              <Link href="/invoices" className="button-link-secondary">
                Cancel
              </Link>
            </div>
          </form>
        </div>
      )}

      {invoices.length === 0 ? (
        <p className="empty">
          No invoices yet.{' '}
          {userCanTransfer && (
            <Link href="/invoices?new=1" scroll={false}>
              Create the first one
            </Link>
          )}
        </p>
      ) : (
        <div className="panel" style={{ padding: 0, overflow: 'hidden' }}>
          <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
            <table className="data">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Status</th>
                  <th>Operator</th>
                  <th>Client</th>
                  <th className="num">Entries</th>
                  <th className="num">Cost</th>
                  <th className="num">Billout</th>
                  <th className="num">Margin</th>
                  <th>Invoice date</th>
                </tr>
              </thead>
              <tbody>
                {invoices.map((inv) => {
                  const t = totals.get(inv.id) ?? {
                    count: 0,
                    billout: 0,
                    cost: 0,
                  }
                  const effectiveBillout = inv.manual_total_usd ?? t.billout
                  const margin = effectiveBillout - t.cost
                  const marginPct =
                    effectiveBillout > 0
                      ? (margin / effectiveBillout) * 100
                      : null
                  return (
                    <tr key={inv.id}>
                      <td>
                        <Link href={`/invoices/${inv.id}`}>{inv.name}</Link>
                      </td>
                      <td>
                        <span
                          className="badge"
                          style={{
                            background: STATUS_BADGE[inv.status].color,
                            color: '#fff',
                            padding: '0.15em 0.5em',
                            borderRadius: 999,
                            fontSize: '0.8em',
                          }}
                        >
                          {STATUS_BADGE[inv.status].label}
                        </span>
                      </td>
                      <td className="muted">{inv.operator_name ?? '—'}</td>
                      <td className="muted">{inv.client_name ?? '—'}</td>
                      <td className="num">{t.count}</td>
                      <td className="num">{fmtUsd(t.cost)}</td>
                      <td className="num">
                        {fmtUsd(effectiveBillout)}
                        {inv.manual_total_usd != null && t.billout !== inv.manual_total_usd && (
                          <span
                            className="muted"
                            style={{
                              display: 'block',
                              fontSize: '0.75em',
                              lineHeight: 1.2,
                            }}
                            title={`Sum of entries: ${fmtUsd(t.billout)}`}
                          >
                            manual override
                          </span>
                        )}
                      </td>
                      <td
                        className="num"
                        style={{
                          color: margin >= 0 ? '#0a7d3f' : '#b91c1c',
                        }}
                      >
                        {margin >= 0 ? '+' : ''}
                        {fmtUsd(margin)}
                        {marginPct != null && (
                          <span
                            className="muted"
                            style={{
                              display: 'block',
                              fontSize: '0.75em',
                              lineHeight: 1.2,
                            }}
                          >
                            {marginPct.toFixed(1)}%
                          </span>
                        )}
                      </td>
                      <td className="muted" style={{ fontSize: '0.85em' }}>
                        {inv.invoice_date ?? inv.created_at.slice(0, 10)}
                      </td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </main>
  )
}
