import React from 'react';
import { CreditCard, Download, Loader2, RefreshCw, Sparkles } from 'lucide-react';

import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';

import { AdminLayout } from '../components/AdminLayout';
import {
  CreditLedgerEntry,
  getCreditBalance,
  getCreditLedger,
  getTenantPackagesOverview,
  PaginationMeta,
  TenantPackageSummary,
} from '../api';
import { isAuthError } from '../auth/tokens';

type LedgerState = {
  entries: CreditLedgerEntry[];
  meta: PaginationMeta | null;
};

export default function BillingPage() {
  const [balance, setBalance] = React.useState<number>(0);
  const [packages, setPackages] = React.useState<TenantPackageSummary[]>([]);
  const [activePackage, setActivePackage] = React.useState<TenantPackageSummary | null>(null);
  const [ledger, setLedger] = React.useState<LedgerState>({ entries: [], meta: null });
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [loadingMore, setLoadingMore] = React.useState(false);

  React.useEffect(() => {
    void loadAll();
  }, []);

  async function loadAll() {
    setLoading(true);
    setError(null);
    try {
      const [balanceResult, packagesResult, ledgerResult] = await Promise.all([
        safeCall(() => getCreditBalance()),
        safeCall(() => getTenantPackagesOverview()),
        safeCall(() => getCreditLedger(1)),
      ]);

      if (balanceResult?.balance !== undefined) {
        setBalance(balanceResult.balance);
      }

      if (packagesResult) {
        setPackages(packagesResult.packages);
        setActivePackage(packagesResult.activePackage);
      }

      if (ledgerResult) {
        setLedger({ entries: ledgerResult.data, meta: ledgerResult.meta });
      } else {
        setLedger({ entries: [], meta: null });
      }
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Billing Daten konnten nicht geladen werden.');
      }
    } finally {
      setLoading(false);
    }
  }

  async function loadMore() {
    if (!ledger.meta || loadingMore) {
      return;
    }
    const { current_page, last_page } = ledger.meta;
    if (current_page >= last_page) {
      return;
    }

    setLoadingMore(true);
    try {
      const next = await getCreditLedger(current_page + 1);
      setLedger({
        entries: [...ledger.entries, ...next.data],
        meta: next.meta,
      });
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Weitere Ledger Eintraege konnten nicht geladen werden.');
      }
    } finally {
      setLoadingMore(false);
    }
  }

  const actions = (
    <Button variant="outline" onClick={() => void loadAll()} disabled={loading}>
      {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />}
      Aktualisieren
    </Button>
  );

  return (
    <AdminLayout
      title="Billing und Credits"
      subtitle="Verwalte Guthaben, Pakete und Abrechnungen."
      actions={actions}
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>Fehler</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {loading ? (
        <BillingSkeleton />
      ) : (
        <>
          <Card className="border-0 bg-white/85 shadow-xl shadow-pink-100/60">
            <CardHeader className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
              <div>
                <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
                  <CreditCard className="h-5 w-5 text-pink-500" />
                  Credits und Status
                </CardTitle>
                <CardDescription className="text-sm text-slate-600">
                  Dein aktuelles Guthaben und das aktive Reseller Paket.
                </CardDescription>
              </div>
              <Badge className={activePackage ? 'bg-pink-500/10 text-pink-700' : 'bg-slate-200 text-slate-700'}>
                {activePackage ? activePackage.package_name : 'Kein aktives Paket'}
              </Badge>
            </CardHeader>
            <CardContent className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
              <InfoCard label="Verfuegbare Credits" value={balance} tone="pink" />
              <InfoCard
                label="Genutzte Events"
                value={activePackage?.used_events ?? 0}
                tone="amber"
                helper={`Verfuegbar: ${activePackage?.remaining_events ?? 0}`}
              />
              <InfoCard
                label="Preis (netto)"
                value={formatCurrency(activePackage?.price)}
                tone="sky"
                helper={activePackage?.currency ?? 'EUR'}
              />
              <InfoCard
                label="Ablauf"
                value={formatDate(activePackage?.expires_at)}
                tone="emerald"
                helper="Automatisch verlaengern falls aktiv"
              />
            </CardContent>
          </Card>

          <Card className="border-0 bg-white/85 shadow-xl shadow-amber-100/60">
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
                <Sparkles className="h-5 w-5 text-amber-500" />
                Paket Historie
              </CardTitle>
              <CardDescription className="text-sm text-slate-600">
                Uebersicht ueber aktive und vergangene Reseller Pakete.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-3">
              {packages.length === 0 ? (
                <EmptyState message="Noch keine Pakete gebucht." />
              ) : (
                packages.map((pkg) => (
                  <PackageCard key={pkg.id} pkg={pkg} isActive={pkg.active} />
                ))
              )}
            </CardContent>
          </Card>

          <Card className="border-0 bg-white/85 shadow-xl shadow-sky-100/60">
            <CardHeader className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
              <div>
                <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
                  <Sparkles className="h-5 w-5 text-sky-500" />
                  Credit Ledger
                </CardTitle>
                <CardDescription className="text-sm text-slate-600">
                  Alle Zu- und Abbuchungen deines Credits Kontos.
                </CardDescription>
              </div>
              <Button variant="outline" size="sm">
                <Download className="h-4 w-4" />
                Export als CSV
              </Button>
            </CardHeader>
            <CardContent className="space-y-2">
              {ledger.entries.length === 0 ? (
                <EmptyState message="Noch keine Ledger Eintraege vorhanden." />
              ) : (
                <>
                  {ledger.entries.map((entry) => (
                    <LedgerRow key={`${entry.id}-${entry.created_at}`} entry={entry} />
                  ))}
                  {ledger.meta && ledger.meta.current_page < ledger.meta.last_page && (
                    <Button variant="outline" className="w-full" onClick={() => void loadMore()} disabled={loadingMore}>
                      {loadingMore ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Mehr laden'}
                    </Button>
                  )}
                </>
              )}
            </CardContent>
          </Card>
        </>
      )}
    </AdminLayout>
  );
}

async function safeCall<T>(callback: () => Promise<T>): Promise<T | null> {
  try {
    return await callback();
  } catch (error) {
    if (!isAuthError(error)) {
      console.warn('[Tenant Billing] optional endpoint fehlgeschlagen', error);
    }
    return null;
  }
}

function InfoCard({
  label,
  value,
  helper,
  tone,
}: {
  label: string;
  value: string | number | null | undefined;
  helper?: string;
  tone: 'pink' | 'amber' | 'sky' | 'emerald';
}) {
  const toneClass = {
    pink: 'from-pink-50 to-rose-100 text-pink-700',
    amber: 'from-amber-50 to-yellow-100 text-amber-700',
    sky: 'from-sky-50 to-blue-100 text-sky-700',
    emerald: 'from-emerald-50 to-green-100 text-emerald-700',
  }[tone];

  return (
    <div className={`rounded-2xl border border-white/60 bg-gradient-to-br ${toneClass} p-5 shadow-sm`}>
      <span className="text-xs uppercase tracking-wide text-slate-600/90">{label}</span>
      <div className="mt-3 text-xl font-semibold">{value ?? '--'}</div>
      {helper && <p className="mt-2 text-xs text-slate-600/80">{helper}</p>}
    </div>
  );
}

function PackageCard({ pkg, isActive }: { pkg: TenantPackageSummary; isActive: boolean }) {
  return (
    <div className="rounded-2xl border border-amber-100 bg-white/90 p-4 shadow-sm">
      <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h3 className="text-sm font-semibold text-slate-900">{pkg.package_name}</h3>
          <p className="text-xs text-slate-600">
            {formatDate(pkg.purchased_at)} - {formatCurrency(pkg.price)} {pkg.currency ?? 'EUR'}
          </p>
        </div>
        <Badge className={isActive ? 'bg-amber-500/10 text-amber-700' : 'bg-slate-200 text-slate-700'}>
          {isActive ? 'Aktiv' : 'Inaktiv'}
        </Badge>
      </div>
      <Separator className="my-3" />
      <div className="grid gap-2 text-xs text-slate-600 sm:grid-cols-3">
        <span>Genutzte Events: {pkg.used_events}</span>
        <span>Verfuegbar: {pkg.remaining_events ?? '--'}</span>
        <span>Ablauf: {formatDate(pkg.expires_at)}</span>
      </div>
    </div>
  );
}

function LedgerRow({ entry }: { entry: CreditLedgerEntry }) {
  const positive = entry.delta >= 0;
  return (
    <div className="flex flex-col gap-2 rounded-2xl border border-slate-100 bg-white/90 p-4 shadow-sm sm:flex-row sm:items-center sm:justify-between">
      <div>
        <p className="text-sm font-semibold text-slate-900">{mapReason(entry.reason)}</p>
        {entry.note && <p className="text-xs text-slate-500">{entry.note}</p>}
      </div>
      <div className="flex items-center gap-4">
        <span className={`text-sm font-semibold ${positive ? 'text-emerald-600' : 'text-rose-600'}`}>
          {positive ? '+' : ''}
          {entry.delta}
        </span>
        <span className="text-xs text-slate-500">{formatDate(entry.created_at)}</span>
      </div>
    </div>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <div className="flex flex-col items-center justify-center gap-3 rounded-2xl border border-dashed border-slate-200 bg-white/70 p-8 text-center">
      <div className="rounded-full bg-pink-100 p-3 text-pink-600 shadow-inner shadow-pink-200/80">
        <Sparkles className="h-5 w-5" />
      </div>
      <p className="text-sm text-slate-600">{message}</p>
    </div>
  );
}

function BillingSkeleton() {
  return (
    <div className="grid gap-6">
      {Array.from({ length: 3 }).map((_, index) => (
        <div key={index} className="space-y-4 rounded-2xl border border-white/60 bg-white/70 p-6 shadow-sm">
          <div className="h-6 w-48 animate-pulse rounded bg-gradient-to-r from-white/40 via-white/60 to-white/40" />
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            {Array.from({ length: 4 }).map((__, placeholderIndex) => (
              <div
                key={placeholderIndex}
                className="h-24 animate-pulse rounded-2xl bg-gradient-to-r from-white/40 via-white/60 to-white/40"
              />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function mapReason(reason: string): string {
  switch (reason) {
    case 'purchase':
      return 'Credit Kauf';
    case 'usage':
      return 'Verbrauch';
    case 'manual':
      return 'Manuelle Anpassung';
    default:
      return reason;
  }
}

function formatDate(value: string | null | undefined): string {
  if (!value) return '--';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '--';
  return date.toLocaleDateString('de-DE', { day: '2-digit', month: 'short', year: 'numeric' });
}

function formatCurrency(value: number | null | undefined): string {
  if (value === null || value === undefined) return '--';
  return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(value);
}
