'use client';

import { useEffect, useState, useCallback } from 'react';
import { Award, Loader2, Plus, Minus, History, X, Save } from 'lucide-react';
import { toast } from 'sonner';
import { usePlanFeatures } from '@client/contexts/PlanFeaturesContext';
import {
  getCustomerLoyalty,
  adjustCustomerPoints,
  listCustomerLedger,
  type CustomerLoyaltyView,
  type LedgerRow,
} from '@client/api/loyalty';

export default function CustomerLoyaltyCard({ customerId }: { customerId: string }) {
  const { hasFeature } = usePlanFeatures();
  const [view, setView] = useState<CustomerLoyaltyView | null>(null);
  const [loading, setLoading] = useState(true);
  const [showAdjust, setShowAdjust] = useState(false);
  const [showLedger, setShowLedger] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const v = await getCustomerLoyalty(customerId);
      setView(v);
    } catch (e) {
      const msg = (e as Error).message || '';
      if (!msg.includes('Plan')) toast.error(msg || 'Failed to load loyalty');
      setView(null);
    } finally {
      setLoading(false);
    }
  }, [customerId]);

  useEffect(() => { if (hasFeature('loyalty')) load(); else setLoading(false); }, [load, hasFeature]);

  if (!hasFeature('loyalty')) return null;
  if (loading) {
    return (
      <div className="card p-5 flex items-center justify-center">
        <Loader2 className="animate-spin" size={18} style={{ color: 'hsl(var(--primary))' }} />
      </div>
    );
  }
  if (!view || !view.enabled || !view.wallet) {
    return (
      <div className="card p-5">
        <h3 className="font-semibold mb-2 flex items-center gap-2"><Award size={15} /> Loyalty</h3>
        <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
          {view?.enabled === false ? 'Loyalty program is disabled.' : 'No wallet yet.'}
        </p>
      </div>
    );
  }

  const { wallet, tier, next_tier, progress_to_next, settings } = view;
  const mode = settings?.tier_threshold_mode ?? 'lifetime_points';
  const currentMetric = mode === 'rolling_12mo_spend' ? wallet.rolling_12mo_spend : wallet.lifetime_points;

  return (
    <div className="card p-5">
      <div className="flex items-center justify-between mb-3">
        <h3 className="font-semibold flex items-center gap-2"><Award size={15} /> Loyalty</h3>
        <div className="flex gap-1">
          <button className="btn-secondary px-2 py-1 text-xs inline-flex items-center gap-1" onClick={() => setShowLedger(true)}>
            <History size={12} /> Ledger
          </button>
          <button className="btn-secondary px-2 py-1 text-xs inline-flex items-center gap-1" onClick={() => setShowAdjust(true)}>
            <Plus size={12} /> Adjust
          </button>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3 mb-4">
        <div className="p-3 rounded-lg" style={{ backgroundColor: 'hsl(var(--muted))' }}>
          <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>Balance</p>
          <p className="text-lg font-bold tabular-nums" style={{ color: 'hsl(var(--foreground))' }}>
            {wallet.balance.toLocaleString()}
          </p>
        </div>
        <div className="p-3 rounded-lg" style={{ backgroundColor: 'hsl(var(--muted))' }}>
          <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>Lifetime</p>
          <p className="text-lg font-bold tabular-nums" style={{ color: 'hsl(var(--foreground))' }}>
            {wallet.lifetime_points.toLocaleString()}
          </p>
        </div>
      </div>

      {tier && (
        <div className="mb-3">
          <div className="flex items-center justify-between mb-1.5">
            <span className="inline-flex items-center gap-1.5 text-sm font-medium">
              <span className="w-2.5 h-2.5 rounded-full" style={{ background: tier.badge_color || '#9ca3af' }} />
              {tier.name}
            </span>
            {next_tier && (
              <span className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
                next: {next_tier.name}
              </span>
            )}
          </div>
          {next_tier ? (
            <>
              <div className="h-1.5 w-full rounded-full overflow-hidden" style={{ background: 'hsl(var(--muted))' }}>
                <div
                  className="h-full rounded-full transition-all"
                  style={{ width: `${Math.round(progress_to_next * 100)}%`, background: tier.badge_color || 'hsl(var(--primary))' }}
                />
              </div>
              <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>
                {mode === 'rolling_12mo_spend'
                  ? `$${currentMetric.toFixed(2)} / $${Number(next_tier.threshold).toFixed(2)}`
                  : `${currentMetric.toLocaleString()} / ${Number(next_tier.threshold).toLocaleString()} pts`}
              </p>
            </>
          ) : (
            <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>Top tier reached.</p>
          )}
          {tier.perks_text && (
            <p className="text-xs mt-2" style={{ color: 'hsl(var(--foreground))' }}>{tier.perks_text}</p>
          )}
        </div>
      )}

      {showAdjust && (
        <AdjustModal
          customerId={customerId}
          balance={wallet.balance}
          onClose={() => setShowAdjust(false)}
          onDone={() => { setShowAdjust(false); load(); }}
        />
      )}

      {showLedger && (
        <LedgerDrawer customerId={customerId} onClose={() => setShowLedger(false)} />
      )}
    </div>
  );
}

function AdjustModal({
  customerId, balance, onClose, onDone,
}: { customerId: string; balance: number; onClose: () => void; onDone: () => void }) {
  const [direction, setDirection] = useState<'add' | 'remove'>('add');
  const [amount, setAmount] = useState(0);
  const [reason, setReason] = useState('');
  const [saving, setSaving] = useState(false);

  const submit = async () => {
    const n = Math.floor(Number(amount));
    if (!n || n <= 0) return toast.error('Enter a positive integer amount');
    if (!reason.trim()) return toast.error('Reason is required');
    if (direction === 'remove' && n > balance) return toast.error('Cannot remove more than current balance');
    setSaving(true);
    try {
      const delta = direction === 'add' ? n : -n;
      await adjustCustomerPoints(customerId, delta, reason.trim());
      toast.success('Balance updated');
      onDone();
    } catch (e) {
      toast.error((e as Error).message || 'Failed');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4" style={{ background: 'rgba(0,0,0,0.45)' }} onClick={onClose}>
      <div className="card p-5 w-full max-w-sm" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-lg font-semibold">Adjust points</h3>
          <button className="btn-secondary px-2 py-1" onClick={onClose}><X size={14} /></button>
        </div>
        <div className="space-y-3">
          <div className="flex gap-2">
            <button
              className={direction === 'add' ? 'btn-primary flex-1 inline-flex items-center justify-center gap-1' : 'btn-secondary flex-1 inline-flex items-center justify-center gap-1'}
              onClick={() => setDirection('add')}
            ><Plus size={14} /> Add</button>
            <button
              className={direction === 'remove' ? 'btn-primary flex-1 inline-flex items-center justify-center gap-1' : 'btn-secondary flex-1 inline-flex items-center justify-center gap-1'}
              onClick={() => setDirection('remove')}
            ><Minus size={14} /> Remove</button>
          </div>
          <div>
            <label className="block text-xs font-medium mb-1" style={{ color: 'hsl(var(--muted-foreground))' }}>Amount</label>
            <input
              type="number" min={1} step={1}
              className="input-base w-full"
              value={amount || ''}
              onChange={(e) => setAmount(Number(e.target.value))}
            />
            <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>
              Current balance: <span className="tabular-nums">{balance.toLocaleString()}</span>
            </p>
          </div>
          <div>
            <label className="block text-xs font-medium mb-1" style={{ color: 'hsl(var(--muted-foreground))' }}>Reason</label>
            <input
              className="input-base w-full"
              value={reason}
              onChange={(e) => setReason(e.target.value)}
              placeholder="e.g. service recovery, signup bonus"
            />
          </div>
        </div>
        <div className="flex justify-end gap-2 mt-5">
          <button className="btn-secondary" onClick={onClose} disabled={saving}>Cancel</button>
          <button className="btn-primary inline-flex items-center gap-2" onClick={submit} disabled={saving}>
            {saving ? <Loader2 className="animate-spin" size={14} /> : <Save size={14} />}
            Apply
          </button>
        </div>
      </div>
    </div>
  );
}

function LedgerDrawer({ customerId, onClose }: { customerId: string; onClose: () => void }) {
  const [rows, setRows] = useState<LedgerRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [pages, setPages] = useState(1);

  useEffect(() => {
    let active = true;
    setLoading(true);
    listCustomerLedger(customerId, page, 25)
      .then((r) => { if (active) { setRows(r.data); setPages(r.pages); } })
      .catch((e) => toast.error((e as Error).message || 'Failed'))
      .finally(() => { if (active) setLoading(false); });
    return () => { active = false; };
  }, [customerId, page]);

  const typeColor: Record<string, string> = {
    earn: 'badge-success', redeem: 'badge-info', adjust: 'badge-warning',
    expire: 'badge-neutral', reverse: 'badge-danger',
  };

  return (
    <div className="fixed inset-0 z-50 flex justify-end" style={{ background: 'rgba(0,0,0,0.45)' }} onClick={onClose}>
      <div className="h-full w-full max-w-md flex flex-col" style={{ background: 'hsl(var(--background))' }} onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between px-5 py-4" style={{ borderBottom: '1px solid hsl(var(--border))' }}>
          <h3 className="font-semibold">Loyalty ledger</h3>
          <button className="btn-secondary px-2 py-1" onClick={onClose}><X size={14} /></button>
        </div>
        <div className="flex-1 overflow-auto p-4">
          {loading ? (
            <div className="flex items-center justify-center py-10">
              <Loader2 className="animate-spin" size={20} style={{ color: 'hsl(var(--primary))' }} />
            </div>
          ) : rows.length === 0 ? (
            <p className="text-center text-sm py-10" style={{ color: 'hsl(var(--muted-foreground))' }}>No ledger entries.</p>
          ) : (
            <ul className="space-y-2">
              {rows.map((r) => (
                <li key={r.id} className="card p-3">
                  <div className="flex items-center justify-between">
                    <span className={`badge ${typeColor[r.type] || 'badge-neutral'} text-xs`}>{r.type}</span>
                    <span className={`tabular-nums font-semibold ${r.points >= 0 ? '' : ''}`} style={{ color: r.points >= 0 ? 'hsl(var(--primary))' : 'hsl(var(--destructive))' }}>
                      {r.points > 0 ? `+${r.points}` : r.points}
                    </span>
                  </div>
                  <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>
                    {new Date(r.created_at).toLocaleString()}
                    {r.order_id ? ` · order ${r.order_id.slice(0, 8)}` : ''}
                  </p>
                  {r.reason && <p className="text-xs mt-1">{r.reason}</p>}
                </li>
              ))}
            </ul>
          )}
        </div>
        {pages > 1 && (
          <div className="flex items-center justify-between px-5 py-3" style={{ borderTop: '1px solid hsl(var(--border))' }}>
            <span className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>Page {page} of {pages}</span>
            <div className="flex gap-1">
              <button className="btn-secondary px-2 py-1 text-xs" disabled={page <= 1} onClick={() => setPage(p => p - 1)}>Prev</button>
              <button className="btn-secondary px-2 py-1 text-xs" disabled={page >= pages} onClick={() => setPage(p => p + 1)}>Next</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
