'use client'

import { useState, useEffect, useCallback } from 'react'
import Box from '@mui/material/Box'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import Typography from '@mui/material/Typography'
import Button from '@mui/material/Button'
import IconButton from '@mui/material/IconButton'
import Chip from '@mui/material/Chip'
import Divider from '@mui/material/Divider'
import Dialog from '@mui/material/Dialog'
import DialogTitle from '@mui/material/DialogTitle'
import DialogContent from '@mui/material/DialogContent'
import DialogActions from '@mui/material/DialogActions'
import TextField from '@mui/material/TextField'
import MenuItem from '@mui/material/MenuItem'
import Alert from '@mui/material/Alert'
import Checkbox from '@mui/material/Checkbox'
import Tooltip from '@mui/material/Tooltip'
import type { ClientFolder, Matter, TimeEntry, Invoice, Expense, ExpenseCategory, PracticeArea, BillingType } from './types'
import MatterWorkflowsPanel from '@/views/workflows/MatterWorkflowsPanel'

// ─── Helpers ──────────────────────────────────────────────────────────────────

function fmtDate(iso?: string) {
  if (!iso) return '—'
  return new Date(iso).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
}
function fmtMoney(n: number, currency = 'THB') {
  return new Intl.NumberFormat('en-TH', { style: 'currency', currency, maximumFractionDigits: 0 }).format(n)
}
function fmtMinutes(m: number) {
  const h = Math.floor(m / 60)
  const min = m % 60
  if (!h) return `${min}m`
  if (!min) return `${h}h`
  return `${h}h ${min}m`
}
function today() {
  return new Date().toISOString().slice(0, 10)
}

// ─── Constants ────────────────────────────────────────────────────────────────

const PRACTICE_AREAS: { value: PracticeArea; label: string }[] = [
  { value: 'immigration',      label: 'Immigration' },
  { value: 'corporate',        label: 'Corporate' },
  { value: 'civil_litigation', label: 'Civil Litigation' },
  { value: 'property',         label: 'Property' },
  { value: 'family',           label: 'Family' },
  { value: 'employment',       label: 'Employment' },
  { value: 'criminal',         label: 'Criminal' },
  { value: 'other',            label: 'Other' },
]

const BILLING_TYPES: { value: BillingType; label: string }[] = [
  { value: 'hourly',      label: 'Hourly' },
  { value: 'fixed',       label: 'Fixed Fee' },
  { value: 'retainer',    label: 'Retainer Draw' },
  { value: 'contingency', label: 'Contingency' },
]

const STATUS_CONFIG: Record<string, { label: string; color: string; bg: string }> = {
  open:     { label: 'Open',     color: '#71DD37', bg: '#EEFBE5' },
  pending:  { label: 'Pending',  color: '#FFB400', bg: '#FFF5DB' },
  closed:   { label: 'Closed',   color: '#8A92A3', bg: '#F0F0F0' },
  archived: { label: 'Archived', color: '#8A92A3', bg: '#F0F0F0' },
}

const INV_STATUS_CONFIG: Record<string, { label: string; color: string; bg: string }> = {
  draft: { label: 'Draft',  color: '#8A92A3', bg: '#F0F0F0' },
  sent:  { label: 'Sent',   color: '#03C3EC', bg: '#E5F9FF' },
  paid:  { label: 'Paid',   color: '#71DD37', bg: '#EEFBE5' },
  void:  { label: 'Void',   color: '#FF4C51', bg: '#FFECEC' },
}

const PA_ICONS: Record<string, string> = {
  immigration:      'ri-passport-line',
  corporate:        'ri-building-4-line',
  civil_litigation: 'ri-scales-3-line',
  property:         'ri-home-2-line',
  family:           'ri-group-line',
  employment:       'ri-briefcase-line',
  criminal:         'ri-police-badge-line',
  other:            'ri-folder-3-line',
}

// ─── Sub-panel: Matter Time Entries ───────────────────────────────────────────

function TimePanel({
  matter,
  clientFolder,
  onInvoiceCreated,
}: {
  matter: Matter
  clientFolder: ClientFolder
  onInvoiceCreated: () => void
}) {
  const [entries, setEntries]         = useState<TimeEntry[]>([])
  const [loading, setLoading]         = useState(false)
  const [selected, setSelected]       = useState<Set<string>>(new Set())
  const [addOpen, setAddOpen]         = useState(false)
  const [generating, setGenerating]   = useState(false)
  const [error, setError]             = useState('')

  // New time entry form
  const [form, setForm] = useState({
    attorney: clientFolder.responsibleAttorney,
    date: today(),
    durationMinutes: '',
    ratePerHour: matter.hourlyRate ? String(matter.hourlyRate) : '5000',
    description: '',
    currency: clientFolder.currency ?? 'THB',
  })

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const r = await fetch(`/api/time-entries?matterId=${matter._id}&limit=100`)
      const data = await r.json()
      setEntries(data.items ?? [])
    } finally { setLoading(false) }
  }, [matter._id])

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

  const unbilled = entries.filter(e => !e.billed)
  const selectedEntries = entries.filter(e => selected.has(e._id))
  const unbilledTotal = unbilled.reduce((s, e) => s + (e.durationMinutes / 60) * e.ratePerHour, 0)
  const selTotal = selectedEntries.reduce((s, e) => s + (e.durationMinutes / 60) * e.ratePerHour, 0)

  function toggleAll() {
    if (selected.size === unbilled.length) {
      setSelected(new Set())
    } else {
      setSelected(new Set(unbilled.map(e => e._id)))
    }
  }
  function toggle(id: string) {
    setSelected(prev => {
      const s = new Set(prev)
      s.has(id) ? s.delete(id) : s.add(id)
      return s
    })
  }

  async function addEntry() {
    setError('')
    if (!form.description.trim()) { setError('Description is required'); return }
    const dur = parseInt(form.durationMinutes)
    if (!dur || dur < 1) { setError('Duration must be at least 1 minute'); return }
    const r = await fetch('/api/time-entries', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        matterId: matter._id,
        clientFolderId: clientFolder._id,
        attorney: form.attorney,
        date: form.date,
        durationMinutes: dur,
        ratePerHour: parseFloat(form.ratePerHour) || 0,
        currency: form.currency,
        description: form.description,
      }),
    })
    if (!r.ok) { setError('Failed to save time entry'); return }
    setAddOpen(false)
    setForm(f => ({ ...f, durationMinutes: '', description: '' }))
    load()
  }

  async function generateInvoice() {
    if (!selected.size) return
    setGenerating(true)
    setError('')
    try {
      const r = await fetch('/api/invoices/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          matterId: matter._id,
          clientFolderId: clientFolder._id,
          timeEntryIds: [...selected],
          createdBy: clientFolder.responsibleAttorney,
        }),
      })
      if (!r.ok) { setError('Invoice generation failed'); return }
      setSelected(new Set())
      load()
      onInvoiceCreated()
    } finally { setGenerating(false) }
  }

  return (
    <Box>
      {/* Header row */}
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1.5 }}>
        <Typography variant='subtitle2' sx={{ fontWeight: 700 }}>Time Entries</Typography>
        <Box sx={{ display: 'flex', gap: 1 }}>
          {selected.size > 0 && (
            <Button
              size='small' variant='contained' color='primary'
              disabled={generating}
              startIcon={<i className='ri-file-text-line' />}
              onClick={generateInvoice}
            >
              {generating ? 'Generating…' : `Invoice ${selected.size} entr${selected.size === 1 ? 'y' : 'ies'} (${fmtMoney(selTotal, form.currency)})`}
            </Button>
          )}
          <Button size='small' variant='outlined' startIcon={<i className='ri-add-line' />} onClick={() => setAddOpen(true)}>
            Log Time
          </Button>
        </Box>
      </Box>

      {error && <Alert severity='error' sx={{ mb: 1.5 }} onClose={() => setError('')}>{error}</Alert>}

      {/* Unbilled summary */}
      {unbilled.length > 0 && (
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 1.5, p: 1.5, bgcolor: '#F8F7FF', borderRadius: 2, border: '1px solid', borderColor: 'divider' }}>
          <Checkbox
            size='small'
            checked={selected.size === unbilled.length && unbilled.length > 0}
            indeterminate={selected.size > 0 && selected.size < unbilled.length}
            onChange={toggleAll}
          />
          <Typography variant='caption' color='text.secondary'>
            {unbilled.length} unbilled {unbilled.length === 1 ? 'entry' : 'entries'} · {fmtMinutes(unbilled.reduce((s, e) => s + e.durationMinutes, 0))} · <strong>{fmtMoney(unbilledTotal, form.currency)}</strong>
          </Typography>
        </Box>
      )}

      {/* Entry list */}
      {loading ? (
        <Typography variant='body2' color='text.disabled' sx={{ py: 2, textAlign: 'center' }}>Loading…</Typography>
      ) : entries.length === 0 ? (
        <Box sx={{ py: 4, textAlign: 'center' }}>
          <i className='ri-timer-line' style={{ fontSize: '2rem', color: 'rgba(128,128,128,0.25)' }} />
          <Typography variant='body2' color='text.disabled' sx={{ mt: 1 }}>No time entries yet</Typography>
        </Box>
      ) : (
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.75 }}>
          {entries.map(e => (
            <Box
              key={e._id}
              sx={{
                display: 'flex', alignItems: 'flex-start', gap: 1.5, p: 1.5,
                borderRadius: 1.5, border: '1px solid', borderColor: 'divider',
                bgcolor: e.billed ? 'action.hover' : 'background.paper',
                opacity: e.billed ? 0.65 : 1,
              }}
            >
              {!e.billed && (
                <Checkbox size='small' checked={selected.has(e._id)} onChange={() => toggle(e._id)} sx={{ mt: -0.25 }} />
              )}
              {e.billed && <Box sx={{ width: 32 }} />}
              <Box sx={{ flex: 1, minWidth: 0 }}>
                <Typography variant='body2' sx={{ fontWeight: 500 }}>{e.description}</Typography>
                <Typography variant='caption' color='text.secondary'>
                  {e.attorney} · {fmtDate(e.date)} · {fmtMinutes(e.durationMinutes)} @ {fmtMoney(e.ratePerHour, e.currency)}/hr
                </Typography>
              </Box>
              <Box sx={{ textAlign: 'right', flexShrink: 0 }}>
                <Typography variant='body2' sx={{ fontWeight: 700, fontFamily: 'monospace' }}>
                  {fmtMoney((e.durationMinutes / 60) * e.ratePerHour, e.currency)}
                </Typography>
                {e.billed && (
                  <Typography variant='caption' color='text.disabled'>{e.invoiceRef ?? 'Billed'}</Typography>
                )}
              </Box>
            </Box>
          ))}
        </Box>
      )}

      {/* Log Time Dialog */}
      <Dialog open={addOpen} onClose={() => setAddOpen(false)} maxWidth='sm' fullWidth>
        <DialogTitle>Log Time</DialogTitle>
        <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: '16px !important' }}>
          <TextField label='Attorney' value={form.attorney} onChange={e => setForm(f => ({ ...f, attorney: e.target.value }))} fullWidth size='small' />
          <TextField label='Date' type='date' value={form.date} onChange={e => setForm(f => ({ ...f, date: e.target.value }))} fullWidth size='small' InputLabelProps={{ shrink: true }} />
          <Box sx={{ display: 'flex', gap: 1.5 }}>
            <TextField
              label='Duration (minutes)' type='number' value={form.durationMinutes}
              onChange={e => setForm(f => ({ ...f, durationMinutes: e.target.value }))}
              fullWidth size='small' placeholder='e.g. 90'
            />
            <TextField
              label='Rate / hour' type='number' value={form.ratePerHour}
              onChange={e => setForm(f => ({ ...f, ratePerHour: e.target.value }))}
              fullWidth size='small'
            />
          </Box>
          <TextField
            label='Description' value={form.description}
            onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
            multiline rows={2} fullWidth size='small'
          />
          {error && <Alert severity='error'>{error}</Alert>}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setAddOpen(false)}>Cancel</Button>
          <Button variant='contained' onClick={addEntry}>Save</Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}

// ─── Sub-panel: Matter Invoices ───────────────────────────────────────────────

function InvoicesPanel({ matterId, currency }: { matterId: string; currency: string }) {
  const [invoices, setInvoices]   = useState<Invoice[]>([])
  const [loading, setLoading]     = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const r = await fetch(`/api/invoices?matterId=${matterId}&limit=50`)
      const data = await r.json()
      setInvoices(data.items ?? [])
    } finally { setLoading(false) }
  }, [matterId])

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

  async function action(id: string, path: string, body?: object) {
    await fetch(`/api/invoices/${id}/${path}`, {
      method: 'POST',
      headers: body ? { 'Content-Type': 'application/json' } : {},
      body: body ? JSON.stringify(body) : undefined,
    })
    load()
  }

  if (loading) return <Typography variant='body2' color='text.disabled' sx={{ py: 2, textAlign: 'center' }}>Loading…</Typography>

  if (!invoices.length) return (
    <Typography variant='body2' color='text.disabled' sx={{ py: 2, textAlign: 'center' }}>
      No invoices yet — log time and use "Invoice entries" to generate one.
    </Typography>
  )

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
      {invoices.map(inv => {
        const cfg = INV_STATUS_CONFIG[inv.status]
        return (
          <Box key={inv._id} sx={{ p: 1.5, border: '1px solid', borderColor: 'divider', borderRadius: 1.5, display: 'flex', alignItems: 'center', gap: 2 }}>
            <Box sx={{ flex: 1, minWidth: 0 }}>
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.25 }}>
                <Typography variant='body2' sx={{ fontFamily: 'monospace', fontWeight: 700 }}>{inv.invoiceNumber}</Typography>
                <Chip label={cfg.label} size='small' sx={{ bgcolor: cfg.bg, color: cfg.color, fontWeight: 600, height: 20, fontSize: '0.7rem' }} />
              </Box>
              <Typography variant='caption' color='text.secondary'>
                Issued {fmtDate(inv.issueDate)} · Due {fmtDate(inv.dueDate)} · {inv.lineItems.length} line{inv.lineItems.length !== 1 ? 's' : ''}
              </Typography>
            </Box>
            <Box sx={{ textAlign: 'right', flexShrink: 0 }}>
              <Typography variant='body2' sx={{ fontWeight: 700, fontFamily: 'monospace' }}>{fmtMoney(inv.total, inv.currency)}</Typography>
              {inv.vatRate > 0 && (
                <Typography variant='caption' color='text.secondary'>{(inv.vatRate * 100).toFixed(0)}% VAT incl.</Typography>
              )}
            </Box>
            <Box sx={{ display: 'flex', gap: 0.5, flexShrink: 0 }}>
              {inv.status === 'draft' && (
                <Tooltip title='Mark Sent'>
                  <IconButton size='small' onClick={() => action(inv._id, 'send')}>
                    <i className='ri-send-plane-line' style={{ fontSize: '1rem' }} />
                  </IconButton>
                </Tooltip>
              )}
              {(inv.status === 'draft' || inv.status === 'sent') && (
                <Tooltip title='Mark Paid'>
                  <IconButton size='small' onClick={() => action(inv._id, 'pay', { paidAmount: inv.total })}>
                    <i className='ri-checkbox-circle-line' style={{ fontSize: '1rem', color: '#71DD37' }} />
                  </IconButton>
                </Tooltip>
              )}
              {inv.status !== 'paid' && inv.status !== 'void' && (
                <Tooltip title='Void Invoice'>
                  <IconButton size='small' onClick={() => action(inv._id, 'void')}>
                    <i className='ri-close-circle-line' style={{ fontSize: '1rem', color: '#FF4C51' }} />
                  </IconButton>
                </Tooltip>
              )}
              <Tooltip title='Download PDF'>
                <IconButton size='small' component='a' href={`/api/invoices/${inv._id}/pdf`} target='_blank'>
                  <i className='ri-file-pdf-2-line' style={{ fontSize: '1rem', color: '#FF4C51' }} />
                </IconButton>
              </Tooltip>
            </Box>
          </Box>
        )
      })}
    </Box>
  )
}

// ─── Sub-panel: Expenses ─────────────────────────────────────────────────────

const EXPENSE_CATEGORIES: { value: ExpenseCategory; label: string }[] = [
  { value: 'court_filing',    label: 'Court Filing' },
  { value: 'translation',     label: 'Translation' },
  { value: 'notarization',    label: 'Notarization' },
  { value: 'travel',          label: 'Travel' },
  { value: 'accommodation',   label: 'Accommodation' },
  { value: 'courier',         label: 'Courier' },
  { value: 'printing',        label: 'Printing' },
  { value: 'government_fee',  label: 'Government Fee' },
  { value: 'expert_witness',  label: 'Expert Witness' },
  { value: 'other',           label: 'Other' },
]

function ExpensesPanel({ matterId, clientFolderId, currency }: { matterId: string; clientFolderId: string; currency: string }) {
  const [expenses, setExpenses]   = useState<Expense[]>([])
  const [loading, setLoading]     = useState(false)
  const [addOpen, setAddOpen]     = useState(false)
  const [error, setError]         = useState('')
  const [selected, setSelected]   = useState<Set<string>>(new Set())
  const [form, setForm]           = useState({
    description: '', category: 'other' as ExpenseCategory, amount: '',
    expenseDate: new Date().toISOString().slice(0, 10), billable: true,
    notes: '', createdBy: 'Counsel',
  })

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const r = await fetch(`/api/expenses?matterId=${matterId}&limit=100`)
      const data = await r.json()
      setExpenses(Array.isArray(data) ? data : [])
    } finally { setLoading(false) }
  }, [matterId])

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

  async function addExpense() {
    if (!form.description || !form.amount) { setError('Description and amount are required'); return }
    setError('')
    const r = await fetch('/api/expenses', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ...form, amount: parseFloat(form.amount), matterId, clientFolderId, currency }),
    })
    if (!r.ok) { const d = await r.json(); setError(d.message ?? 'Failed'); return }
    setAddOpen(false)
    setForm(f => ({ ...f, description: '', amount: '', notes: '' }))
    load()
  }

  async function deleteExpense(id: string) {
    await fetch(`/api/expenses/${id}`, { method: 'DELETE' })
    setSelected(s => { const n = new Set(s); n.delete(id); return n })
    load()
  }

  const toggle = (id: string) => setSelected(s => {
    const n = new Set(s)
    n.has(id) ? n.delete(id) : n.add(id)
    return n
  })

  const selTotal = [...selected].reduce((s, id) => {
    const e = expenses.find(x => x._id === id)
    return s + (e?.amount ?? 0)
  }, 0)
  const [generating, setGenerating] = useState(false)

  async function invoiceExpenses() {
    if (!selected.size) return
    setGenerating(true)
    setError('')
    try {
      const r = await fetch('/api/invoices/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          matterId, clientFolderId,
          timeEntryIds: [],
          expenseIds: [...selected],
          createdBy: 'Counsel',
        }),
      })
      if (!r.ok) { const d = await r.json(); setError(d.message ?? 'Invoice generation failed'); return }
      setSelected(new Set())
      load()
    } finally { setGenerating(false) }
  }

  return (
    <Box>
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1.5 }}>
        <Typography variant='subtitle2' sx={{ fontWeight: 700 }}>Disbursements & Expenses</Typography>
        <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
          {selected.size > 0 && (
            <Button
              size='small' variant='contained' color='primary'
              disabled={generating}
              startIcon={<i className='ri-file-text-line' />}
              onClick={invoiceExpenses}
            >
              {generating ? 'Generating…' : `Invoice ${selected.size} expense${selected.size !== 1 ? 's' : ''} (${fmtMoney(selTotal, currency)})`}
            </Button>
          )}
          <Button size='small' variant='outlined' startIcon={<i className='ri-add-line' />} onClick={() => setAddOpen(true)}>
            Add Expense
          </Button>
        </Box>
      </Box>

      {error && <Alert severity='error' sx={{ mb: 1.5 }} onClose={() => setError('')}>{error}</Alert>}

      {loading ? (
        <Typography variant='body2' color='text.disabled' sx={{ py: 2, textAlign: 'center' }}>Loading…</Typography>
      ) : expenses.length === 0 ? (
        <Box sx={{ py: 3, textAlign: 'center' }}>
          <i className='ri-receipt-line' style={{ fontSize: '1.75rem', color: 'rgba(128,128,128,0.25)' }} />
          <Typography variant='body2' color='text.disabled' sx={{ mt: 0.5 }}>No expenses recorded</Typography>
        </Box>
      ) : (
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.75 }}>
          {expenses.map(exp => {
            const cat = EXPENSE_CATEGORIES.find(c => c.value === exp.category)
            const isPending = exp.status === 'pending'
            return (
              <Box
                key={exp._id}
                sx={{
                  display: 'flex', alignItems: 'center', gap: 1.5, p: 1.25,
                  borderRadius: 1.5, border: '1px solid', borderColor: 'divider',
                  bgcolor: isPending ? 'background.paper' : 'action.hover',
                  opacity: exp.status === 'billed' ? 0.65 : 1,
                }}
              >
                {isPending && exp.billable && (
                  <Checkbox size='small' checked={selected.has(exp._id)} onChange={() => toggle(exp._id)} sx={{ p: 0.5 }} />
                )}
                {(!isPending || !exp.billable) && <Box sx={{ width: 32 }} />}
                <Box sx={{ flex: 1, minWidth: 0 }}>
                  <Typography variant='body2' sx={{ fontWeight: 500 }}>{exp.description}</Typography>
                  <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mt: 0.25 }}>
                    <Typography variant='caption' color='text.secondary'>
                      {cat?.label ?? exp.category} · {new Date(exp.expenseDate).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })}
                    </Typography>
                    {!exp.billable && <Chip label='Non-billable' size='small' sx={{ height: 16, fontSize: '0.65rem', bgcolor: '#F3F4F6' }} />}
                    {exp.status !== 'pending' && (
                      <Chip
                        label={exp.status.charAt(0).toUpperCase() + exp.status.slice(1)}
                        size='small'
                        sx={{ height: 16, fontSize: '0.65rem', bgcolor: exp.status === 'billed' ? '#E8F4FD' : '#EEFBE5', color: exp.status === 'billed' ? '#0D9394' : '#71DD37' }}
                      />
                    )}
                  </Box>
                </Box>
                <Typography variant='body2' sx={{ fontWeight: 700, fontFamily: 'monospace', flexShrink: 0 }}>
                  {fmtMoney(exp.amount, exp.currency)}
                </Typography>
                {isPending && (
                  <Tooltip title='Delete'>
                    <IconButton size='small' onClick={() => deleteExpense(exp._id)}>
                      <i className='ri-delete-bin-line' style={{ fontSize: '0.85rem', color: '#FF4C51' }} />
                    </IconButton>
                  </Tooltip>
                )}
              </Box>
            )
          })}
        </Box>
      )}

      {/* Add Expense Dialog */}
      <Dialog open={addOpen} onClose={() => setAddOpen(false)} maxWidth='sm' fullWidth>
        <DialogTitle>Add Expense / Disbursement</DialogTitle>
        <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: '16px !important' }}>
          <TextField
            label='Description' value={form.description}
            onChange={e => setForm(f => ({ ...f, description: e.target.value }))}
            fullWidth size='small'
          />
          <Box sx={{ display: 'flex', gap: 1.5 }}>
            <TextField
              select label='Category' value={form.category}
              onChange={e => setForm(f => ({ ...f, category: e.target.value as ExpenseCategory }))}
              fullWidth size='small'
            >
              {EXPENSE_CATEGORIES.map(c => <MenuItem key={c.value} value={c.value}>{c.label}</MenuItem>)}
            </TextField>
            <TextField
              label='Amount' type='number' value={form.amount}
              onChange={e => setForm(f => ({ ...f, amount: e.target.value }))}
              fullWidth size='small' inputProps={{ min: 0, step: 0.01 }}
            />
          </Box>
          <TextField
            label='Date' type='date' value={form.expenseDate}
            onChange={e => setForm(f => ({ ...f, expenseDate: e.target.value }))}
            fullWidth size='small' InputLabelProps={{ shrink: true }}
          />
          <TextField
            select label='Billable to Client' value={form.billable ? 'yes' : 'no'}
            onChange={e => setForm(f => ({ ...f, billable: e.target.value === 'yes' }))}
            fullWidth size='small'
          >
            <MenuItem value='yes'>Yes — include in invoice</MenuItem>
            <MenuItem value='no'>No — internal / absorbed</MenuItem>
          </TextField>
          <TextField
            label='Notes (optional)' value={form.notes}
            onChange={e => setForm(f => ({ ...f, notes: e.target.value }))}
            multiline rows={2} fullWidth size='small'
          />
          {error && <Alert severity='error'>{error}</Alert>}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setAddOpen(false)}>Cancel</Button>
          <Button variant='contained' onClick={addExpense}>Save</Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}

// ─── Matter Detail Panel ──────────────────────────────────────────────────────

function MatterPanel({ matter, clientFolder, onClose }: { matter: Matter; clientFolder: ClientFolder; onClose: () => void }) {
  const [invoiceRefresh, setInvoiceRefresh] = useState(0)

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
      {/* Header */}
      <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1.5 }}>
        <IconButton size='small' onClick={onClose} sx={{ mt: 0.25 }}>
          <i className='ri-arrow-left-line' style={{ fontSize: '1rem' }} />
        </IconButton>
        <Box sx={{ flex: 1 }}>
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
            <Typography variant='caption' sx={{ fontFamily: 'monospace', color: '#0D9394', fontWeight: 700 }}>{matter.matterNumber}</Typography>
            <Chip
              label={STATUS_CONFIG[matter.status]?.label ?? matter.status}
              size='small'
              sx={{
                bgcolor: STATUS_CONFIG[matter.status]?.bg ?? '#F0F0F0',
                color: STATUS_CONFIG[matter.status]?.color ?? '#8A92A3',
                fontWeight: 600, height: 20, fontSize: '0.7rem',
              }}
            />
          </Box>
          <Typography variant='h6' sx={{ fontWeight: 700, lineHeight: 1.3 }}>{matter.title}</Typography>
          <Typography variant='caption' color='text.secondary'>
            {PRACTICE_AREAS.find(p => p.value === matter.practiceArea)?.label ?? matter.practiceArea}
            {matter.courtReference && ` · Court ref: ${matter.courtReference}`}
            {matter.responsibleAttorney && ` · ${matter.responsibleAttorney}`}
          </Typography>
        </Box>
      </Box>

      {/* Billing summary */}
      <Box sx={{ display: 'flex', gap: 1.5, flexWrap: 'wrap' }}>
        {[
          { label: 'Total Billed', value: fmtMoney(matter.totalBilled, matter.currency) },
          { label: 'Total Paid',   value: fmtMoney(matter.totalPaid, matter.currency) },
          { label: 'Balance Due',  value: fmtMoney(matter.totalBilled - matter.totalPaid, matter.currency) },
        ].map(s => (
          <Box key={s.label} sx={{ flex: '1 1 120px', p: 1.5, border: '1px solid', borderColor: 'divider', borderRadius: 2, textAlign: 'center' }}>
            <Typography variant='caption' color='text.secondary' display='block'>{s.label}</Typography>
            <Typography variant='subtitle2' sx={{ fontWeight: 700, fontFamily: 'monospace' }}>{s.value}</Typography>
          </Box>
        ))}
      </Box>

      {/* Notes */}
      {matter.notes && (
        <Box sx={{ p: 1.5, bgcolor: 'action.hover', borderRadius: 1.5 }}>
          <Typography variant='body2'>{matter.notes}</Typography>
        </Box>
      )}

      <Divider />

      {/* Time entries */}
      <TimePanel
        matter={matter}
        clientFolder={clientFolder}
        onInvoiceCreated={() => setInvoiceRefresh(n => n + 1)}
      />

      <Divider />

      {/* Expenses */}
      <ExpensesPanel matterId={matter._id} clientFolderId={clientFolder._id} currency={matter.currency} />

      <Divider />

      {/* Invoices */}
      <Box>
        <Typography variant='subtitle2' sx={{ fontWeight: 700, mb: 1.5 }}>Invoices</Typography>
        <InvoicesPanel key={invoiceRefresh} matterId={matter._id} currency={matter.currency} />
      </Box>

      <Divider />

      {/* Workflows & Obligation Timeline */}
      <MatterWorkflowsPanel matterId={matter._id} practiceArea={matter.practiceArea} />

    </Box>
  )
}

// ─── Create Matter Dialog ─────────────────────────────────────────────────────

function CreateMatterDialog({
  open,
  clientFolder,
  onClose,
  onCreated,
}: {
  open: boolean
  clientFolder: ClientFolder
  onClose: () => void
  onCreated: (m: Matter) => void
}) {
  const [form, setForm] = useState({
    title: '',
    practiceArea: 'immigration' as PracticeArea,
    billingType: 'hourly' as BillingType,
    hourlyRate: '5000',
    fixedFee: '',
    responsibleAttorney: clientFolder.responsibleAttorney,
    courtReference: '',
    notes: '',
  })
  const [error, setError] = useState('')
  const [saving, setSaving] = useState(false)

  async function submit() {
    setError('')
    if (!form.title.trim()) { setError('Title is required'); return }
    setSaving(true)
    try {
      const body: Record<string, unknown> = {
        clientFolderId: clientFolder._id,
        title: form.title,
        practiceArea: form.practiceArea,
        billingType: form.billingType,
        responsibleAttorney: form.responsibleAttorney,
        currency: clientFolder.currency ?? 'THB',
      }
      if (form.billingType === 'hourly' && form.hourlyRate) body.hourlyRate = parseFloat(form.hourlyRate)
      if (form.billingType === 'fixed' && form.fixedFee) body.fixedFee = parseFloat(form.fixedFee)
      if (form.courtReference) body.courtReference = form.courtReference
      if (form.notes) body.notes = form.notes

      const r = await fetch('/api/matters', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      })
      if (!r.ok) { const d = await r.json(); setError(d.message ?? 'Failed to create matter'); return }
      const matter = await r.json()
      onCreated(matter)
    } finally { setSaving(false) }
  }

  function set(k: string) {
    return (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
      setForm(f => ({ ...f, [k]: e.target.value }))
  }

  return (
    <Dialog open={open} onClose={onClose} maxWidth='sm' fullWidth>
      <DialogTitle>New Matter</DialogTitle>
      <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: '16px !important' }}>
        <TextField label='Matter Title' value={form.title} onChange={set('title')} fullWidth size='small' placeholder='e.g. TM.7 Extension — James Smith' />
        <TextField select label='Practice Area' value={form.practiceArea} onChange={set('practiceArea')} fullWidth size='small'>
          {PRACTICE_AREAS.map(p => <MenuItem key={p.value} value={p.value}>{p.label}</MenuItem>)}
        </TextField>
        <TextField label='Responsible Attorney' value={form.responsibleAttorney} onChange={set('responsibleAttorney')} fullWidth size='small' />
        <TextField select label='Billing Type' value={form.billingType} onChange={set('billingType')} fullWidth size='small'>
          {BILLING_TYPES.map(b => <MenuItem key={b.value} value={b.value}>{b.label}</MenuItem>)}
        </TextField>
        {form.billingType === 'hourly' && (
          <TextField label='Hourly Rate (THB)' type='number' value={form.hourlyRate} onChange={set('hourlyRate')} fullWidth size='small' />
        )}
        {form.billingType === 'fixed' && (
          <TextField label='Fixed Fee (THB)' type='number' value={form.fixedFee} onChange={set('fixedFee')} fullWidth size='small' />
        )}
        <TextField label='Court Reference (optional)' value={form.courtReference} onChange={set('courtReference')} fullWidth size='small' />
        <TextField label='Notes (optional)' value={form.notes} onChange={set('notes')} multiline rows={2} fullWidth size='small' />
        {error && <Alert severity='error'>{error}</Alert>}
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Cancel</Button>
        <Button variant='contained' onClick={submit} disabled={saving}>{saving ? 'Creating…' : 'Create Matter'}</Button>
      </DialogActions>
    </Dialog>
  )
}

// ─── Main Component ───────────────────────────────────────────────────────────

export default function MattersTab({
  clientFolder,
  onUpdate,
}: {
  clientFolder: ClientFolder
  onUpdate?: (updated: Partial<ClientFolder>) => void
}) {
  const [matters, setMatters]       = useState<Matter[]>([])
  const [loading, setLoading]       = useState(true)
  const [selected, setSelected]     = useState<Matter | null>(null)
  const [createOpen, setCreateOpen] = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const r = await fetch(`/api/matters?clientFolderId=${clientFolder._id}&limit=50`)
      const data = await r.json()
      setMatters(data.items ?? [])
    } finally { setLoading(false) }
  }, [clientFolder._id])

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

  function handleCreated(m: Matter) {
    setMatters(prev => [m, ...prev])
    setCreateOpen(false)
    setSelected(m)
  }

  // Detail view
  if (selected) {
    return (
      <Card>
        <CardContent>
          <MatterPanel
            matter={matters.find(m => m._id === selected._id) ?? selected}
            clientFolder={clientFolder}
            onClose={() => setSelected(null)}
          />
        </CardContent>
      </Card>
    )
  }

  // List view
  return (
    <>
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
        <Typography variant='h6' sx={{ fontWeight: 700 }}>Matters</Typography>
        <Button
          variant='contained' size='small'
          startIcon={<i className='ri-add-line' />}
          onClick={() => setCreateOpen(true)}
        >
          New Matter
        </Button>
      </Box>

      {loading ? (
        <Typography variant='body2' color='text.disabled' sx={{ py: 4, textAlign: 'center' }}>Loading…</Typography>
      ) : matters.length === 0 ? (
        <Card sx={{ border: '1px dashed', borderColor: 'divider' }}>
          <CardContent sx={{ py: 5, textAlign: 'center' }}>
            <i className='ri-briefcase-line' style={{ fontSize: '2.5rem', color: 'rgba(128,128,128,0.25)' }} />
            <Typography variant='body2' color='text.disabled' sx={{ mt: 1.5, fontWeight: 500 }}>No matters yet</Typography>
            <Typography variant='caption' color='text.disabled'>Create a matter to start tracking time, hearings, and billing for this client.</Typography>
            <Box sx={{ mt: 2 }}>
              <Button variant='outlined' size='small' startIcon={<i className='ri-add-line' />} onClick={() => setCreateOpen(true)}>
                Create First Matter
              </Button>
            </Box>
          </CardContent>
        </Card>
      ) : (
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
          {matters.map(m => {
            const paIcon = PA_ICONS[m.practiceArea] ?? 'ri-folder-3-line'
            const sc = STATUS_CONFIG[m.status] ?? STATUS_CONFIG.open

            return (
              <Card
                key={m._id}
                sx={{ cursor: 'pointer', '&:hover': { boxShadow: 3 }, transition: 'box-shadow 0.15s' }}
                onClick={() => setSelected(m)}
              >
                <CardContent sx={{ py: 1.75, '&:last-child': { pb: 1.75 } }}>
                  <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1.5 }}>
                    <Box sx={{ width: 40, height: 40, borderRadius: 2, bgcolor: 'action.hover', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                      <i className={paIcon} style={{ fontSize: '1.25rem', color: '#7C6AF7' }} />
                    </Box>
                    <Box sx={{ flex: 1, minWidth: 0 }}>
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
                        <Typography variant='caption' sx={{ fontFamily: 'monospace', color: '#0D9394', fontWeight: 700 }}>{m.matterNumber}</Typography>
                        <Chip
                          label={sc.label}
                          size='small'
                          sx={{ bgcolor: sc.bg, color: sc.color, fontWeight: 600, height: 20, fontSize: '0.7rem' }}
                        />
                        {m.courtReference && (
                          <Typography variant='caption' color='text.disabled'>· {m.courtReference}</Typography>
                        )}
                      </Box>
                      <Typography variant='body1' sx={{ fontWeight: 600, lineHeight: 1.4 }}>{m.title}</Typography>
                      <Typography variant='caption' color='text.secondary'>
                        {PRACTICE_AREAS.find(p => p.value === m.practiceArea)?.label ?? m.practiceArea}
                        {' · '}{m.responsibleAttorney}
                        {m.openedDate && ` · Opened ${fmtDate(m.openedDate)}`}
                      </Typography>
                    </Box>
                    <Box sx={{ textAlign: 'right', flexShrink: 0 }}>
                      {m.totalBilled > 0 && (
                        <Typography variant='body2' sx={{ fontFamily: 'monospace', fontWeight: 700 }}>
                          {fmtMoney(m.totalBilled, m.currency)}
                        </Typography>
                      )}
                      <i className='ri-arrow-right-s-line' style={{ color: 'rgba(128,128,128,0.4)' }} />
                    </Box>
                  </Box>
                </CardContent>
              </Card>
            )
          })}
        </Box>
      )}

      <CreateMatterDialog
        open={createOpen}
        clientFolder={clientFolder}
        onClose={() => setCreateOpen(false)}
        onCreated={handleCreated}
      />
    </>
  )
}
