'use client'

import React, { Fragment, useEffect, useState, useCallback } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import {
  XMarkIcon,
  DocumentTextIcon,
  UserIcon,
  BanknotesIcon,
  CalendarDaysIcon,
  ArrowDownTrayIcon,
  ArrowPathIcon,
  CheckCircleIcon,
  ExclamationCircleIcon,
  ClockIcon,
  NoSymbolIcon,
  PencilSquareIcon,
  ShieldCheckIcon,
} from '@heroicons/react/24/outline'
import useAuthStore from '../../../store/authStore'

/* ---------- types ---------- */
export type AdminInvoice = {
  id: string | number
  invoice_number?: string | null
  user_id?: string | number | null
  buyer_name?: string | null
  buyer_email?: string | null
  buyer_street?: string | null
  buyer_postal_code?: string | null
  buyer_city?: string | null
  buyer_country?: string | null
  currency?: string | null
  total_net?: number | null
  total_tax?: number | null
  total_gross?: number | null
  vat_rate?: number | null
  status?: string
  issued_at?: string | null
  due_at?: string | null
  pdf_storage_key?: string | null
  context?: any | null
  created_at?: string | null
  updated_at?: string | null
}

type InvoiceItem = {
  id?: number
  invoice_id?: number
  product_id?: number | null
  sku?: string | null
  description?: string | null
  quantity?: number
  unit_price?: number
  tax_rate?: number | null
  line_net?: number
  line_tax?: number
  line_gross?: number
  created_at?: string
}

type InvoicePayment = {
  id?: number
  invoice_id?: number
  payment_method?: string | null
  transaction_id?: string | null
  amount?: number | null
  paid_at?: string | null
  status?: string | null
  details?: string | null
  created_at?: string
}

interface InvoiceDetailModalProps {
  invoice: AdminInvoice | null
  open: boolean
  onClose: () => void
  onStatusChanged?: () => void
  onRunPoolCheck?: (invoiceId: string | number) => void
  onExport?: (invoice: AdminInvoice) => void
}

/* ---------- constants ---------- */
const STATUSES = ['draft', 'issued', 'paid', 'overdue', 'canceled'] as const
type InvoiceStatus = (typeof STATUSES)[number]

const STATUS_CONFIG: Record<InvoiceStatus, { label: string; bg: string; text: string; icon: React.ElementType }> = {
  draft:    { label: 'Draft',    bg: 'bg-gray-100',   text: 'text-gray-700',   icon: PencilSquareIcon },
  issued:   { label: 'Issued',   bg: 'bg-indigo-100', text: 'text-indigo-700', icon: DocumentTextIcon },
  paid:     { label: 'Paid',     bg: 'bg-green-100',  text: 'text-green-700',  icon: CheckCircleIcon },
  overdue:  { label: 'Overdue',  bg: 'bg-red-100',    text: 'text-red-700',    icon: ExclamationCircleIcon },
  canceled: { label: 'Canceled', bg: 'bg-yellow-100', text: 'text-yellow-700', icon: NoSymbolIcon },
}

function fmtDate(d?: string | null) {
  if (!d) return '—'
  return new Date(d).toLocaleDateString('de-DE', { year: 'numeric', month: 'short', day: '2-digit' })
}

function fmtDateTime(d?: string | null) {
  if (!d) return '—'
  return new Date(d).toLocaleString('de-DE', { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' })
}

function fmtMoney(v?: number | null, currency = 'EUR') {
  return `€ ${Number(v ?? 0).toFixed(2)}`
}

/* ---------- component ---------- */
export default function InvoiceDetailModal({
  invoice,
  open,
  onClose,
  onStatusChanged,
  onRunPoolCheck,
  onExport,
}: InvoiceDetailModalProps) {
  const token = useAuthStore((s) => s.accessToken)

  // detail data
  const [items, setItems] = useState<InvoiceItem[]>([])
  const [payments, setPayments] = useState<InvoicePayment[]>([])
  const [detailLoading, setDetailLoading] = useState(false)
  const [detailError, setDetailError] = useState('')

  // status change
  const [changingStatus, setChangingStatus] = useState(false)
  const [statusMsg, setStatusMsg] = useState('')
  const [statusErr, setStatusErr] = useState('')
  const [currentStatus, setCurrentStatus] = useState<string>(invoice?.status ?? 'draft')

  // keep current status in sync with prop
  useEffect(() => {
    if (invoice) setCurrentStatus(invoice.status ?? 'draft')
  }, [invoice])

  // fetch detail (items + payments) when opened
  const fetchDetail = useCallback(async () => {
    if (!invoice?.id || !token) return
    setDetailLoading(true)
    setDetailError('')
    try {
      const base = process.env.NEXT_PUBLIC_API_BASE_URL || ''
      const res = await fetch(`${base}/api/admin/invoices/${encodeURIComponent(String(invoice.id))}/detail`, {
        method: 'GET',
        credentials: 'include',
        headers: {
          Accept: 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
      })
      const body = await res.json().catch(() => ({}))
      if (!res.ok || body?.success === false) {
        setDetailError(body?.message || `Failed to load details (${res.status})`)
        return
      }
      setItems(Array.isArray(body?.data?.items) ? body.data.items : [])
      setPayments(Array.isArray(body?.data?.payments) ? body.data.payments : [])
    } catch (e: any) {
      setDetailError(e?.message || 'Network error')
    } finally {
      setDetailLoading(false)
    }
  }, [invoice?.id, token])

  useEffect(() => {
    if (open && invoice) {
      void fetchDetail()
    } else {
      setItems([])
      setPayments([])
      setDetailError('')
      setStatusMsg('')
      setStatusErr('')
    }
  }, [open, invoice, fetchDetail])

  // change status
  async function handleStatusChange(newStatus: string) {
    if (!invoice?.id || !token || newStatus === currentStatus) return
    setChangingStatus(true)
    setStatusErr('')
    setStatusMsg('')
    try {
      const base = process.env.NEXT_PUBLIC_API_BASE_URL || ''
      const res = await fetch(`${base}/api/admin/invoices/${encodeURIComponent(String(invoice.id))}/status`, {
        method: 'PATCH',
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ status: newStatus }),
      })
      const body = await res.json().catch(() => ({}))
      if (!res.ok || body?.success === false) {
        setStatusErr(body?.message || `Failed to update status (${res.status})`)
        return
      }
      setCurrentStatus(newStatus)
      // Build status message including pool booking info
      let msg = `Status updated to "${newStatus}"`
      if (body?.poolResult) {
        const pr = body.poolResult
        if (pr.error) {
          msg += ` — Pool booking error: ${pr.error}`
        } else if (pr.inserted > 0) {
          msg += ` — ${pr.inserted} pool inflow(s) booked`
        } else if (pr.reason && pr.reason !== 'ok') {
          const reasonLabels: Record<string, string> = {
            invalid_invoice_id: 'Invalid invoice ID',
            invoice_not_found: 'Invoice not found for pool booking',
            invoice_not_paid: 'Invoice not marked as paid',
            unsupported_source_type: 'Not a subscription invoice — no pool booking',
            missing_abonement_relation: 'No linked subscription — no pool booking',
            abonement_not_found: 'Linked subscription not found',
            no_breakdown_lines: 'Subscription has no capsule breakdown — no pool booking',
            no_active_system_pools: 'No active system pools found',
          }
          msg += ` — ${reasonLabels[pr.reason] || pr.reason}`
        }
      }
      setStatusMsg(msg)
      // Re-fetch detail to pick up any payment records (e.g. after marking paid)
      void fetchDetail()
      onStatusChanged?.()
    } catch (e: any) {
      setStatusErr(e?.message || 'Network error')
    } finally {
      setChangingStatus(false)
    }
  }

  if (!invoice) return null

  const statusConf = STATUS_CONFIG[(currentStatus as InvoiceStatus)] ?? STATUS_CONFIG.draft
  const StatusIcon = statusConf.icon as React.ComponentType<React.SVGProps<SVGSVGElement>>

  return (
    <Transition show={open} as={Fragment}>
      <Dialog onClose={onClose} className="relative z-[1100]">
        {/* backdrop */}
        <Transition.Child
          as={Fragment}
          enter="transition-opacity ease-out duration-200"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="transition-opacity ease-in duration-150"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-black/40 backdrop-blur-sm" />
        </Transition.Child>

        {/* panel */}
        <div className="fixed inset-0 overflow-y-auto">
          <div className="flex min-h-full items-center justify-center p-4">
            <Transition.Child
              as={Fragment}
              enter="transition-all ease-out duration-200"
              enterFrom="opacity-0 translate-y-2 sm:scale-95"
              enterTo="opacity-100 translate-y-0 sm:scale-100"
              leave="transition-all ease-in duration-150"
              leaveFrom="opacity-100 translate-y-0 sm:scale-100"
              leaveTo="opacity-0 translate-y-2 sm:scale-95"
            >
              <Dialog.Panel className="w-full max-w-3xl rounded-2xl bg-white shadow-2xl ring-1 ring-black/5 overflow-hidden">
                {/* ─── header ─── */}
                <div className="bg-gradient-to-r from-[#1C2B4A] to-[#2d3f66] px-6 py-5 flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <div className="h-10 w-10 rounded-lg bg-white/10 flex items-center justify-center">
                      <DocumentTextIcon className="h-5 w-5 text-white" />
                    </div>
                    <div>
                      <Dialog.Title className="text-lg font-bold text-white">
                        Invoice {invoice.invoice_number ?? `#${invoice.id}`}
                      </Dialog.Title>
                      <p className="text-sm text-blue-200/80">
                        Created {fmtDateTime(invoice.created_at)}
                      </p>
                    </div>
                  </div>
                  <button
                    onClick={onClose}
                    className="rounded-lg p-1.5 text-blue-200 hover:text-white hover:bg-white/10 transition"
                  >
                    <XMarkIcon className="h-5 w-5" />
                  </button>
                </div>

                {/* ─── body ─── */}
                <div className="px-6 py-5 space-y-6 max-h-[75vh] overflow-y-auto">

                  {/* status badge + status switcher */}
                  <div className="flex flex-col sm:flex-row sm:items-center gap-4">
                    <div className="flex items-center gap-2">
                      <span className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold ${statusConf.bg} ${statusConf.text}`}>
                        <StatusIcon className="h-4 w-4" />
                        {statusConf.label}
                      </span>
                    </div>
                    <div className="flex-1" />
                    <div className="flex items-center gap-2 flex-wrap">
                      <span className="text-xs text-gray-500 mr-1">Change status:</span>
                      {STATUSES.map((s) => {
                        const sc = STATUS_CONFIG[s]
                        const active = s === currentStatus
                        return (
                          <button
                            key={s}
                            disabled={active || changingStatus}
                            onClick={() => handleStatusChange(s)}
                            className={`rounded-lg px-3 py-1.5 text-xs font-medium border transition ${
                              active
                                ? `${sc.bg} ${sc.text} border-transparent cursor-default`
                                : 'border-gray-200 text-gray-600 hover:bg-gray-50 disabled:opacity-40'
                            }`}
                          >
                            {sc.label}
                          </button>
                        )
                      })}
                    </div>
                  </div>

                  {/* status feedback */}
                  {changingStatus && (
                    <div className="rounded-lg bg-blue-50 border border-blue-100 px-3 py-2 text-sm text-blue-700 flex items-center gap-2">
                      <ArrowPathIcon className="h-4 w-4 animate-spin" /> Updating status…
                    </div>
                  )}
                  {statusMsg && (
                    <div className="rounded-lg bg-green-50 border border-green-200 px-3 py-2 text-sm text-green-700 flex items-center gap-2">
                      <CheckCircleIcon className="h-4 w-4" /> {statusMsg}
                    </div>
                  )}
                  {statusErr && (
                    <div className="rounded-lg bg-red-50 border border-red-200 px-3 py-2 text-sm text-red-700 flex items-center gap-2">
                      <ExclamationCircleIcon className="h-4 w-4" /> {statusErr}
                    </div>
                  )}

                  {/* ── two-column info cards ── */}
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    {/* Customer info */}
                    <div className="rounded-xl border border-gray-100 bg-gray-50/50 p-4 space-y-2">
                      <div className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] mb-1">
                        <UserIcon className="h-4 w-4" /> Customer
                      </div>
                      <InfoRow label="Name" value={invoice.buyer_name} />
                      <InfoRow label="Email" value={invoice.buyer_email} />
                      <InfoRow label="Street" value={invoice.buyer_street} />
                      <InfoRow label="City" value={[invoice.buyer_postal_code, invoice.buyer_city].filter(Boolean).join(' ')} />
                      <InfoRow label="Country" value={invoice.buyer_country} />
                      <InfoRow label="User ID" value={invoice.user_id != null ? String(invoice.user_id) : null} />
                    </div>

                    {/* Financial info */}
                    <div className="rounded-xl border border-gray-100 bg-gray-50/50 p-4 space-y-2">
                      <div className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] mb-1">
                        <BanknotesIcon className="h-4 w-4" /> Financials
                      </div>
                      <InfoRow label="Net" value={fmtMoney(invoice.total_net, invoice.currency ?? 'EUR')} />
                      <InfoRow label="Tax" value={fmtMoney(invoice.total_tax, invoice.currency ?? 'EUR')} />
                      <InfoRow label="Gross" value={fmtMoney(invoice.total_gross, invoice.currency ?? 'EUR')} highlight />
                      <InfoRow label="VAT Rate" value={invoice.vat_rate != null ? `${invoice.vat_rate}%` : '—'} />
                      <InfoRow label="Currency" value={invoice.currency ?? 'EUR'} />
                    </div>
                  </div>

                  {/* Dates */}
                  <div className="rounded-xl border border-gray-100 bg-gray-50/50 p-4">
                    <div className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] mb-2">
                      <CalendarDaysIcon className="h-4 w-4" /> Dates
                    </div>
                    <div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
                      <DateChip label="Issued" value={invoice.issued_at} />
                      <DateChip label="Due" value={invoice.due_at} />
                      <DateChip label="Created" value={invoice.created_at} />
                      <DateChip label="Updated" value={invoice.updated_at} />
                    </div>
                  </div>

                  {/* Line items */}
                  <div className="rounded-xl border border-gray-100 bg-gray-50/50 p-4">
                    <div className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] mb-3">
                      <DocumentTextIcon className="h-4 w-4" /> Line Items
                    </div>
                    {detailLoading ? (
                      <div className="space-y-2">
                        <div className="h-4 w-3/4 bg-gray-200 animate-pulse rounded" />
                        <div className="h-4 w-1/2 bg-gray-200 animate-pulse rounded" />
                      </div>
                    ) : detailError ? (
                      <div className="text-sm text-red-600">{detailError}</div>
                    ) : items.length === 0 ? (
                      <div className="text-sm text-gray-500">No line items found.</div>
                    ) : (
                      <div className="overflow-x-auto">
                        <table className="min-w-full text-sm">
                          <thead>
                            <tr className="text-left text-xs uppercase text-gray-500 border-b border-gray-200">
                              <th className="pb-2 pr-4 font-medium">Description</th>
                              <th className="pb-2 pr-4 font-medium">Qty</th>
                              <th className="pb-2 pr-4 font-medium">Unit Price</th>
                              <th className="pb-2 pr-4 font-medium">Tax</th>
                              <th className="pb-2 pr-4 font-medium text-right">Gross</th>
                            </tr>
                          </thead>
                          <tbody className="divide-y divide-gray-100">
                            {items.map((item, i) => (
                              <tr key={item.id ?? i}>
                                <td className="py-2 pr-4 text-gray-800">{item.description || '—'}</td>
                                <td className="py-2 pr-4 text-gray-600">{item.quantity ?? 0}</td>
                                <td className="py-2 pr-4 text-gray-600">{fmtMoney(item.unit_price)}</td>
                                <td className="py-2 pr-4 text-gray-600">{item.tax_rate != null ? `${item.tax_rate}%` : '—'}</td>
                                <td className="py-2 pr-4 text-right font-medium text-gray-800">{fmtMoney(item.line_gross)}</td>
                              </tr>
                            ))}
                          </tbody>
                          <tfoot>
                            <tr className="border-t border-gray-200">
                              <td colSpan={4} className="pt-2 text-right font-semibold text-gray-700">Total</td>
                              <td className="pt-2 text-right font-bold text-[#1C2B4A]">{fmtMoney(invoice.total_gross)}</td>
                            </tr>
                          </tfoot>
                        </table>
                      </div>
                    )}
                  </div>

                  {/* Payments */}
                  {payments.length > 0 && (
                    <div className="rounded-xl border border-gray-100 bg-gray-50/50 p-4">
                      <div className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] mb-3">
                        <ShieldCheckIcon className="h-4 w-4" /> Payments
                      </div>
                      <div className="overflow-x-auto">
                        <table className="min-w-full text-sm">
                          <thead>
                            <tr className="text-left text-xs uppercase text-gray-500 border-b border-gray-200">
                              <th className="pb-2 pr-4 font-medium">Method</th>
                              <th className="pb-2 pr-4 font-medium">Transaction</th>
                              <th className="pb-2 pr-4 font-medium">Amount</th>
                              <th className="pb-2 pr-4 font-medium">Paid At</th>
                              <th className="pb-2 pr-4 font-medium">Status</th>
                            </tr>
                          </thead>
                          <tbody className="divide-y divide-gray-100">
                            {payments.map((p, i) => (
                              <tr key={p.id ?? i}>
                                <td className="py-2 pr-4 text-gray-700">{p.payment_method ?? '—'}</td>
                                <td className="py-2 pr-4 text-gray-600 font-mono text-xs">{p.transaction_id ?? '—'}</td>
                                <td className="py-2 pr-4 text-gray-700">{p.amount != null ? fmtMoney(p.amount) : '—'}</td>
                                <td className="py-2 pr-4 text-gray-600">{fmtDateTime(p.paid_at)}</td>
                                <td className="py-2 pr-4">
                                  <span className="inline-flex rounded-full px-2 py-0.5 text-xs font-medium bg-green-50 text-green-700">
                                    {p.status ?? '—'}
                                  </span>
                                </td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  )}

                  {/* Context (raw JSON if present) */}
                  {invoice.context && (
                    <details className="rounded-xl border border-gray-100 bg-gray-50/50 p-4 group">
                      <summary className="flex items-center gap-2 text-sm font-semibold text-[#1C2B4A] cursor-pointer select-none">
                        <ClockIcon className="h-4 w-4" /> Context / Metadata
                        <span className="text-xs font-normal text-gray-400 ml-1">(click to expand)</span>
                      </summary>
                      <pre className="mt-3 text-xs text-gray-600 overflow-x-auto whitespace-pre-wrap break-all max-h-48">
                        {typeof invoice.context === 'string' ? invoice.context : JSON.stringify(invoice.context, null, 2)}
                      </pre>
                    </details>
                  )}
                </div>

                {/* ─── footer actions ─── */}
                <div className="bg-gray-50 border-t border-gray-100 px-6 py-4 flex items-center justify-between gap-3">
                  <div className="flex items-center gap-2">
                    <button
                      onClick={() => onExport?.(invoice)}
                      className="inline-flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition"
                    >
                      <ArrowDownTrayIcon className="h-4 w-4" /> Export JSON
                    </button>
                    <button
                      onClick={() => onRunPoolCheck?.(invoice.id)}
                      className="inline-flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition"
                    >
                      <ArrowPathIcon className="h-4 w-4" /> Pool Check
                    </button>
                  </div>
                  <button
                    onClick={onClose}
                    className="inline-flex items-center rounded-lg bg-[#1C2B4A] px-4 py-2 text-sm font-semibold text-white hover:bg-[#1C2B4A]/90 transition"
                  >
                    Close
                  </button>
                </div>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  )
}

/* ---------- sub-components ---------- */
function InfoRow({ label, value, highlight = false }: { label: string; value?: string | null; highlight?: boolean }) {
  return (
    <div className="flex items-baseline justify-between gap-2 text-sm">
      <span className="text-gray-500 shrink-0">{label}</span>
      <span className={`text-right truncate ${highlight ? 'font-semibold text-[#1C2B4A]' : 'text-gray-800'}`}>
        {value || '—'}
      </span>
    </div>
  )
}

function DateChip({ label, value }: { label: string; value?: string | null }) {
  return (
    <div>
      <div className="text-xs text-gray-500">{label}</div>
      <div className="text-sm text-gray-800 font-medium">{fmtDate(value)}</div>
    </div>
  )
}
