'use client'
import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import axios from 'axios'
import { formatCurrency, fmtDate } from '@/lib/utils'
import { Settings, Save, RefreshCw, Archive, Database, Shield, Users, Briefcase, ChevronDown, ChevronRight, AlertCircle, Trash2, UserPlus, CheckCircle2, XCircle, AlertTriangle } from 'lucide-react'
import { Card, CardHeader, CardTitle, CardContent, Button, PageHeader, Badge, Alert, LoadingSpinner, Input, Select, Modal, FormGrid, StatCard } from '@/components/ui/components'
import { toast } from 'sonner'

export default function AccountingSetupPage() {
  const qc = useQueryClient()
  const [syncing, setSyncing] = useState(false)
  const [activeTab, setActiveTab] = useState<'mappings' | 'opening' | 'archive' | 'defaults'>('mappings')
  const [saving, setSaving] = useState<string | null>(null)
  const [selectedAccounts, setSelectedAccounts] = useState<Record<string, string>>({})
  const [openingEntries, setOpeningEntries] = useState<Record<string, string>>({})
  const [posting, setPosting] = useState(false)
  const [cutoffDate, setCutoffDate] = useState('')
  const [archiving, setArchiving] = useState(false)
  const [archiveResult, setArchiveResult] = useState<any>(null)
  const [seedModal, setSeedModal] = useState(false)
  const [seeding, setSeeding] = useState(false)
  const [wipeModal, setWipeModal] = useState(false)
  const [wiping, setWiping] = useState(false)
  const [wipeConfirm, setWipeConfirm] = useState('')

  const { data, isLoading } = useQuery({
    queryKey: ['accounting-setup'],
    queryFn: () => axios.get('/api/accounting/setup').then(r => r.data.data),
  })

  const { data: archiveStats, refetch: refetchArchive } = useQuery({
    queryKey: ['archive-stats'],
    queryFn: () => axios.get('/api/accounting/archive').then(r => r.data.data),
  })

  const { data: defaultsData } = useQuery({
    queryKey: ['system-defaults'],
    queryFn: () => axios.get('/api/accounting/defaults').then(r => r.data.data),
  })

  function handleSync() {
    setSyncing(true)
    axios.post('/api/accounting/sync', { mode: 'full' }).then(r => {
      toast.success(r.data.message)
      qc.invalidateQueries({ queryKey: ['accounting-setup'] })
      qc.invalidateQueries({ queryKey: ['coa'] })
      qc.invalidateQueries({ queryKey: ['trial-balance'] })
    }).catch((e: any) => {
      toast.error(e.response?.data?.error ?? 'Sync failed')
    }).finally(() => setSyncing(false))
  }

  async function handleUpdateMapping(systemKey: string) {
    const accountCode = selectedAccounts[systemKey]
    if (!accountCode) { toast.error('Select an account first'); return }
    setSaving(systemKey)
    try {
      const res = await axios.patch('/api/accounting/setup', { action: 'update-mapping', systemKey, accountCode })
      toast.success(`Mapped to ${res.data.data.accountCode} — ${res.data.data.accountName}`)
      qc.invalidateQueries({ queryKey: ['accounting-setup'] })
    } catch (e: any) {
      toast.error(e.response?.data?.error ?? 'Failed to update mapping')
    } finally { setSaving(null) }
  }

  async function handlePostOpeningBalances() {
    const entries = Object.entries(openingEntries)
      .map(([code, amount]) => ({ accountCode: code, amount: parseFloat(amount) || 0 }))
      .filter(e => e.amount > 0)
    if (entries.length === 0) { toast.error('Enter at least one opening balance'); return }
    setPosting(true)
    try {
      const res = await axios.post('/api/accounting/setup', { action: 'post-opening-balances', entries })
      toast.success(`Opening balances posted — ${res.data.data.lines} journal lines created`)
      qc.invalidateQueries({ queryKey: ['accounting-setup'] })
      qc.invalidateQueries({ queryKey: ['trial-balance'] })
      qc.invalidateQueries({ queryKey: ['coa'] })
      qc.invalidateQueries({ queryKey: ['income-statement'] })
      qc.invalidateQueries({ queryKey: ['balance-sheet'] })
      setOpeningEntries({})
    } catch (e: any) {
      toast.error(e.response?.data?.error ?? 'Failed to post opening balances')
    } finally { setPosting(false) }
  }

  async function handleArchive() {
    if (!cutoffDate) { toast.error('Select a cutoff date'); return }
    setArchiving(true)
    setArchiveResult(null)
    try {
      const res = await axios.post('/api/accounting/archive', { cutoffDate })
      setArchiveResult(res.data.data)
      toast.success(`Archived ${res.data.data.totalArchived} records`)
      refetchArchive()
      qc.invalidateQueries({ queryKey: ['accounting-setup'] })
    } catch (e: any) {
      toast.error(e.response?.data?.error ?? 'Archive failed')
    } finally { setArchiving(false) }
  }

  async function handleSeedDefaults() {
    setSeeding(true)
    try {
      const res = await axios.post('/api/accounting/defaults', { action: 'seed-all' })
      toast.success(res.data.message ?? 'Defaults seeded')
      setSeedModal(false)
      qc.invalidateQueries({ queryKey: ['system-defaults'] })
      qc.invalidateQueries({ queryKey: ['accounting-setup'] })
      qc.invalidateQueries({ queryKey: ['coa'] })
    } catch (e: any) {
      toast.error(e.response?.data?.error ?? 'Failed')
    } finally { setSeeding(false) }
  }

  async function handleWipeData() {
    setWiping(true)
    try {
      await axios.post('/api/accounting/wipe')
      toast.success('All transactional data wiped successfully')
      setWipeModal(false)
      setWipeConfirm('')
      qc.invalidateQueries()
      refetchArchive()
    } catch (e: any) {
      toast.error(e.response?.data?.error ?? 'Wipe failed')
    } finally { setWiping(false) }
  }

  const defaultsConfig = data?.defaultsConfig ?? []
  const allAccounts = data?.allLeafAccounts ?? []
  const openingBalances = data?.openingBalances ?? []
  const stats = archiveStats?.stats ?? {}
  const dateRange = archiveStats?.dateRange ?? null

  return (
    <div className="p-6 space-y-5 max-w-screen-xl mx-auto">
      <PageHeader title="Accounting Setup" description="Configure system accounts, archive old data, and set defaults" icon={<Settings className="w-6 h-6"/>}
        actions={
          <Button variant="outline" size="sm" loading={syncing} onClick={handleSync}>
            <RefreshCw className="w-4 h-4 mr-1"/>Resync
          </Button>
        }
      />

      {/* Tabs */}
      <div className="flex gap-1 bg-muted/40 rounded-lg p-1 flex-wrap">
        {([
          { key: 'mappings', label: 'System Account Mappings', icon: <Settings className="w-3.5 h-3.5" /> },
          { key: 'opening', label: 'Opening Balances', icon: <Database className="w-3.5 h-3.5" /> },
          { key: 'archive', label: 'Data Archive', icon: <Archive className="w-3.5 h-3.5" /> },
          { key: 'defaults', label: 'System Defaults', icon: <Shield className="w-3.5 h-3.5" /> },
        ] as const).map(tab => (
          <button key={tab.key} onClick={() => setActiveTab(tab.key)}
            className={`flex items-center gap-1.5 px-4 py-2 text-sm font-medium rounded-md transition-colors ${activeTab === tab.key ? 'bg-background shadow-sm' : 'hover:text-foreground/80 text-muted-foreground'}`}>
            {tab.icon}{tab.label}
          </button>
        ))}
      </div>

      {isLoading ? <LoadingSpinner message="Loading setup data…"/> : (
        <>
          {/* ── TAB: System Account Mappings ── */}
          {activeTab === 'mappings' && (
            <Card>
              <CardHeader><CardTitle>System Account Mappings</CardTitle></CardHeader>
              <CardContent>
                <Alert variant="info" title="What is this?">
                  Each system function (e.g. Loan Portfolio, Interest Income) needs to be mapped to a GL account.
                  Changes take effect immediately.
                </Alert>
                <div className="overflow-x-auto mt-4">
                  <table className="table-lms w-full">
                    <thead>
                      <tr><th className="text-left">Purpose</th><th className="text-left">Current Account</th><th className="text-left">Change To</th><th className="text-right">Action</th></tr>
                    </thead>
                    <tbody>
                      {defaultsConfig.map((def: any) => (
                        <tr key={def.key} className={!def.current ? 'bg-amber-50 dark:bg-amber-950/20' : ''}>
                          <td>
                            <div className="flex items-center gap-2">
                              <span className="text-sm font-medium">{def.label}</span>
                              {!def.current && <Badge variant="warning">Not configured</Badge>}
                            </div>
                            <p className="text-xs text-muted-foreground font-mono">{def.key}</p>
                          </td>
                          <td>
                            {def.current ? (
                              <span className="font-mono text-sm">{def.current.accountCode} — {def.current.accountName}</span>
                            ) : (
                              <span className="text-xs text-muted-foreground italic">None</span>
                            )}
                          </td>
                          <td>
                            <select value={selectedAccounts[def.key] ?? def.current?.accountCode ?? ''}
                              onChange={e => setSelectedAccounts(prev => ({ ...prev, [def.key]: e.target.value }))}
                              className="w-full max-w-xs px-2 py-1.5 text-sm border rounded-lg bg-background">
                              <option value="">— Select account —</option>
                              {allAccounts.map((a: any) => (
                                <option key={a.id} value={a.code}>{a.code} — {a.name} ({a.accountType})</option>
                              ))}
                            </select>
                          </td>
                          <td className="text-right">
                            <Button size="sm" loading={saving === def.key}
                              onClick={() => handleUpdateMapping(def.key)}
                              disabled={!selectedAccounts[def.key] && !def.current}>
                              <Save className="w-3.5 h-3.5 mr-1"/>Save
                            </Button>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </CardContent>
            </Card>
          )}

          {/* ── TAB: Opening Balances ── */}
          {activeTab === 'opening' && (
            <Card>
              <CardHeader><CardTitle>Opening Balances</CardTitle></CardHeader>
              <CardContent>
                <Alert variant="info" title="How it works">
                  Enter opening balances for each GL account. When you click "Post Opening Balances", a balancing
                  journal entry is created. Differences post to the Suspense account (6000).
                </Alert>
                <div className="overflow-x-auto mt-4">
                  <table className="table-lms w-full">
                    <thead>
                      <tr><th className="text-left">Code</th><th className="text-left">Account Name</th><th className="text-left">Type</th><th className="text-right">Current</th><th className="text-right">Opening</th><th className="w-32 text-right">New (KES)</th></tr>
                    </thead>
                    <tbody>
                      {openingBalances.map((a: any) => (
                        <tr key={a.id}>
                          <td className="font-mono text-xs text-muted-foreground">{a.code}</td>
                          <td className="text-sm">{a.name}</td>
                          <td><Badge variant="default">{a.accountType}</Badge></td>
                          <td className="text-right text-sm font-mono">{formatCurrency(a.currentBalance)}</td>
                          <td className="text-right text-sm font-mono">{formatCurrency(a.openingBalance)}</td>
                          <td className="text-right">
                            <input type="number" step="0.01" min="0"
                              value={openingEntries[a.code] ?? ''}
                              onChange={e => setOpeningEntries(prev => ({ ...prev, [a.code]: e.target.value }))}
                              placeholder="0.00"
                              className="w-full max-w-[140px] text-right px-2 py-1 text-sm border rounded-md bg-background ml-auto"/>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                <div className="flex justify-end mt-4">
                  <Button loading={posting} onClick={handlePostOpeningBalances}>
                    <AlertCircle className="w-4 h-4 mr-1"/>Post Opening Balances
                  </Button>
                </div>
              </CardContent>
            </Card>
          )}

          {/* ── TAB: Data Archive ── */}
          {activeTab === 'archive' && (
            <>
              <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3">
                {Object.entries(stats).map(([label, s]: [string, any]) => (
                  <StatCard key={label} label={label}
                    value={`${(s.current ?? 0).toLocaleString()} current · ${(s.archive ?? 0).toLocaleString()} archived`}
                    icon={<Database className="w-5 h-5"/>} color="blue" />
                ))}
              </div>

              <Card>
                <CardHeader><CardTitle>Archive Old Data</CardTitle></CardHeader>
                <CardContent className="space-y-4">
                  <Alert variant="info" title="How archiving works">
                    Moves data older than the cutoff date to archive tables. This keeps current-period queries fast.
                    Archived data can be queried separately. Recommended: archive after fiscal year-end closure.
                  </Alert>

                  {dateRange && (
                    <p className="text-sm text-muted-foreground">
                      Data range: <span className="font-mono">{fmtDate(dateRange.min)}</span> to <span className="font-mono">{fmtDate(dateRange.max)}</span>
                    </p>
                  )}

                  <div className="flex items-end gap-3 flex-wrap">
                    <Input label="Cutoff Date (archive data older than)" type="date"
                      value={cutoffDate} onChange={e => setCutoffDate(e.target.value)} />
                    <Button loading={archiving} onClick={handleArchive} variant={cutoffDate ? 'primary' : 'outline'}>
                      <Archive className="w-4 h-4 mr-1"/>Archive
                    </Button>
                  </div>

                  {archiveResult && (
                    <div className="border rounded-lg p-4 space-y-2 bg-muted/20">
                      <p className="text-sm font-semibold">Archive Complete — {archiveResult.totalArchived} records archived</p>
                      {Object.entries(archiveResult.results).map(([label, count]: [string, any]) => (
                        count > 0 && <p key={label} className="text-sm text-muted-foreground pl-4">• {label}: {count} rows</p>
                      ))}
                    </div>
                  )}
              </CardContent>
            </Card>

            {/* Clear All Data */}
            <Card>
              <CardHeader>
                <CardTitle><Trash2 className="w-4 h-4 inline mr-2 text-red-500" />Clear All Transactional Data</CardTitle>
              </CardHeader>
              <CardContent className="space-y-3">
                <Alert variant="warning" title="⚠️ Irreversible action">
                  This permanently deletes all loans, repayments, journal entries, audit logs, cash advances, expenses,
                  payroll runs, budgets, fixed assets, fixed deposits, savings transactions, and share transactions.
                  Account balances will be reset to zero. Master data (members, COA structure, users, branches, loan products) is kept.
                </Alert>
                <Button variant="destructive" onClick={() => setWipeModal(true)}>
                  <Trash2 className="w-4 h-4 mr-1" />Clear All Transactional Data
                </Button>
              </CardContent>
            </Card>
          </>
          )}

          {/* ── TAB: System Defaults ── */}
          {activeTab === 'defaults' && (
            <div className="space-y-5">
              {/* Seed Defaults Card */}
              <Card>
                <CardHeader>
                  <CardTitle><Shield className="w-4 h-4 inline mr-2" />System Initialization</CardTitle>
                </CardHeader>
                <CardContent className="space-y-4">
                  <Alert variant="info" title="First-time setup">
                    Initialize the system with default Chart of Accounts, Super Admin user, default Departments, and standard User Roles.
                    Run this only if the system is not yet configured or you need to reset to defaults.
                  </Alert>

                  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
                    <StatCard label="Accounts" value={defaultsData?.accounts?.length ?? 0} icon={<Database className="w-5 h-5"/>} color="blue" />
                    <StatCard label="Super Admins" value={defaultsData?.superAdmins ?? 0} icon={<Shield className="w-5 h-5"/>} color="purple" />
                    <StatCard label="Departments" value={defaultsData?.departments?.length ?? 0} icon={<Briefcase className="w-5 h-5"/>} color="green" />
                    <StatCard label="Roles" value={defaultsData?.roles?.length ?? 0} icon={<Users className="w-5 h-5"/>} color="amber" />
                  </div>

                  <div className="flex gap-3 flex-wrap">
                    <Button onClick={() => setSeedModal(true)} icon={<Database className="w-4 h-4" />}>
                      Seed All Defaults
                    </Button>
                    <Button variant="outline" onClick={async () => {
                      try {
                        const res = await axios.post('/api/accounting/defaults', { action: 'create-super-admin' })
                        toast.success(res.data.message ?? 'Super admin ready')
                        qc.invalidateQueries({ queryKey: ['system-defaults'] })
                      } catch (e: any) { toast.error(e.response?.data?.error ?? 'Failed') }
                    }}>
                      <UserPlus className="w-4 h-4 mr-1"/>Create Super Admin
                    </Button>
                  </div>
                </CardContent>
              </Card>

              {/* Departments List */}
              <Card>
                <CardHeader>
                  <CardTitle><Briefcase className="w-4 h-4 inline mr-2" />Departments</CardTitle>
                </CardHeader>
                <CardContent>
                  {(!defaultsData?.departments || defaultsData.departments.length === 0) ? (
                    <p className="text-sm text-muted-foreground py-4 text-center">No departments configured. Run Seed All Defaults to create standard departments.</p>
                  ) : (
                    <div className="overflow-x-auto">
                      <table className="table-lms w-full">
                        <thead><tr><th>Name</th><th className="text-center">Staff Count</th></tr></thead>
                        <tbody>
                          {defaultsData.departments.map((d: any, i: number) => (
                            <tr key={i}><td className="text-sm">{d.name}</td><td className="text-center text-sm text-muted-foreground">{d.count ?? 0}</td></tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                </CardContent>
              </Card>

              {/* Roles List */}
              <Card>
                <CardHeader>
                  <CardTitle><Users className="w-4 h-4 inline mr-2" />User Roles</CardTitle>
                </CardHeader>
                <CardContent>
                  {(!defaultsData?.roles || defaultsData.roles.length === 0) ? (
                    <p className="text-sm text-muted-foreground py-4 text-center">No roles configured. Run Seed All Defaults to create standard roles.</p>
                  ) : (
                    <div className="overflow-x-auto">
                      <table className="table-lms w-full">
                        <thead><tr><th>Name</th><th>Description</th><th className="text-center">System</th><th className="text-center">Users</th></tr></thead>
                        <tbody>
                          {defaultsData.roles.map((r: any) => (
                            <tr key={r.id}>
                              <td className="text-sm font-medium">{r.name}</td>
                              <td className="text-sm text-muted-foreground">{r.description ?? '—'}</td>
                              <td className="text-center">{r.isSystemRole ? <CheckCircle2 className="w-4 h-4 text-green-500 inline"/> : <XCircle className="w-4 h-4 text-muted-foreground inline"/>}</td>
                              <td className="text-center text-sm">{r._count?.userRoles ?? 0}</td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                </CardContent>
              </Card>
            </div>
          )}
        </>
      )}

      {/* Wipe Data Confirmation Modal */}
      <Modal open={wipeModal} onClose={() => setWipeModal(false)} title="Clear All Transactional Data" size="md">
        <div className="space-y-4">
          <Alert variant="error" title="🚨 This action CANNOT be undone">
            <ul className="list-disc pl-4 space-y-1 text-sm mt-2">
              <li>All loans, repayments, schedules, and loan history will be deleted</li>
              <li>All journal entries and audit logs will be deleted</li>
              <li>All cash advances, cashbook entries, expenses, payroll runs will be deleted</li>
              <li>All budgets, fixed assets, fixed deposits will be deleted</li>
              <li>All savings transactions and share transactions will be deleted</li>
              <li>Archive tables will be dropped</li>
              <li>All COA balances, savings balances, and share balances will reset to zero</li>
            </ul>
          </Alert>
          <p className="text-sm text-muted-foreground">Master data (members, COA structure, users, branches, loan products, fees config) will be preserved.</p>
          <p className="text-sm font-semibold text-red-600">Type <span className="font-mono bg-red-50 dark:bg-red-950 px-2 py-0.5 rounded border border-red-200">CONFIRM</span> to proceed:</p>
          <Input value={wipeConfirm} onChange={e => setWipeConfirm(e.target.value)} placeholder="Type CONFIRM" />
          <div className="flex justify-end gap-3 pt-2">
            <Button variant="outline" onClick={() => { setWipeModal(false); setWipeConfirm('') }}>Cancel</Button>
            <Button variant="destructive" loading={wiping} disabled={wipeConfirm !== 'CONFIRM'} onClick={handleWipeData}>
              <Trash2 className="w-4 h-4 mr-1" />Clear Everything
            </Button>
          </div>
        </div>
      </Modal>

      {/* Seed Defaults Modal */}
      <Modal open={seedModal} onClose={() => setSeedModal(false)} title="Seed System Defaults" size="md">
        <div className="space-y-4">
          <Alert variant="warning" title="⚠️ This will:">
            <ul className="list-disc pl-4 space-y-1 text-sm">
              <li>Create default Chart of Accounts if empty</li>
              <li>Create standard Departments (HR, Finance, Operations, IT, Credit, Legal)</li>
              <li>Create default User Roles (Super Admin, Manager, Loans Officer, Accountant, Auditor)</li>
              <li>Assign all permissions to the Super Admin role</li>
              <li>Create a Super Admin user if none exists</li>
            </ul>
          </Alert>
          <p className="text-sm text-muted-foreground">Existing data will not be overwritten. This only fills in missing defaults.</p>
          <div className="flex justify-end gap-3 pt-2">
            <Button variant="outline" onClick={() => setSeedModal(false)}>Cancel</Button>
            <Button loading={seeding} onClick={handleSeedDefaults}>
              <Database className="w-4 h-4 mr-1"/>Seed Defaults
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  )
}
