'use client'

import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
  BookOpen, CheckCircle2, CircleSlash, FileCheck, FilePlus2, History,
  Loader2, Pencil, Plus, RefreshCcw, Save, Search, Send, ShieldCheck, Trash2,
} from 'lucide-react'

import { useAuth } from '@/contexts/auth-context'
import { Button } from '@/components/ui/button'
import { DataTable, type Column } from '@/components/ui/data-table'
import { KpiCard } from '@/components/ui/kpi-card'
import { Modal } from '@/components/ui/modal'
import { PageHeader } from '@/components/ui/page-header'
import { SearchableSelectField, type SearchableSelectOption } from '@/components/ui/searchable-select-field'
import { SectionCard } from '@/components/ui/section-card'
import { StatusBadge, type StatusTone } from '@/components/ui/status-badge'
import { ENDPOINTS } from '@/constants/endpoints'
import type { JournalHeaderRead, JournalLineRead } from '@/hooks/useLedger'
import { api } from '@/lib/api'
import { formatDateTime } from '@/lib/format'

type Account = { id: string; code: string; name_ar?: string; name_en?: string; allow_posting: boolean; is_active: boolean }
type Currency = { id: string; code: string; name_ar?: string; name_en?: string }
type Audit = { id: string; action: string; actor_user_id?: string | null; old_values?: Record<string, unknown>; new_values?: Record<string, unknown>; created_at: string }
type DraftLine = { account_id: string; entry_type: 'debit' | 'credit'; amount: string; currency_id: string; description: string }

const emptyLine = (entry_type: 'debit' | 'credit' = 'debit'): DraftLine => ({ account_id: '', entry_type, amount: '', currency_id: '', description: '' })
const unpack = <T,>(response: any): T => (response?.data?.data ?? response?.data ?? response) as T
const amount = (value: string | number | null | undefined) => Number(value || 0)

export default function LedgerPage() {
  const { i18n } = useTranslation()
  const ar = i18n.language?.startsWith('ar')
  const { user } = useAuth()
  const [journals, setJournals] = useState<JournalHeaderRead[]>([])
  const [selectedId, setSelectedId] = useState<string | null>(null)
  const [accounts, setAccounts] = useState<Account[]>([])
  const [currencies, setCurrencies] = useState<Currency[]>([])
  const [audits, setAudits] = useState<Audit[]>([])
  const [loading, setLoading] = useState(true)
  const [busy, setBusy] = useState(false)
  const [createOpen, setCreateOpen] = useState(false)
  const [query, setQuery] = useState('')
  const [statusFilter, setStatusFilter] = useState('')
  const [sourceFilter, setSourceFilter] = useState('')
  const [editHeader, setEditHeader] = useState({ journal_date: '', description: '' })
  const [newLine, setNewLine] = useState<DraftLine>(emptyLine())
  const [editingLine, setEditingLine] = useState<JournalLineRead | null>(null)
  const [editLineForm, setEditLineForm] = useState<DraftLine>(emptyLine())
  const [createForm, setCreateForm] = useState({ journal_date: new Date().toISOString().slice(0, 10), description: '', source: 'manual', lines: [emptyLine('debit'), emptyLine('credit')] })

  const text = ar ? {
    title: 'القيود اليومية والترحيل', description: 'إنشاء القيود ومراجعة توازنها واعتمادها وترحيلها وعكسها.', journals: 'قائمة القيود', create: 'قيد جديد',
    search: 'ابحث برقم القيد أو البيان أو المرجع', allStatus: 'كل الحالات', allSources: 'كل المصادر', number: 'رقم القيد', date: 'التاريخ', source: 'المصدر', status: 'الحالة', descriptionLabel: 'البيان',
    total: 'إجمالي القيود', drafts: 'المسودات', awaiting: 'بانتظار الاعتماد', posted: 'مرحلة', details: 'تفاصيل القيد', select: 'اختر قيداً لعرض تفاصيله.', lines: 'سطور القيد', account: 'الحساب', debit: 'مدين', credit: 'دائن', currency: 'العملة', actions: 'الإجراءات',
    balance: 'معاينة التوازن', balanced: 'القيد متوازن', unbalanced: 'القيد غير متوازن', addLine: 'إضافة سطر', saveHeader: 'حفظ البيانات', validate: 'فحص', submit: 'إرسال للاعتماد', approve: 'اعتماد', post: 'ترحيل', cancel: 'إلغاء', reverse: 'عكس', audit: 'سجل التدقيق', noAudit: 'لا توجد أحداث تدقيق.',
    draft: 'مسودة', validated: 'تم الفحص', pending_approval: 'بانتظار الاعتماد', approved: 'معتمد', reversed: 'معكوس', cancelled: 'ملغي', createHelp: 'أدخل رأس القيد وسطرين على الأقل. يجب أن يتساوى المدين والدائن لكل عملة.', add: 'إضافة', close: 'إغلاق', reason: 'اكتب سبب العكس', confirmPost: 'الترحيل يجعل القيد غير قابل للتعديل. هل تريد المتابعة؟',
  } : {
    title: 'Journals and posting', description: 'Create, balance, approve, post, and reverse journal entries.', journals: 'Journal list', create: 'New journal',
    search: 'Search number, description, or reference', allStatus: 'All statuses', allSources: 'All sources', number: 'Journal number', date: 'Date', source: 'Source', status: 'Status', descriptionLabel: 'Description',
    total: 'Total journals', drafts: 'Drafts', awaiting: 'Awaiting approval', posted: 'Posted', details: 'Journal details', select: 'Select a journal to inspect it.', lines: 'Journal lines', account: 'Account', debit: 'Debit', credit: 'Credit', currency: 'Currency', actions: 'Actions',
    balance: 'Posting preview', balanced: 'Journal is balanced', unbalanced: 'Journal is not balanced', addLine: 'Add line', saveHeader: 'Save details', validate: 'Validate', submit: 'Submit for approval', approve: 'Approve', post: 'Post', cancel: 'Cancel', reverse: 'Reverse', audit: 'Audit history', noAudit: 'No audit events.',
    draft: 'Draft', validated: 'Validated', pending_approval: 'Pending approval', approved: 'Approved', reversed: 'Reversed', cancelled: 'Cancelled', createHelp: 'Enter the journal header and at least two lines. Debit and credit must balance per currency.', add: 'Add', close: 'Close', reason: 'Enter the reversal reason', confirmPost: 'Posting makes the journal immutable. Continue?',
  }

  const roleCodes = new Set(user?.roles?.map((role) => typeof role === 'string' ? role : role.code) || [])
  const manager = user?.user_type === 'admin' || roleCodes.has('super_admin')
  const permissions = new Set(user?.permissions || [])
  const can = (permission: string) => manager || permissions.has(permission)

  const loadJournals = useCallback(async () => {
    setLoading(true)
    try {
      const response = await api.get(ENDPOINTS.LEDGER.LIST, { params: { limit: 500, status: statusFilter || undefined, source: sourceFilter || undefined } })
      const list = unpack<JournalHeaderRead[]>(response)
      setJournals(Array.isArray(list) ? list : [])
    } finally { setLoading(false) }
  }, [statusFilter, sourceFilter])

  useEffect(() => { loadJournals() }, [loadJournals])
  useEffect(() => {
    Promise.all([
      api.get(ENDPOINTS.ACCOUNTS.POSTING, { params: { limit: 500 } }).catch(() => []),
      api.get(ENDPOINTS.CURRENCIES.LIST, { params: { limit: 200 } }).catch(() => []),
    ]).then(([accountResponse, currencyResponse]) => {
      const accountList = unpack<Account[]>(accountResponse)
      const currencyList = unpack<Currency[]>(currencyResponse)
      setAccounts(Array.isArray(accountList) ? accountList : [])
      setCurrencies(Array.isArray(currencyList) ? currencyList : [])
    })
  }, [])

  const selected = journals.find((journal) => journal.id === selectedId) || null
  useEffect(() => {
    if (!selected) { setAudits([]); return }
    setEditHeader({ journal_date: selected.journal_date || '', description: selected.description || '' })
    api.get(ENDPOINTS.LEDGER.AUDIT(selected.id)).then((response) => {
      const list = unpack<Audit[]>(response); setAudits(Array.isArray(list) ? list : [])
    }).catch(() => setAudits([]))
  }, [selected?.id, selected?.updated_at])

  const accountOptions: SearchableSelectOption[] = accounts.map((account) => ({ value: account.id, label: `${account.code} · ${ar ? account.name_ar || account.name_en : account.name_en || account.name_ar}`, description: account.allow_posting ? undefined : 'Not postable' }))
  const accountName = (id: string) => { const account = accounts.find((item) => item.id === id); return account ? `${account.code} · ${ar ? account.name_ar || account.name_en : account.name_en || account.name_ar}` : id }
  const currencyCode = (id?: string | null) => currencies.find((item) => item.id === id)?.code || (id ? id.slice(0, 8) : '-')
  const editText = ar ? 'تعديل' : 'Edit'
  const saveLineText = ar ? 'حفظ السطر' : 'Save line'

  const filtered = useMemo(() => {
    const needle = query.trim().toLowerCase()
    if (!needle) return journals
    return journals.filter((journal) => [journal.journal_number, journal.description, journal.reference_type, journal.source].filter(Boolean).join(' ').toLowerCase().includes(needle))
  }, [journals, query])

  const statusMeta: Record<string, { label: string; tone: StatusTone }> = {
    draft: { label: text.draft, tone: 'neutral' }, validated: { label: text.validated, tone: 'info' }, pending_approval: { label: text.pending_approval, tone: 'warning' }, approved: { label: text.approved, tone: 'success' }, posted: { label: text.posted, tone: 'success' }, reversed: { label: text.reversed, tone: 'danger' }, cancelled: { label: text.cancelled, tone: 'neutral' },
  }

  const columns: Column<JournalHeaderRead>[] = [
    { key: 'number', header: text.number, cell: (row) => <span className="font-mono text-xs font-semibold">{row.journal_number}</span> },
    { key: 'date', header: text.date, cell: (row) => <span className="text-xs">{row.journal_date}</span> },
    { key: 'source', header: text.source, cell: (row) => <span className="text-xs">{row.source}</span> },
    { key: 'description', header: text.descriptionLabel, cell: (row) => <span className="block max-w-64 truncate text-xs text-muted-foreground">{row.description || '-'}</span> },
    { key: 'status', header: text.status, cell: (row) => <StatusBadge tone={statusMeta[row.status]?.tone || 'neutral'} size="sm">{statusMeta[row.status]?.label || row.status}</StatusBadge> },
  ]

  const runAction = async (endpoint: string, body?: unknown, confirmation?: string) => {
    if (confirmation && !window.confirm(confirmation)) return
    setBusy(true)
    try { await api.post(endpoint, body); toast.success(ar ? 'تم تنفيذ الإجراء.' : 'Action completed.'); await loadJournals() }
    finally { setBusy(false) }
  }

  const createJournal = async () => {
    if (createForm.lines.length < 2 || createForm.lines.some((line) => !line.account_id || !line.amount)) return
    setBusy(true)
    try {
      const headerResponse = await api.post(ENDPOINTS.LEDGER.CREATE, { journal_date: createForm.journal_date, description: createForm.description || null, source: createForm.source })
      const header = unpack<JournalHeaderRead>(headerResponse)
      await api.post(ENDPOINTS.LEDGER.LINES(header.id), { lines: createForm.lines.map((line, index) => ({ line_order: index + 1, entry_type: line.entry_type, account_id: line.account_id, amount: line.amount, currency_id: line.currency_id || null, description: line.description || null })) })
      setCreateOpen(false); setCreateForm({ journal_date: new Date().toISOString().slice(0, 10), description: '', source: 'manual', lines: [emptyLine('debit'), emptyLine('credit')] })
      await loadJournals(); setSelectedId(header.id); toast.success(ar ? 'تم إنشاء القيد.' : 'Journal created.')
    } finally { setBusy(false) }
  }

  const saveHeader = async () => {
    if (!selected) return
    setBusy(true)
    try { await api.patch(ENDPOINTS.LEDGER.UPDATE(selected.id), editHeader); await loadJournals(); toast.success(ar ? 'تم حفظ القيد.' : 'Journal saved.') }
    finally { setBusy(false) }
  }

  const addLine = async () => {
    if (!selected || !newLine.account_id || !newLine.amount) return
    setBusy(true)
    try {
      await api.post(ENDPOINTS.LEDGER.LINES(selected.id), { lines: [{ line_order: Math.max(0, ...(selected.lines || []).map((line) => line.line_order)) + 1, entry_type: newLine.entry_type, account_id: newLine.account_id, amount: newLine.amount, currency_id: newLine.currency_id || null, description: newLine.description || null }] })
      setNewLine(emptyLine()); await loadJournals()
    } finally { setBusy(false) }
  }

  const removeLine = async (line: JournalLineRead) => {
    if (!selected || !window.confirm(ar ? 'حذف هذا السطر؟' : 'Delete this line?')) return
    setBusy(true)
    try { await api.del(ENDPOINTS.LEDGER.LINE(selected.id, line.id)); await loadJournals() }
    finally { setBusy(false) }
  }

  const openLineEditor = (line: JournalLineRead) => {
    setEditingLine(line)
    setEditLineForm({
      account_id: line.account_id,
      entry_type: line.entry_type === 'credit' ? 'credit' : 'debit',
      amount: String(line.amount ?? ''),
      currency_id: line.currency_id || '',
      description: line.description || '',
    })
  }

  const saveLine = async () => {
    if (!selected || !editingLine || !editLineForm.account_id || !editLineForm.amount) return
    setBusy(true)
    try {
      await api.patch(ENDPOINTS.LEDGER.LINE(selected.id, editingLine.id), {
        account_id: editLineForm.account_id,
        entry_type: editLineForm.entry_type,
        amount: editLineForm.amount,
        currency_id: editLineForm.currency_id || undefined,
        description: editLineForm.description || null,
      })
      setEditingLine(null)
      await loadJournals()
      toast.success(ar ? 'تم حفظ السطر.' : 'Journal line saved.')
    } finally { setBusy(false) }
  }

  const totals = useMemo(() => {
    const lines = selected?.lines || []
    const byCurrency = new Map<string, { debit: number; credit: number }>()
    lines.forEach((line) => {
      const key = line.currency_id || 'default'
      const current = byCurrency.get(key) || { debit: 0, credit: 0 }
      current[line.entry_type === 'debit' ? 'debit' : 'credit'] += amount(line.amount)
      byCurrency.set(key, current)
    })
    return {
      debit: lines.filter((line) => line.entry_type === 'debit').reduce((sum, line) => sum + amount(line.amount), 0),
      credit: lines.filter((line) => line.entry_type === 'credit').reduce((sum, line) => sum + amount(line.amount), 0),
      byCurrency,
    }
  }, [selected])
  const balanced = totals.byCurrency.size > 0 && Array.from(totals.byCurrency.values()).every((group) => group.debit > 0 && group.debit === group.credit)

  return <div className="space-y-5">
    <PageHeader title={text.title} description={text.description} breadcrumbs={[{ label: ar ? 'المالية والتدقيق' : 'Finance and audit', href: '#' }, { label: text.title }]} actions={can('journal:create') ? <Button onClick={() => setCreateOpen(true)}><FilePlus2 className="h-4 w-4" />{text.create}</Button> : undefined} />
    <div className="grid grid-cols-2 gap-3 lg:grid-cols-4"><KpiCard label={text.total} value={String(journals.length)} icon={BookOpen} tone="gold" accent /><KpiCard label={text.drafts} value={String(journals.filter((j) => j.status === 'draft').length)} icon={FilePlus2} tone="info" /><KpiCard label={text.awaiting} value={String(journals.filter((j) => j.status === 'pending_approval').length)} icon={ShieldCheck} tone="warning" /><KpiCard label={text.posted} value={String(journals.filter((j) => j.status === 'posted').length)} icon={FileCheck} tone="success" /></div>
    <div className="grid gap-5 xl:grid-cols-[minmax(0,1fr)_520px]">
      <SectionCard title={text.journals} padded={false}><div className="flex flex-col gap-2 border-b border-border p-4 md:flex-row"><label className="relative flex-1"><Search className="absolute start-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" /><input value={query} onChange={(e) => setQuery(e.target.value)} placeholder={text.search} className="h-10 w-full rounded-md border border-border bg-background ps-9 pe-3 text-sm" /></label><select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} className="h-10 rounded-md border border-border bg-background px-3 text-sm"><option value="">{text.allStatus}</option>{Object.entries(statusMeta).map(([value, meta]) => <option key={value} value={value}>{meta.label}</option>)}</select><select value={sourceFilter} onChange={(e) => setSourceFilter(e.target.value)} className="h-10 rounded-md border border-border bg-background px-3 text-sm"><option value="">{text.allSources}</option><option value="manual">manual</option><option value="buy_order">buy_order</option><option value="sell_order">sell_order</option><option value="receiving_order">receiving_order</option><option value="payment">payment</option></select></div>{loading ? <div className="flex justify-center p-10"><Loader2 className="h-6 w-6 animate-spin" /></div> : <DataTable columns={columns} data={filtered} rowKey={(row) => row.id} activeRowKey={selectedId || undefined} onRowClick={(row) => setSelectedId(row.id)} />}</SectionCard>
      <SectionCard title={selected ? `${text.details} · ${selected.journal_number}` : text.details}>{!selected ? <p className="text-sm text-muted-foreground">{text.select}</p> : <div className="space-y-5">
        <div className="flex flex-wrap items-center justify-between gap-2 border-b border-border pb-3"><StatusBadge tone={statusMeta[selected.status]?.tone || 'neutral'}>{statusMeta[selected.status]?.label || selected.status}</StatusBadge><div className="flex flex-wrap gap-2">{selected.status === 'draft' && can('journal:validate') && <Button size="sm" variant="outline" disabled={!balanced} isLoading={busy} onClick={() => runAction(ENDPOINTS.LEDGER.VALIDATE(selected.id))}><CheckCircle2 className="h-4 w-4" />{text.validate}</Button>}{selected.status === 'validated' && can('journal:validate') && <Button size="sm" isLoading={busy} onClick={() => runAction(ENDPOINTS.LEDGER.SUBMIT_APPROVAL(selected.id))}><Send className="h-4 w-4" />{text.submit}</Button>}{selected.status === 'pending_approval' && can('journal:approve') && <Button size="sm" isLoading={busy} onClick={() => runAction(ENDPOINTS.LEDGER.APPROVE(selected.id))}><ShieldCheck className="h-4 w-4" />{text.approve}</Button>}{selected.status === 'approved' && can('journal:post') && <Button size="sm" isLoading={busy} onClick={() => runAction(ENDPOINTS.LEDGER.POST(selected.id), undefined, text.confirmPost)}><FileCheck className="h-4 w-4" />{text.post}</Button>}{selected.status === 'posted' && can('journal:reverse') && <Button size="sm" variant="danger" isLoading={busy} onClick={() => { const reason = window.prompt(text.reason); if (reason) runAction(ENDPOINTS.LEDGER.REVERSE(selected.id), { reason }) }}><RefreshCcw className="h-4 w-4" />{text.reverse}</Button>}{['draft','validated','pending_approval','approved'].includes(selected.status) && can('journal:update') && <Button size="sm" variant="ghost" isLoading={busy} onClick={() => runAction(ENDPOINTS.LEDGER.CANCEL(selected.id), undefined, ar ? 'إلغاء القيد؟' : 'Cancel this journal?')}><CircleSlash className="h-4 w-4" />{text.cancel}</Button>}</div></div>
        {selected.status === 'draft' ? <div className="grid grid-cols-2 gap-3"><label className="text-xs font-medium">{text.date}<input type="date" value={editHeader.journal_date} onChange={(e) => setEditHeader({ ...editHeader, journal_date: e.target.value })} className="mt-1 h-9 w-full rounded-md border border-border bg-background px-3" /></label><label className="col-span-2 text-xs font-medium">{text.descriptionLabel}<textarea value={editHeader.description} onChange={(e) => setEditHeader({ ...editHeader, description: e.target.value })} className="mt-1 min-h-16 w-full rounded-md border border-border bg-background p-3" /></label>{can('journal:update') && <Button size="sm" className="col-span-2 justify-self-end" isLoading={busy} onClick={saveHeader}><Save className="h-4 w-4" />{text.saveHeader}</Button>}</div> : <div className="grid grid-cols-2 gap-3 text-xs"><Fact label={text.date} value={selected.journal_date || '-'} /><Fact label={text.source} value={selected.source} /><Fact label={text.descriptionLabel} value={selected.description || '-'} wide /></div>}
        <div><h3 className="mb-2 text-xs font-semibold">{text.balance}</h3><div className={`grid grid-cols-3 gap-3 rounded-md border p-3 ${balanced ? 'border-emerald-200 bg-emerald-50' : 'border-amber-200 bg-amber-50'}`}><Fact label={text.debit} value={totals.debit.toFixed(2)} /><Fact label={text.credit} value={totals.credit.toFixed(2)} /><div className="text-xs font-semibold">{balanced ? text.balanced : text.unbalanced}</div></div></div>
        <div><h3 className="mb-2 text-xs font-semibold">{text.lines}</h3><div className="divide-y divide-border border-y border-border">{(selected.lines || []).map((line) => <div key={line.id} className="grid grid-cols-[1fr_70px_90px_86px] items-center gap-2 py-2 text-xs"><span className="truncate" title={accountName(line.account_id)}>{accountName(line.account_id)}</span><span className={line.entry_type === 'debit' ? 'text-emerald-700' : 'text-red-700'}>{line.entry_type === 'debit' ? text.debit : text.credit}</span><span className="font-mono">{amount(line.amount).toFixed(2)} {currencyCode(line.currency_id)}</span>{selected.status === 'draft' && can('journal:update') ? <span className="flex justify-end gap-2"><button type="button" onClick={() => openLineEditor(line)} title={editText} className="inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-muted-foreground hover:bg-muted"><Pencil className="h-3.5 w-3.5" />{editText}</button><button type="button" onClick={() => removeLine(line)} title={ar ? 'حذف السطر' : 'Delete line'}><Trash2 className="h-4 w-4 text-red-600" /></button></span> : <span />}</div>)}</div></div>
        {selected.status === 'draft' && can('journal:update') && <div className="space-y-3 border-t border-border pt-4"><h3 className="text-xs font-semibold">{text.addLine}</h3><SearchableSelectField id="line_account" label={text.account} value={newLine.account_id} onChange={(value) => setNewLine({ ...newLine, account_id: value })} options={accountOptions} placeholder={ar ? 'ابحث عن حساب قابل للترحيل' : 'Search posting account'} required /><div className="grid grid-cols-3 gap-2"><select value={newLine.entry_type} onChange={(e) => setNewLine({ ...newLine, entry_type: e.target.value as 'debit' | 'credit' })} className="h-9 rounded-md border border-border bg-background px-2 text-xs"><option value="debit">{text.debit}</option><option value="credit">{text.credit}</option></select><input type="number" min="0.000001" step="0.01" value={newLine.amount} onChange={(e) => setNewLine({ ...newLine, amount: e.target.value })} placeholder="0.00" className="h-9 rounded-md border border-border bg-background px-2 text-xs" /><select value={newLine.currency_id} onChange={(e) => setNewLine({ ...newLine, currency_id: e.target.value })} className="h-9 rounded-md border border-border bg-background px-2 text-xs"><option value="">-</option>{currencies.map((currency) => <option key={currency.id} value={currency.id}>{currency.code}</option>)}</select></div><Button size="sm" variant="outline" disabled={!newLine.account_id || !newLine.amount} isLoading={busy} onClick={addLine}><Plus className="h-4 w-4" />{text.add}</Button></div>}
        <div><h3 className="mb-2 flex items-center gap-2 text-xs font-semibold"><History className="h-4 w-4" />{text.audit}</h3>{!audits.length ? <p className="text-xs text-muted-foreground">{text.noAudit}</p> : <div className="max-h-44 space-y-2 overflow-y-auto">{audits.map((audit) => <div key={audit.id} className="border-b border-border pb-2 text-xs"><div className="flex justify-between gap-3"><span className="font-medium">{audit.action}</span><span className="text-muted-foreground">{formatDateTime(audit.created_at)}</span></div></div>)}</div>}</div>
      </div>}</SectionCard>
    </div>

    <Modal open={createOpen} onClose={() => setCreateOpen(false)} title={text.create} description={text.createHelp} size="lg"><div className="max-h-[70vh] space-y-4 overflow-y-auto pe-1"><div className="grid grid-cols-2 gap-3"><label className="text-xs font-medium">{text.date}<input type="date" value={createForm.journal_date} onChange={(e) => setCreateForm({ ...createForm, journal_date: e.target.value })} className="mt-1 h-10 w-full rounded-md border border-border bg-background px-3" /></label><label className="text-xs font-medium">{text.source}<select value={createForm.source} onChange={(e) => setCreateForm({ ...createForm, source: e.target.value })} className="mt-1 h-10 w-full rounded-md border border-border bg-background px-3"><option value="manual">manual</option><option value="adjustment">adjustment</option></select></label><label className="col-span-2 text-xs font-medium">{text.descriptionLabel}<textarea value={createForm.description} onChange={(e) => setCreateForm({ ...createForm, description: e.target.value })} className="mt-1 min-h-16 w-full rounded-md border border-border bg-background p-3" /></label></div><div className="space-y-3"><div className="flex items-center justify-between"><h3 className="text-xs font-semibold">{text.lines}</h3><Button size="sm" variant="outline" onClick={() => setCreateForm({ ...createForm, lines: [...createForm.lines, emptyLine()] })}><Plus className="h-4 w-4" />{text.addLine}</Button></div>{createForm.lines.map((line, index) => <div key={index} className="grid grid-cols-[minmax(0,1fr)_100px_110px_100px_32px] items-end gap-2 border-b border-border pb-3"><SearchableSelectField id={`create_account_${index}`} label={text.account} value={line.account_id} onChange={(value) => setCreateForm({ ...createForm, lines: createForm.lines.map((item, position) => position === index ? { ...item, account_id: value } : item) })} options={accountOptions} placeholder={text.account} required /><select value={line.entry_type} onChange={(e) => setCreateForm({ ...createForm, lines: createForm.lines.map((item, position) => position === index ? { ...item, entry_type: e.target.value as 'debit' | 'credit' } : item) })} className="h-10 rounded-md border border-border bg-background px-2 text-xs"><option value="debit">{text.debit}</option><option value="credit">{text.credit}</option></select><input type="number" step="0.01" min="0.000001" value={line.amount} onChange={(e) => setCreateForm({ ...createForm, lines: createForm.lines.map((item, position) => position === index ? { ...item, amount: e.target.value } : item) })} placeholder="0.00" className="h-10 rounded-md border border-border bg-background px-2 text-xs" /><select value={line.currency_id} onChange={(e) => setCreateForm({ ...createForm, lines: createForm.lines.map((item, position) => position === index ? { ...item, currency_id: e.target.value } : item) })} className="h-10 rounded-md border border-border bg-background px-2 text-xs"><option value="">-</option>{currencies.map((currency) => <option key={currency.id} value={currency.id}>{currency.code}</option>)}</select><button type="button" disabled={createForm.lines.length <= 2} onClick={() => setCreateForm({ ...createForm, lines: createForm.lines.filter((_, position) => position !== index) })} className="mb-2 disabled:opacity-30"><Trash2 className="h-4 w-4 text-red-600" /></button></div>)}</div><div className="flex justify-end gap-2 border-t border-border pt-4"><Button variant="outline" onClick={() => setCreateOpen(false)}>{text.close}</Button><Button isLoading={busy} disabled={createForm.lines.some((line) => !line.account_id || !line.amount)} onClick={createJournal}><Save className="h-4 w-4" />{text.create}</Button></div></div></Modal>
    <Modal open={!!editingLine} onClose={() => setEditingLine(null)} title={saveLineText} size="md"><div className="space-y-4"><SearchableSelectField id="edit_line_account" label={text.account} value={editLineForm.account_id} onChange={(value) => setEditLineForm({ ...editLineForm, account_id: value })} options={accountOptions} placeholder={ar ? 'ط§ط¨ط­ط« ط¹ظ† ط­ط³ط§ط¨ ظ‚ط§ط¨ظ„ ظ„ظ„طھط±ط­ظٹظ„' : 'Search posting account'} required /><div className="grid grid-cols-3 gap-3"><label className="text-xs font-medium">{text.status}<select value={editLineForm.entry_type} onChange={(e) => setEditLineForm({ ...editLineForm, entry_type: e.target.value as 'debit' | 'credit' })} className="mt-1 h-10 w-full rounded-md border border-border bg-background px-3"><option value="debit">{text.debit}</option><option value="credit">{text.credit}</option></select></label><label className="text-xs font-medium">{text.debit}/{text.credit}<input type="number" min="0.000001" step="0.01" value={editLineForm.amount} onChange={(e) => setEditLineForm({ ...editLineForm, amount: e.target.value })} className="mt-1 h-10 w-full rounded-md border border-border bg-background px-3" /></label><label className="text-xs font-medium">{text.currency}<select value={editLineForm.currency_id} onChange={(e) => setEditLineForm({ ...editLineForm, currency_id: e.target.value })} className="mt-1 h-10 w-full rounded-md border border-border bg-background px-3"><option value="">-</option>{currencies.map((currency) => <option key={currency.id} value={currency.id}>{currency.code}</option>)}</select></label><label className="col-span-3 text-xs font-medium">{text.descriptionLabel}<textarea value={editLineForm.description} onChange={(e) => setEditLineForm({ ...editLineForm, description: e.target.value })} className="mt-1 min-h-16 w-full rounded-md border border-border bg-background p-3" /></label></div><div className="flex justify-end gap-2 border-t border-border pt-4"><Button variant="outline" onClick={() => setEditingLine(null)}>{text.close}</Button><Button isLoading={busy} disabled={!editLineForm.account_id || !editLineForm.amount} onClick={saveLine}><Save className="h-4 w-4" />{saveLineText}</Button></div></div></Modal>
  </div>
}

function Fact({ label, value, wide }: { label: string; value: string; wide?: boolean }) {
  return <div className={wide ? 'col-span-2' : ''}><div className="text-[11px] text-muted-foreground">{label}</div><div className="mt-0.5 break-words text-xs font-medium">{value}</div></div>
}
