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 { fmtUsd } from '@/lib/format'
import {
  findHighlightMatch,
  formatCcPasteBlock,
  type AssignedCcLineForPaste,
} from '@/lib/cc-expenses'
import { appendCcLines, reapplyRules } from '../actions'
import { ExpenseLineRow, type LineForRow } from './expense-line-row'
import { CcPasteBlock } from './paste-block'

type Batch = {
  id: string
  name: string
  org_id: string
  created_at: string
}

type LineRow = {
  id: string
  batch_id: string
  line_index: number
  raw_line: string
  expense_date: string | null
  description: string | null
  amount_usd: number | string | null
  balance_usd: number | string | null
  project_id: string | null
  assignment_description: string | null
  category: string | null
  auto_assigned: boolean
  project?: {
    name: string | null
    client: { name: string | null } | null
  } | null
}

export default async function CcExpenseDetailPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>
  searchParams: Promise<{ error?: string; info?: string }>
}) {
  const { id } = await params
  const sp = await searchParams

  const supabase = await createClient()
  const org = await getAppOrg(supabase)
  if (!org) {
    return (
      <main>
        <h1>Credit Card Expenses</h1>
        <p className="error">Bowden Works organization not found.</p>
      </main>
    )
  }
  const eu = await getEffectiveUser(supabase, org.id)
  if (!canTransfer(eu)) {
    return (
      <main>
        <h1>Credit Card Expenses</h1>
        <p className="error">Owner only.</p>
      </main>
    )
  }

  const { data: batch } = await supabase
    .from('cc_expense_batches')
    .select('id, name, org_id, created_at')
    .eq('org_id', org.id)
    .eq('id', id)
    .maybeSingle<Batch>()

  if (!batch) {
    return (
      <main>
        <h1>Batch not found</h1>
        <p>
          <Link href="/tools/cc-expenses">← Back</Link>
        </p>
      </main>
    )
  }

  const [{ data: lineRows }, { data: projectRows }] = await Promise.all([
    supabase
      .from('cc_expense_lines')
      .select(
        'id, batch_id, line_index, raw_line, expense_date, description, amount_usd, balance_usd, project_id, assignment_description, category, auto_assigned, project:projects(name, client:clients(name))',
      )
      .eq('batch_id', batch.id)
      .order('line_index', { ascending: true })
      .returns<LineRow[]>(),
    supabase
      .from('projects')
      .select('id, name, client:clients(name)')
      .eq('org_id', org.id)
      .order('name')
      .returns<
        { id: string; name: string; client: { name: string } | null }[]
      >(),
  ])

  // Project options for the combobox: `{client} : {project}` per ADR
  // #042's labeling convention.
  const projectOptions = (projectRows ?? [])
    .filter((p) => p.client?.name)
    .map((p) => ({
      id: p.id,
      label: `${p.client!.name} : ${p.name}`,
    }))
    .sort((a, b) => a.label.localeCompare(b.label))

  // Category autocomplete: distinct values used across the org's
  // existing CC lines. Cheap at this scale; can become an RPC if it
  // grows.
  const { data: cats } = await supabase
    .from('cc_expense_lines')
    .select('category, batch:cc_expense_batches!inner(org_id)')
    .eq('batch.org_id', org.id)
    .not('category', 'is', null)
    .returns<{ category: string | null }[]>()
  const categoryOptions = Array.from(
    new Set((cats ?? []).map((r) => r.category).filter((c): c is string => !!c)),
  ).sort()

  // Highlight keywords for the org. Each line's description is matched
  // at render time; matched rows get a yellow background.
  const { data: highlightRows } = await supabase
    .from('cc_highlight_keywords')
    .select('keyword')
    .eq('org_id', org.id)
    .returns<{ keyword: string }[]>()
  const highlightKeywords = highlightRows ?? []

  // Reshape line rows to the row component's expected shape.
  const lines: LineForRow[] = (lineRows ?? []).map((l) => ({
    id: l.id,
    batch_id: l.batch_id,
    line_index: l.line_index,
    expense_date: l.expense_date,
    description: l.description,
    amount_usd: l.amount_usd == null ? null : Number(l.amount_usd),
    project_id: l.project_id,
    project_label:
      l.project && l.project.client?.name
        ? `${l.project.client.name} : ${l.project.name}`
        : null,
    assignment_description: l.assignment_description,
    category: l.category,
    auto_assigned: l.auto_assigned,
  }))

  // Stats
  const totalLines = lines.length
  const assigned = lines.filter((l) => l.project_id).length
  const totalAmount = lines.reduce((s, l) => s + (l.amount_usd ?? 0), 0)

  // Build the export block from assigned lines only. Skip any line
  // missing the date (the destination sheet needs it).
  const pasteRows: AssignedCcLineForPaste[] = []
  for (const l of lines) {
    if (!l.project_id || !l.project_label || l.amount_usd == null) continue
    if (!l.expense_date) continue
    const [client, project] = l.project_label.split(' : ', 2)
    pasteRows.push({
      client: client ?? '(no client)',
      project: project ?? '(no project)',
      assignment_description: l.assignment_description ?? '',
      amount_usd: l.amount_usd,
      expense_date: l.expense_date,
      category: l.category ?? '',
    })
  }
  const pasteText = formatCcPasteBlock(pasteRows)

  return (
    <main>
      <div className="page-head">
        <div>
          <p className="muted" style={{ fontSize: '0.85em', margin: 0 }}>
            <Link href="/tools/cc-expenses">← Batches</Link>
          </p>
          <h1 style={{ margin: '0.1rem 0' }}>{batch.name}</h1>
          <p className="muted" style={{ fontSize: '0.9em', margin: '0.1rem 0' }}>
            {totalLines} lines · {assigned} assigned · {fmtUsd(totalAmount)} total
          </p>
        </div>
        <div className="flex-row" style={{ gap: '0.5rem' }}>
          <form action={reapplyRules} style={{ display: 'inline' }}>
            <input type="hidden" name="batch_id" value={batch.id} />
            <button
              type="submit"
              className="secondary"
              title="Scan unassigned lines in this batch against the current auto-assign rules. Assigned lines are not touched."
            >
              Re-apply rules
            </button>
          </form>
          <Link
            href="/tools/cc-expenses/rules"
            className="button-link-secondary"
          >
            Manage rules
          </Link>
        </div>
      </div>

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

      <div className="panel" style={{ marginBottom: '1.25rem' }}>
        <div className="panel-header">
          <h3 style={{ margin: 0, fontSize: '0.95rem' }}>
            Paste lines from your CC statement
          </h3>
        </div>
        <form action={appendCcLines}>
          <input type="hidden" name="batch_id" value={batch.id} />
          <label>
            <span className="muted" style={{ fontSize: '0.85em' }}>
              Tab-separated columns: Date · Description · Amount · (Credit) · Balance.
              Trailing tabs are tolerated. Pastes multiple times — each
              paste appends.
            </span>
            <textarea
              name="paste"
              rows={6}
              placeholder={
                'May 20, 2026\tFACEBK *N7VKLP9RX2\t$7.15\t\t$3,856.56\nMay 18, 2026\tGOOGLE *ADS9772464823\t$750.00\t\t$2,625.41'
              }
              style={{
                width: '100%',
                fontFamily: 'monospace',
                fontSize: '0.85rem',
              }}
            />
          </label>
          <div className="flex-row" style={{ gap: '0.5rem', marginTop: '0.5rem' }}>
            <button type="submit">Add lines</button>
          </div>
        </form>
      </div>

      <div className="panel" style={{ padding: 0, overflow: 'hidden' }}>
        <div
          className="panel-header"
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            gap: '1rem',
          }}
        >
          <h3 style={{ margin: 0, fontSize: '0.95rem' }}>
            Lines{' '}
            <span className="muted" style={{ fontSize: '0.85em' }}>
              ({lines.length})
            </span>
          </h3>
          <span
            className="muted"
            style={{
              fontSize: '0.75em',
              display: 'inline-flex',
              gap: '0.75rem',
              alignItems: 'center',
              flexWrap: 'wrap',
            }}
          >
            <Swatch color="#fef9c3" label="highlight" />
            <Swatch color="#fed7aa" label="auto-matched" />
            <Swatch color="#d1fae5" label="saved" />
          </span>
        </div>
        {lines.length === 0 ? (
          <p className="empty" style={{ padding: '1rem', margin: 0 }}>
            Paste lines above to get started.
          </p>
        ) : (
          <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
            <table className="data">
              <thead>
                <tr>
                  <th>Date</th>
                  <th>Description</th>
                  <th className="num">Amount</th>
                  <th colSpan={4}>
                    Assignment{' '}
                    <span className="muted" style={{ fontSize: '0.78em', fontWeight: 'normal' }}>
                      (Project · Description · Category · Save)
                    </span>
                  </th>
                  <th />
                </tr>
              </thead>
              <tbody>
                {lines.map((line) => (
                  <ExpenseLineRow
                    key={line.id}
                    line={line}
                    projectOptions={projectOptions}
                    categoryOptions={categoryOptions}
                    highlightMatch={findHighlightMatch(
                      line.description,
                      highlightKeywords,
                    )}
                  />
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <div
        className="panel"
        style={{ marginTop: '1.25rem', padding: 0, overflow: 'hidden' }}
      >
        <div className="panel-header">
          <h3 style={{ margin: 0, fontSize: '0.95rem' }}>
            Paste block for the PlusROI sheet
          </h3>
        </div>
        <CcPasteBlock text={pasteText} />
      </div>
    </main>
  )
}

/** Tiny color-swatch + label used in the lines-section legend. */
function Swatch({ color, label }: { color: string; label: string }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: '0.3em' }}>
      <span
        aria-hidden
        style={{
          display: 'inline-block',
          width: '0.85em',
          height: '0.85em',
          background: color,
          borderRadius: 3,
          border: '1px solid #d4d4d4',
        }}
      />
      {label}
    </span>
  )
}
