import { useState, useEffect, useMemo } from 'react';
import { X, CheckCircle, Loader2, Minus, Plus } from 'lucide-react';
import { useConfigurableCaps, useConfigureSubscription } from '../hooks/useConfigurableCaps';

interface ConfiguratorPanelProps {
  onClose: () => void;
  onSuccess?: () => void;
}

/**
 * "Anpassen" panel — lets a customer scale every configurable capability
 * (extra seats / sites / commands) UP-ONLY from the plan's included baseline.
 * Shows a live monthly delta and applies the change via POST /subscription/configure
 * (immediate prorated billing handled server-side).
 */
export function ConfiguratorPanel({ onClose, onSuccess }: ConfiguratorPanelProps) {
  const { data, isLoading, isError } = useConfigurableCaps();
  const configure = useConfigureSubscription();

  const [totals, setTotals] = useState<Record<string, number>>({});
  const [isComplete, setIsComplete] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Seed local desired totals from the server snapshot once it loads.
  useEffect(() => {
    if (!data?.items) return;
    const seed: Record<string, number> = {};
    for (const item of data.items) seed[item.capabilityKey] = item.currentTotal;
    setTotals(seed);
  }, [data]);

  useEffect(() => {
    if (!isComplete) return;
    const timer = setTimeout(() => {
      onSuccess?.();
      onClose();
    }, 1800);
    return () => clearTimeout(timer);
  }, [isComplete, onSuccess, onClose]);

  const currency = (data?.currency ?? 'EUR').toUpperCase();
  const items = data?.items ?? [];

  const clamp = (total: number, included: number, max: number | null) => {
    let next = Math.floor(total);
    if (next < included) next = included;
    if (max != null && next > max) next = max;
    return next;
  };

  const monthlyDelta = useMemo(() => {
    let sum = 0;
    for (const item of items) {
      const total = totals[item.capabilityKey] ?? item.included;
      const extra = Math.max(0, total - item.included);
      if (extra > 0 && item.unitPrice) sum += extra * item.unitPrice;
    }
    return Number(sum.toFixed(2));
  }, [items, totals]);

  const dirty = useMemo(
    () => items.some((item) => (totals[item.capabilityKey] ?? item.currentTotal) !== item.currentTotal),
    [items, totals],
  );

  const handleApply = () => {
    setError(null);
    const payload = items.map((item) => ({
      capabilityKey: item.capabilityKey,
      quantity: totals[item.capabilityKey] ?? item.included,
    }));
    configure.mutate(payload, {
      onSuccess: () => setIsComplete(true),
      onError: (err) => setError((err as Error).message || 'Failed to apply changes'),
    });
  };

  const label = (name: Record<string, string>) => name.en ?? Object.values(name)[0] ?? '';

  return (
    <>
      <div className="fixed inset-0 bg-black/50 z-40 transition-opacity animate-fade-in" onClick={onClose} aria-hidden="true" />
      <div className="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none">
        <div
          className="bg-card rounded-2xl border border-border shadow-2xl w-full max-w-lg pointer-events-auto animate-scale-in"
          onClick={(e) => e.stopPropagation()}
        >
          <div className="flex items-center justify-between p-6 border-b border-border">
            <h2 className="text-xl font-semibold text-foreground">Customize your plan</h2>
            <button onClick={onClose} className="p-2 hover:bg-muted rounded-lg transition-colors" aria-label="Close">
              <X className="w-5 h-5 text-muted-foreground" />
            </button>
          </div>

          <div className="p-6">
            {isComplete ? (
              <div className="flex flex-col items-center text-center py-8">
                <CheckCircle className="h-16 w-16 text-green-500 mb-4" />
                <h3 className="text-xl font-bold text-foreground mb-2">Plan updated</h3>
                <p className="text-sm text-muted-foreground">Your new capacity is active.</p>
              </div>
            ) : isLoading ? (
              <div className="flex items-center justify-center py-10">
                <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
              </div>
            ) : isError || items.length === 0 ? (
              <p className="text-sm text-muted-foreground py-6 text-center">
                No configurable options are available on your current plan.
              </p>
            ) : (
              <>
                <div className="space-y-3 mb-6">
                  {items.map((item) => {
                    const total = totals[item.capabilityKey] ?? item.included;
                    const extra = Math.max(0, total - item.included);
                    const atMin = total <= item.included;
                    const atMax = item.max != null && total >= item.max;
                    return (
                      <div key={item.capabilityKey} className="rounded-xl border-2 border-border p-4" data-testid={`cfg-row-${item.capabilityKey}`}>
                        <div className="flex items-center justify-between mb-2">
                          <div>
                            <p className="text-base font-semibold text-foreground">{label(item.name)}</p>
                            <p className="text-xs text-muted-foreground">
                              {item.included} included{item.unitPrice ? ` · ${currency} ${item.unitPrice.toFixed(2)}/${item.unit ?? 'unit'}/mo extra` : ''}
                              {item.max != null ? ` · up to ${item.max}` : ''}
                            </p>
                          </div>
                          <div className="inline-flex items-center gap-2">
                            <button
                              type="button"
                              aria-label="Decrease"
                              onClick={() => setTotals((s) => ({ ...s, [item.capabilityKey]: clamp(total - 1, item.included, item.max) }))}
                              disabled={atMin}
                              className="h-8 w-8 inline-flex items-center justify-center rounded-md border border-border hover:bg-muted disabled:opacity-40"
                            >
                              <Minus className="w-4 h-4" />
                            </button>
                            <input
                              type="number"
                              min={item.included}
                              max={item.max ?? undefined}
                              value={total}
                              onChange={(e) => setTotals((s) => ({ ...s, [item.capabilityKey]: clamp(Number(e.target.value) || item.included, item.included, item.max) }))}
                              className="w-16 h-8 text-center rounded-md border border-border bg-background text-foreground"
                              aria-label={`${label(item.name)} total`}
                              data-testid={`cfg-input-${item.capabilityKey}`}
                            />
                            <button
                              type="button"
                              aria-label="Increase"
                              onClick={() => setTotals((s) => ({ ...s, [item.capabilityKey]: clamp(total + 1, item.included, item.max) }))}
                              disabled={atMax || !item.unitPrice}
                              className="h-8 w-8 inline-flex items-center justify-center rounded-md border border-border hover:bg-muted disabled:opacity-40"
                            >
                              <Plus className="w-4 h-4" />
                            </button>
                          </div>
                        </div>
                        {extra > 0 && (
                          <p className="text-xs text-muted-foreground text-right" data-testid={`cfg-extra-${item.capabilityKey}`}>
                            +{extra} extra{item.unitPrice ? ` = ${currency} ${(extra * item.unitPrice).toFixed(2)}/mo` : ''}
                          </p>
                        )}
                      </div>
                    );
                  })}
                </div>

                <div className="mb-6 flex items-center justify-between rounded-xl bg-muted/40 px-4 py-3">
                  <span className="text-sm text-muted-foreground">Added to your monthly bill</span>
                  <span className="text-lg font-bold text-primary" data-testid="cfg-monthly-delta">
                    {currency} {monthlyDelta.toFixed(2)}
                  </span>
                </div>

                <button
                  onClick={handleApply}
                  disabled={!dirty || configure.isPending}
                  className={[
                    'w-full rounded-lg px-4 py-3 text-sm font-semibold text-white transition-colors',
                    'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500',
                    !dirty || configure.isPending ? 'cursor-not-allowed bg-gray-400' : 'bg-blue-600 hover:bg-blue-700',
                  ].join(' ')}
                  data-testid="cfg-apply"
                >
                  {configure.isPending ? (
                    <span className="flex items-center justify-center gap-2">
                      <Loader2 className="h-4 w-4 animate-spin" />
                      Applying…
                    </span>
                  ) : (
                    'Apply changes'
                  )}
                </button>

                {error && <p className="mt-3 text-sm text-destructive">{error}</p>}
              </>
            )}
          </div>
        </div>
      </div>
    </>
  );
}
