﻿import React from 'react';
import { AlertTriangle, Loader2, RefreshCw, Sparkles, ArrowUpRight } from 'lucide-react';
import { useTranslation } from 'react-i18next';

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

import { AdminLayout } from '../components/AdminLayout';
import { getTenantPackagesOverview, getTenantPaddleTransactions, PaddleTransactionSummary, TenantPackageSummary } from '../api';
import { isAuthError } from '../auth/tokens';
import {
  TenantHeroCard,
  FrostedCard,
  FrostedSurface,
  tenantHeroPrimaryButtonClass,
  tenantHeroSecondaryButtonClass,
} from '../components/tenant';

type PackageWarning = { id: string; tone: 'warning' | 'danger'; message: string };

export default function BillingPage() {
  const { t, i18n } = useTranslation(['management', 'dashboard']);
  const locale = React.useMemo(
    () => (i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE'),
    [i18n.language]
  );

  const [packages, setPackages] = React.useState<TenantPackageSummary[]>([]);
  const [activePackage, setActivePackage] = React.useState<TenantPackageSummary | null>(null);
  const [transactions, setTransactions] = React.useState<PaddleTransactionSummary[]>([]);
  const [transactionCursor, setTransactionCursor] = React.useState<string | null>(null);
  const [transactionsHasMore, setTransactionsHasMore] = React.useState(false);
  const [transactionsLoading, setTransactionsLoading] = React.useState(false);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);

  const formatDate = React.useCallback(
    (value: string | null | undefined) => {
      if (!value) return '--';
      const date = new Date(value);
      if (Number.isNaN(date.getTime())) return '--';
      return date.toLocaleDateString(locale, { day: '2-digit', month: 'short', year: 'numeric' });
    },
    [locale]
  );

  const formatCurrency = React.useCallback(
    (value: number | null | undefined, currency = 'EUR') => {
      if (value === null || value === undefined) return '--';
      return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);
    },
    [locale]
  );

  const packageLabels = React.useMemo(
    () => ({
      statusActive: t('billing.sections.packages.card.statusActive'),
      statusInactive: t('billing.sections.packages.card.statusInactive'),
      used: t('billing.sections.packages.card.used'),
      available: t('billing.sections.packages.card.available'),
      expires: t('billing.sections.packages.card.expires'),
    }),
    [t]
  );

  const loadAll = React.useCallback(async (force = false) => {
    setLoading(true);
    setError(null);
    try {
      const [packagesResult, paddleTransactions] = await Promise.all([
        getTenantPackagesOverview(force ? { force: true } : undefined),
        getTenantPaddleTransactions().catch((err) => {
          console.warn('Failed to load Paddle transactions', err);
          return { data: [] as PaddleTransactionSummary[], nextCursor: null, hasMore: false };
        }),
      ]);
      setPackages(packagesResult.packages);
      setActivePackage(packagesResult.activePackage);
      setTransactions(paddleTransactions.data);
      setTransactionCursor(paddleTransactions.nextCursor);
      setTransactionsHasMore(paddleTransactions.hasMore);
    } catch (err) {
      if (!isAuthError(err)) {
        setError(t('billing.errors.load'));
      }
    } finally {
      setLoading(false);
    }
  }, [t]);

  const loadMoreTransactions = React.useCallback(async () => {
    if (!transactionsHasMore || transactionsLoading || !transactionCursor) {
      return;
    }

    setTransactionsLoading(true);
    try {
      const result = await getTenantPaddleTransactions(transactionCursor);
      setTransactions((current) => [...current, ...result.data]);
      setTransactionCursor(result.nextCursor);
      setTransactionsHasMore(result.hasMore && Boolean(result.nextCursor));
    } catch (error) {
      console.warn('Failed to load additional Paddle transactions', error);
      setTransactionsHasMore(false);
    } finally {
      setTransactionsLoading(false);
    }
  }, [transactionCursor, transactionsHasMore, transactionsLoading]);

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

  const activeWarnings = React.useMemo(
    () => buildPackageWarnings(activePackage, t, formatDate, 'billing.sections.overview.warnings'),
    [activePackage, t, formatDate],
  );

  const heroBadge = t('billing.hero.badge', 'Abrechnung');
  const heroDescription = t('billing.hero.description', 'Behalte Laufzeiten, Rechnungen und Limits deiner Pakete im Blick.');
  const heroSupporting: string[] = [
    activePackage
      ? t('billing.hero.summary.active', 'Aktives Paket: {{name}}', { name: activePackage.package_name })
      : t('billing.hero.summary.inactive', 'Noch kein aktives Paket – wählt ein Kontingent, das zu euch passt.'),
    t('billing.hero.summary.transactions', '{{count}} Zahlungen synchronisiert', { count: transactions.length })
  ];
  const packagesHref = `/${i18n.language?.split('-')[0] ?? 'de'}/packages`;
  const heroPrimaryAction = (
    <Button
      size="sm"
      className={tenantHeroPrimaryButtonClass}
      onClick={() => void loadAll(true)}
      disabled={loading}
    >
      {loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <RefreshCw className="mr-2 h-4 w-4" />}
      {t('billing.actions.refresh')}
    </Button>
  );
  const heroSecondaryAction = (
    <Button
      size="sm"
      className={tenantHeroSecondaryButtonClass}
      onClick={() => window.location.assign(packagesHref)}
    >
      {t('billing.actions.explorePackages', 'Pakete vergleichen')}
      <ArrowUpRight className="ml-2 h-4 w-4" />
    </Button>
  );
  const nextRenewalLabel = t('billing.hero.nextRenewal', 'Verlängerung am');
  const topWarning = activeWarnings[0];
  const heroAside = (
    <FrostedSurface className="space-y-4 border-white/25 p-5 text-slate-900 shadow-lg shadow-rose-300/20 dark:border-slate-800/70 dark:bg-slate-950/85">
      <div>
        <p className="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">
          {t('billing.hero.activePackage', 'Aktuelles Paket')}
        </p>
        <p className="mt-1 text-lg font-semibold text-slate-900 dark:text-slate-100">
          {activePackage?.package_name ?? t('billing.hero.activeFallback', 'Noch nicht ausgewählt')}
        </p>
      </div>
      <div>
        <p className="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">{nextRenewalLabel}</p>
        <p className="mt-1 text-sm font-medium text-slate-800 dark:text-slate-200">{formatDate(activePackage?.expires_at)}</p>
      </div>
      {topWarning ? (
        <div className="rounded-xl border border-amber-200/60 bg-amber-50/80 p-3 text-xs text-amber-800 shadow-inner shadow-amber-200/40 dark:border-amber-500/50 dark:bg-amber-500/15 dark:text-amber-200">
          {topWarning.message}
        </div>
      ) : null}
    </FrostedSurface>
  );

  return (
    <AdminLayout title={t('billing.title')} subtitle={t('billing.subtitle')}>
      <TenantHeroCard
        badge={heroBadge}
        title={t('billing.title')}
        description={heroDescription}
        supporting={heroSupporting}
        primaryAction={heroPrimaryAction}
        secondaryAction={heroSecondaryAction}
        aside={heroAside}
      />

      {error && (
        <Alert variant="destructive">
          <AlertTitle>{t('dashboard:alerts.errorTitle')}</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {loading ? (
        <BillingSkeleton />
      ) : (
        <>
          <FrostedCard className="mt-6 border border-white/20">
            <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-pink-500" />
                  {t('billing.sections.overview.title')}
                </CardTitle>
                <CardDescription className="text-sm text-slate-600">
                  {t('billing.sections.overview.description')}
                </CardDescription>
              </div>
              <Badge className={activePackage ? 'bg-pink-500/10 text-pink-700 dark:bg-pink-500/20 dark:text-pink-200' : 'bg-slate-200 text-slate-700 dark:bg-slate-800 dark:text-slate-200'}>
                {activePackage ? activePackage.package_name : t('billing.sections.overview.emptyBadge')}
              </Badge>
            </CardHeader>
            <CardContent>
              {activePackage ? (
                <div className="space-y-4">
                  {activeWarnings.length > 0 && (
                    <div className="space-y-2">
                      {activeWarnings.map((warning) => (
                        <Alert
                          key={warning.id}
                          variant={warning.tone === 'danger' ? 'destructive' : 'default'}
                          className={warning.tone === 'warning' ? 'border-amber-400/40 bg-amber-50 text-amber-900 dark:border-amber-500/60 dark:bg-amber-500/15 dark:text-amber-200' : 'dark:border-slate-800/70 dark:bg-slate-950/80'}
                        >
                          <AlertDescription className="flex items-center gap-2 text-sm">
                            <AlertTriangle className="h-4 w-4" />
                            {warning.message}
                          </AlertDescription>
                        </Alert>
                      ))}
                    </div>
                  )}

                  <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
                    <InfoCard
                      label={t('billing.sections.overview.cards.package.label')}
                      value={activePackage.package_name}
                      tone="pink"
                      helper={t('billing.sections.overview.cards.package.helper')}
                    />
                    <InfoCard
                      label={t('billing.sections.overview.cards.used.label')}
                      value={activePackage.used_events ?? 0}
                      tone="amber"
                      helper={t('billing.sections.overview.cards.used.helper', {
                        count: activePackage.remaining_events ?? 0,
                      })}
                    />
                    <InfoCard
                      label={t('billing.sections.overview.cards.price.label')}
                      value={formatCurrency(activePackage.price ?? null, activePackage.currency ?? 'EUR')}
                      tone="sky"
                      helper={activePackage.currency ?? 'EUR'}
                    />
                    <InfoCard
                      label={t('billing.sections.overview.cards.expires.label')}
                      value={formatDate(activePackage.expires_at)}
                      tone="emerald"
                      helper={t('billing.sections.overview.cards.expires.helper')}
                    />
                  </div>
                </div>
              ) : (
                <EmptyState message={t('billing.sections.overview.empty')} />
              )}
            </CardContent>
          </FrostedCard>

          <FrostedCard className="border border-white/20">
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
                <Sparkles className="h-5 w-5 text-amber-500" />
                {t('billing.sections.packages.title')}
              </CardTitle>
              <CardDescription className="text-sm text-slate-600">
                {t('billing.sections.packages.description')}
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-3">
              {packages.length === 0 ? (
                <EmptyState message={t('billing.sections.packages.empty')} />
              ) : (
                packages.map((pkg) => {
                  const warnings = buildPackageWarnings(pkg, t, formatDate, 'billing.sections.packages.card.warnings');
                  return (
                    <PackageCard
                      key={pkg.id}
                      pkg={pkg}
                      isActive={Boolean(pkg.active)}
                      labels={packageLabels}
                      formatDate={formatDate}
                      formatCurrency={formatCurrency}
                      warnings={warnings}
                    />
                  );
                })
              )}
            </CardContent>
          </FrostedCard>

          <FrostedCard className="border border-white/20">
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
                <Sparkles className="h-5 w-5 text-sky-500" />
                {t('billing.sections.transactions.title')}
              </CardTitle>
              <CardDescription className="text-sm text-slate-600">
                {t('billing.sections.transactions.description')}
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-3">
              {transactions.length === 0 ? (
                <EmptyState message={t('billing.sections.transactions.empty')} />
              ) : (
                <div className="grid gap-3">
                  {transactions.map((transaction) => (
                    <TransactionCard
                      key={transaction.id ?? Math.random().toString(36).slice(2)}
                      transaction={transaction}
                      formatCurrency={formatCurrency}
                      formatDate={formatDate}
                      locale={locale}
                      t={t}
                    />
                  ))}
                </div>
              )}
              {transactionsHasMore && (
                <Button
                  variant="outline"
                  onClick={() => void loadMoreTransactions()}
                  disabled={transactionsLoading}
                >
                  {transactionsLoading ? (
                    <>
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      {t('billing.sections.transactions.loadingMore')}
                    </>
                  ) : (
                    t('billing.sections.transactions.loadMore')
                  )}
                </Button>
              )}
            </CardContent>
          </FrostedCard>

        </>
      )}
    </AdminLayout>
  );
}

function TransactionCard({
  transaction,
  formatCurrency,
  formatDate,
  locale,
  t,
}: {
  transaction: PaddleTransactionSummary;
  formatCurrency: (value: number | null | undefined, currency?: string) => string;
  formatDate: (value: string | null | undefined) => string;
  locale: string;
  t: (key: string, options?: Record<string, unknown>) => string;
}) {
  const amount = transaction.grand_total ?? transaction.amount ?? null;
  const currency = transaction.currency ?? 'EUR';
  const createdAtIso = transaction.created_at ?? null;
  const createdAt = createdAtIso ? new Date(createdAtIso) : null;
  const createdLabel = createdAt
    ? createdAt.toLocaleString(locale, {
        year: 'numeric',
        month: 'short',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
      })
    : formatDate(createdAtIso);
  const statusKey = transaction.status ? `billing.sections.transactions.status.${transaction.status}` : 'billing.sections.transactions.status.unknown';
  const statusText = t(statusKey, {
    defaultValue: (transaction.status ?? 'unknown').replace(/_/g, ' '),
  });

  return (
    <FrostedSurface className="flex flex-col gap-3 border border-slate-200/60 p-4 text-slate-900 shadow-md shadow-slate-200/10 transition-colors duration-200 dark:border-slate-800/70 dark:bg-slate-950/80 md:flex-row md:items-center md:justify-between">
      <div className="space-y-1">
        <p className="text-sm font-semibold text-slate-800 dark:text-slate-100">
          {t('billing.sections.transactions.labels.transactionId', { id: transaction.id ?? '—' })}
        </p>
        <p className="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">{createdLabel}</p>
        {transaction.checkout_id ? (
          <p className="text-xs text-slate-500 dark:text-slate-400">
            {t('billing.sections.transactions.labels.checkoutId', { id: transaction.checkout_id })}
          </p>
        ) : null}
        {transaction.origin ? (
          <p className="text-xs text-slate-500 dark:text-slate-400">
            {t('billing.sections.transactions.labels.origin', { origin: transaction.origin })}
          </p>
        ) : null}
      </div>
      <div className="flex flex-col items-start gap-2 text-sm font-medium text-slate-700 dark:text-slate-300 md:flex-row md:items-center md:gap-4">
        <Badge className="bg-sky-100 text-sky-700 dark:bg-sky-500/20 dark:text-sky-200">
          {statusText}
        </Badge>
        <div className="text-base font-semibold text-slate-900 dark:text-slate-100">
          {formatCurrency(amount, currency)}
        </div>
        {transaction.tax !== undefined && transaction.tax !== null ? (
          <span className="text-xs text-slate-500 dark:text-slate-400">
            {t('billing.sections.transactions.labels.tax', { value: formatCurrency(transaction.tax, currency) })}
          </span>
        ) : null}
        {transaction.receipt_url ? (
          <a
            href={transaction.receipt_url}
            target="_blank"
            rel="noreferrer"
            className="text-xs font-medium text-sky-600 transition hover:text-sky-700 dark:text-sky-300 dark:hover:text-sky-200"
          >
            {t('billing.sections.transactions.labels.receipt')}
          </a>
        ) : null}
      </div>
    </FrostedSurface>
  );
}

function InfoCard({
  label,
  value,
  helper,
  tone,
}: {
  label: string;
  value: string | number | null | undefined;
  helper?: string;
  tone: 'pink' | 'amber' | 'sky' | 'emerald';
}) {
  const toneBorders: Record<'pink' | 'amber' | 'sky' | 'emerald', string> = {
    pink: 'border-pink-200/60 shadow-rose-200/30',
    amber: 'border-amber-200/60 shadow-amber-200/30',
    sky: 'border-sky-200/60 shadow-sky-200/30',
    emerald: 'border-emerald-200/60 shadow-emerald-200/30',
  } as const;

  return (
    <FrostedSurface className={`border ${toneBorders[tone]} p-5 text-slate-900 shadow-md transition-colors duration-200 dark:text-slate-100`}>
      <span className="text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400">{label}</span>
      <div className="mt-3 text-xl font-semibold">{value ?? '--'}</div>
      {helper ? <p className="mt-2 text-xs text-slate-600 dark:text-slate-400">{helper}</p> : null}
    </FrostedSurface>
  );
}

function PackageCard({
  pkg,
  isActive,
  labels,
  formatDate,
  formatCurrency,
  warnings = [],
}: {
  pkg: TenantPackageSummary;
  isActive: boolean;
  labels: {
    statusActive: string;
    statusInactive: string;
    used: string;
    available: string;
    expires: string;
  };
  formatDate: (value: string | null | undefined) => string;
  formatCurrency: (value: number | null | undefined, currency?: string) => string;
  warnings?: PackageWarning[];
}) {
  return (
    <FrostedSurface className={`space-y-4 border ${isActive ? 'border-amber-200/60 shadow-amber-200/20' : 'border-slate-200/60 shadow-slate-200/20'} p-5 text-slate-900 dark:text-slate-100`}>
      {warnings.length > 0 && (
        <div className="mb-3 space-y-2">
          {warnings.map((warning) => (
            <Alert
              key={warning.id}
              variant={warning.tone === 'danger' ? 'destructive' : 'default'}
              className={warning.tone === 'warning' ? 'border-amber-400/40 bg-amber-50 text-amber-900 dark:border-amber-500/50 dark:bg-amber-500/15 dark:text-amber-200' : 'dark:border-slate-800/70 dark:bg-slate-950/80'}
            >
              <AlertDescription className="flex items-center gap-2 text-xs">
                <AlertTriangle className="h-4 w-4" />
                {warning.message}
              </AlertDescription>
            </Alert>
          ))}
        </div>
      )}
      <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 dark:text-slate-100">{pkg.package_name}</h3>
          <p className="text-xs text-slate-600 dark:text-slate-400">
            {formatDate(pkg.purchased_at)} · {formatCurrency(pkg.price, pkg.currency ?? 'EUR')}
          </p>
        </div>
        <Badge className={isActive ? 'bg-amber-500/15 text-amber-700 dark:bg-amber-500/20 dark:text-amber-200' : 'bg-slate-200 text-slate-700 dark:bg-slate-800 dark:text-slate-200'}>
          {isActive ? labels.statusActive : labels.statusInactive}
        </Badge>
      </div>
      <Separator className="my-3 dark:border-slate-800/70" />
      <div className="grid gap-2 text-xs text-slate-600 dark:text-slate-400 sm:grid-cols-3">
        <span>
          {labels.used}: {pkg.used_events}
        </span>
        <span>
          {labels.available}: {pkg.remaining_events ?? '--'}
        </span>
        <span>
          {labels.expires}: {formatDate(pkg.expires_at)}
        </span>
      </div>
    </FrostedSurface>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <FrostedSurface className="flex flex-col items-center justify-center gap-3 border border-dashed border-slate-200/70 p-8 text-center shadow-inner dark:border-slate-700/60">
      <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 dark:text-slate-400">{message}</p>
    </FrostedSurface>
  );
}

function buildPackageWarnings(
  pkg: TenantPackageSummary | null | undefined,
  translate: (key: string, options?: Record<string, unknown>) => string,
  formatDate: (value: string | null | undefined) => string,
  keyPrefix: string,
): PackageWarning[] {
  if (!pkg) {
    return [];
  }

  const warnings: PackageWarning[] = [];
  const remaining = typeof pkg.remaining_events === 'number' ? pkg.remaining_events : null;

  if (remaining !== null) {
    if (remaining <= 0) {
      warnings.push({
        id: `${pkg.id}-no-events`,
        tone: 'danger',
        message: translate(`${keyPrefix}.noEvents`),
      });
    } else if (remaining <= 2) {
      warnings.push({
        id: `${pkg.id}-low-events`,
        tone: 'warning',
        message: translate(`${keyPrefix}.lowEvents`, { remaining }),
      });
    }
  }

  const expiresAt = pkg.expires_at ? new Date(pkg.expires_at) : null;
  if (expiresAt && !Number.isNaN(expiresAt.getTime())) {
    const now = new Date();
    const diffMillis = expiresAt.getTime() - now.getTime();
    const diffDays = Math.ceil(diffMillis / (1000 * 60 * 60 * 24));
    const formatted = formatDate(pkg.expires_at);

    if (diffDays < 0) {
      warnings.push({
        id: `${pkg.id}-expired`,
        tone: 'danger',
        message: translate(`${keyPrefix}.expired`, { date: formatted }),
      });
    } else if (diffDays <= 14) {
      warnings.push({
        id: `${pkg.id}-expires`,
        tone: 'warning',
        message: translate(`${keyPrefix}.expiresSoon`, { date: formatted }),
      });
    }
  }

  return warnings;
}

function BillingSkeleton() {
  return (
    <div className="grid gap-6">
      {Array.from({ length: 3 }).map((_, index) => (
        <FrostedSurface
          key={index}
          className="space-y-4 border border-white/20 p-6 shadow-md shadow-rose-200/10 dark:border-slate-800/70 dark:bg-slate-950/80"
        >
          <div className="h-6 w-48 animate-pulse rounded bg-gradient-to-r from-white/30 via-white/60 to-white/30 dark:from-slate-700 dark:via-slate-600 dark:to-slate-700" />
          <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/30 via-white/55 to-white/30 dark:from-slate-800 dark:via-slate-700 dark:to-slate-800"
              />
            ))}
          </div>
        </FrostedSurface>
      ))}
    </div>
  );
}
