import React from 'react'
import { authFetch } from '../../utils/authFetch'
import { AboInvoice, useAboInvoices } from '../hooks/getAboInvoices'

type Props = {
  abonementId?: string | number | null
}

const BASE_URL = (process.env.NEXT_PUBLIC_API_BASE_URL || '').replace(/\/+$/, '')

const formatDate = (value?: string | null) => {
  if (!value) return '—'
  const d = new Date(value)
  return Number.isNaN(d.getTime()) ? '—' : d.toLocaleDateString('de-DE')
}

const formatMoney = (value?: string | number | null, currency?: string | null) => {
  if (value == null || value === '') return '—'
  const n = typeof value === 'string' ? Number(value) : value
  if (!Number.isFinite(Number(n))) return String(value)
  return new Intl.NumberFormat('de-DE', {
    style: 'currency',
    currency: currency || 'EUR',
  }).format(Number(n))
}

const isAbsUrl = (url: string) => /^https?:\/\//i.test(url)

const resolveInvoiceUrl = (invoice: AboInvoice) => {
  const raw = invoice.pdfUrl || invoice.downloadUrl || invoice.htmlUrl || invoice.fileUrl
  if (!raw) return null
  return isAbsUrl(raw) ? raw : `${BASE_URL}${raw.startsWith('/') ? '' : '/'}${raw}`
}

type UiLifecycleStatus = 'issued' | 'ongoing' | 'finished' | 'pause' | 'cancelled'

const normalizeInvoiceStatus = (rawStatus?: string | null): UiLifecycleStatus => {
  const status = (rawStatus || '').toLowerCase()
  if (!status) return 'issued'
  if (status === 'cancelled' || status === 'canceled' || status === 'void') return 'cancelled'
  if (status === 'pause' || status === 'paused') return 'pause'
  if (status === 'finished' || status === 'paid' || status === 'closed' || status === 'settled') return 'finished'
  if (status === 'ongoing' || status === 'active' || status === 'processing') return 'ongoing'
  if (status === 'issued' || status === 'draft' || status === 'pending') return 'issued'
  return 'issued'
}

const statusBadgeClass = (status: UiLifecycleStatus) => {
  if (status === 'ongoing') return 'bg-green-100 text-green-800'
  if (status === 'pause') return 'bg-amber-100 text-amber-800'
  if (status === 'cancelled') return 'bg-red-100 text-red-700'
  if (status === 'finished') return 'bg-gray-200 text-gray-700'
  return 'bg-blue-100 text-blue-800'
}

const displayStatus = (status: UiLifecycleStatus) =>
  status === 'pause'
    ? 'Pause'
    : status === 'cancelled'
      ? 'Cancelled'
      : status === 'ongoing'
        ? 'Ongoing'
        : status === 'finished'
          ? 'Finished'
          : 'Issued'

function downloadBlob(content: Blob, fileName: string) {
  const url = URL.createObjectURL(content)
  const a = document.createElement('a')
  a.href = url
  a.download = fileName
  document.body.appendChild(a)
  a.click()
  a.remove()
  URL.revokeObjectURL(url)
}

export default function FinanceInvoices({ abonementId }: Props) {
  const { data: invoices, loading, error } = useAboInvoices(abonementId)
  const [busyId, setBusyId] = React.useState<string | number | null>(null)
  const [actionError, setActionError] = React.useState<string | null>(null)

  const onView = (invoice: AboInvoice) => {
    setActionError(null)
    const url = resolveInvoiceUrl(invoice)
    if (!url) {
      setActionError('No view URL is available for this invoice.')
      return
    }
    window.open(url, '_blank', 'noopener,noreferrer')
  }

  const onDownload = async (invoice: AboInvoice) => {
    setActionError(null)
    setBusyId(invoice.id)
    try {
      const url = resolveInvoiceUrl(invoice)
      if (url) {
        const res = await authFetch(url, { method: 'GET' })
        if (!res.ok) throw new Error(`Download failed: ${res.status}`)
        const blob = await res.blob()
        const invoiceNo = invoice.invoiceNumber || String(invoice.id)
        const ext = invoice.pdfUrl ? 'pdf' : 'html'
        downloadBlob(blob, `invoice-${invoiceNo}.${ext}`)
      } else {
        const blob = new Blob([JSON.stringify(invoice.raw, null, 2)], { type: 'application/json' })
        downloadBlob(blob, `invoice-${invoice.invoiceNumber || invoice.id}.json`)
      }
    } catch (e: any) {
      setActionError(e?.message || 'Failed to download invoice.')
    } finally {
      setBusyId(null)
    }
  }

  const onExportAll = () => {
    setActionError(null)
    if (!invoices.length) {
      setActionError('No invoices available to export.')
      return
    }
    const exportPayload = {
      exportedAt: new Date().toISOString(),
      abonementId: abonementId ?? null,
      count: invoices.length,
      invoices: invoices.map((inv) => ({
        id: inv.id,
        invoiceNumber: inv.invoiceNumber,
        issuedAt: inv.issuedAt,
        createdAt: inv.createdAt,
        totalNet: inv.totalNet,
        totalTax: inv.totalTax,
        totalGross: inv.totalGross,
        currency: inv.currency,
        status: inv.status,
      })),
    }
    const blob = new Blob([JSON.stringify(exportPayload, null, 2)], { type: 'application/json' })
    downloadBlob(blob, `invoices-export-${new Date().toISOString().slice(0, 10)}.json`)
  }

  return (
    <section className="space-y-4">
      <div className="flex items-center justify-between gap-3">
        <h2 className="text-lg font-semibold text-gray-900">Finance & Invoices</h2>
        <button
          onClick={onExportAll}
          disabled={!invoices.length || loading}
          className="rounded-md border border-gray-300 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-50 disabled:opacity-60 disabled:cursor-not-allowed"
        >
          Export all invoices
        </button>
      </div>

      {!abonementId ? (
        <div className="rounded-md border border-white/60 bg-white/70 backdrop-blur-md p-4 text-sm text-gray-600 shadow-lg">
          No subscription selected. Invoices will appear once you have an active subscription.
        </div>
      ) : loading ? (
        <div className="rounded-md border border-white/60 bg-white/70 backdrop-blur-md p-4 text-sm text-gray-600 shadow-lg">
          Loading invoices…
        </div>
      ) : error ? (
        <div className="rounded-md border border-red-200 bg-red-50/80 backdrop-blur-md p-4 text-sm text-red-700">
          {error}
        </div>
      ) : invoices.length === 0 ? (
        <div className="rounded-md border border-white/60 bg-white/70 backdrop-blur-md p-4 text-sm text-gray-600 shadow-lg">
          No invoices found for this subscription.
        </div>
      ) : (
        <div className="overflow-x-auto rounded-lg border border-white/60 bg-white/70 backdrop-blur-md shadow-lg">
          <table className="min-w-full text-sm">
            <thead className="bg-white/80">
              <tr className="text-left text-gray-700">
                <th className="px-4 py-3 font-semibold">Date</th>
                <th className="px-4 py-3 font-semibold">Invoice #</th>
                <th className="px-4 py-3 font-semibold">Status</th>
                <th className="px-4 py-3 font-semibold">Total</th>
                <th className="px-4 py-3 font-semibold">Actions</th>
              </tr>
            </thead>
            <tbody>
              {invoices.map((invoice) => (
                <tr key={invoice.id} className="border-t border-gray-200/70">
                  <td className="px-4 py-3 text-gray-800">{formatDate(invoice.issuedAt || invoice.createdAt)}</td>
                  <td className="px-4 py-3 text-gray-800">{invoice.invoiceNumber || `#${invoice.id}`}</td>
                  <td className="px-4 py-3 text-gray-700">
                    <span
                      className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${statusBadgeClass(normalizeInvoiceStatus(invoice.status))}`}
                    >
                      {displayStatus(normalizeInvoiceStatus(invoice.status))}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-gray-900 font-medium">{formatMoney(invoice.totalGross, invoice.currency)}</td>
                  <td className="px-4 py-3">
                    <div className="flex flex-wrap gap-2">
                      <button
                        onClick={() => onView(invoice)}
                        className="rounded-md border border-gray-300 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-50"
                      >
                        View
                      </button>
                      <button
                        onClick={() => onDownload(invoice)}
                        disabled={busyId === invoice.id}
                        className="rounded-md border border-gray-300 px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-50 disabled:opacity-60 disabled:cursor-not-allowed"
                      >
                        {busyId === invoice.id ? 'Downloading…' : 'Download'}
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {actionError && (
        <div className="rounded-md border border-red-200 bg-red-50/80 backdrop-blur-md p-3 text-xs text-red-700">
          {actionError}
        </div>
      )}
    </section>
  )
}
