'use client';

import { useEffect, useState, useCallback } from 'react';
import { Award, Save, Loader2, Plus, Trash2, Settings as SettingsIcon, Layers, Edit3, X } from 'lucide-react';
import { toast } from 'sonner';
import { usePageHeader } from '@client/contexts/PageHeaderContext';
import { useLanguage } from '@client/contexts/LanguageContext';
import FeatureGuard from '@client/components/FeatureGuard';
import { isFeatureLockedError } from '@client/utils/isFeatureLockedError';
import { isForbiddenError } from '@client/utils/isForbiddenError';
import PermissionDenied from '@client/components/ui/PermissionDenied';
import {
  getLoyaltyConfig,
  updateLoyaltySettings,
  createLoyaltyTier,
  updateLoyaltyTier,
  deleteLoyaltyTier,
  type LoyaltySettings,
  type LoyaltyTier,
} from '@client/api/loyalty';

const ORDER_TYPES = ['dine-in', 'takeaway', 'delivery'];
const CHANNELS = ['chat', 'voice', 'whatsapp', 'storefront'];

export default function LoyaltyPage() {
  return (
    <FeatureGuard feature="loyalty" featureName="Loyalty Program">
      <LoyaltyPageInner />
    </FeatureGuard>
  );
}

function LoyaltyPageInner() {
  const { t } = useLanguage();
  usePageHeader(
    t('loyalty.title', 'Loyalty Program'),
    t('loyalty.subtitle', 'Reward repeat customers with points, tiers, and perks')
  );

  const [tab, setTab] = useState<'settings' | 'tiers'>('settings');
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [settings, setSettings] = useState<LoyaltySettings | null>(null);
  const [tiers, setTiers] = useState<LoyaltyTier[]>([]);
  const [forbidden, setForbidden] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const data = await getLoyaltyConfig();
      setSettings(data.settings);
      setTiers(data.tiers);
    } catch (e) {
      if (isForbiddenError(e)) {
        setForbidden(true);
      } else if (!isFeatureLockedError(e)) {
        toast.error((e as Error).message || 'Failed to load loyalty config');
      }
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  const saveSettings = async () => {
    if (!settings) return;
    setSaving(true);
    try {
      const { settings: updated } = await updateLoyaltySettings(settings);
      setSettings(updated);
      toast.success('Settings saved');
    } catch (e) {
      toast.error((e as Error).message || 'Save failed');
    } finally {
      setSaving(false);
    }
  };

  if (forbidden) {
    return <PermissionDenied sectionName="the Loyalty Program section" />;
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="animate-spin" size={28} style={{ color: 'hsl(var(--primary))' }} />
      </div>
    );
  }

  if (!settings) {
    return <div className="p-6 text-center" style={{ color: 'hsl(var(--muted-foreground))' }}>Failed to load loyalty configuration.</div>;
  }

  return (
    <div className="space-y-5">
      <div className="flex items-center gap-1 border-b" style={{ borderColor: 'hsl(var(--border))' }}>
        <TabButton active={tab === 'settings'} onClick={() => setTab('settings')} icon={<SettingsIcon size={15} />}>
          Program settings
        </TabButton>
        <TabButton active={tab === 'tiers'} onClick={() => setTab('tiers')} icon={<Layers size={15} />}>
          Tiers ({tiers.length})
        </TabButton>
      </div>

      {tab === 'settings' && (
        <SettingsTab
          settings={settings}
          setSettings={setSettings}
          saveSettings={saveSettings}
          saving={saving}
        />
      )}

      {tab === 'tiers' && (
        <TiersTab tiers={tiers} reload={load} mode={settings.tier_threshold_mode} />
      )}
    </div>
  );
}

// ─── Settings tab ───
function SettingsTab({
  settings,
  setSettings,
  saveSettings,
  saving,
}: {
  settings: LoyaltySettings;
  setSettings: (s: LoyaltySettings) => void;
  saveSettings: () => void;
  saving: boolean;
}) {
  const update = (patch: Partial<LoyaltySettings>) => setSettings({ ...settings, ...patch });
  const toggleArr = (key: 'eligibility_order_types' | 'eligibility_channels', val: string) => {
    const cur = settings[key] || [];
    update({ [key]: cur.includes(val) ? cur.filter((v) => v !== val) : [...cur, val] } as Partial<LoyaltySettings>);
  };

  return (
    <div className="space-y-5">
      <div className="card p-5">
        <div className="flex items-center justify-between gap-4">
          <div>
            <div className="font-semibold flex items-center gap-2"><Award size={18} /> Loyalty program</div>
            <div className="text-sm mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>
              Toggle the entire program on or off without losing balances.
            </div>
          </div>
          <Toggle checked={settings.enabled} onChange={() => update({ enabled: !settings.enabled })} />
        </div>
      </div>

      <Card title="Earning">
        <Row label="Earn mode">
          <select
            value={settings.earn_mode}
            onChange={(e) => update({ earn_mode: e.target.value as LoyaltySettings['earn_mode'] })}
            className="input-base"
          >
            <option value="per_dollar">Per dollar spent</option>
            <option value="per_order">Per completed order</option>
            <option value="per_item">Per item purchased</option>
          </select>
        </Row>
        <Row label={settings.earn_mode === 'per_dollar' ? 'Points per $1' : settings.earn_mode === 'per_order' ? 'Points per order' : 'Points per item'}>
          <input
            type="number" min={0} step="0.01"
            className="input-base w-32"
            value={settings.earn_rate}
            onChange={(e) => update({ earn_rate: Number(e.target.value) })}
          />
        </Row>
        <Row label="Eligible order types">
          <div className="flex gap-2 flex-wrap">
            {ORDER_TYPES.map((t) => (
              <Pill key={t} active={settings.eligibility_order_types.includes(t)} onClick={() => toggleArr('eligibility_order_types', t)}>{t}</Pill>
            ))}
          </div>
        </Row>
        <Row label="Eligible channels">
          <div className="flex gap-2 flex-wrap">
            {CHANNELS.map((c) => (
              <Pill key={c} active={settings.eligibility_channels.includes(c)} onClick={() => toggleArr('eligibility_channels', c)}>{c}</Pill>
            ))}
          </div>
        </Row>
      </Card>

      <Card title="Redemption">
        <Row label="Points per discount unit">
          <input
            type="number" min={1}
            className="input-base w-32"
            value={settings.redeem_points_per_unit}
            onChange={(e) => update({ redeem_points_per_unit: Math.max(1, Math.floor(Number(e.target.value) || 1)) })}
          />
        </Row>
        <Row label="Discount value per unit ($)">
          <input
            type="number" min={0.01} step="0.01"
            className="input-base w-32"
            value={settings.redeem_unit_value}
            onChange={(e) => update({ redeem_unit_value: Number(e.target.value) })}
          />
        </Row>
        <Row label="Minimum points to redeem">
          <input
            type="number" min={0}
            className="input-base w-32"
            value={settings.min_redeem_points}
            onChange={(e) => update({ min_redeem_points: Math.max(0, Math.floor(Number(e.target.value) || 0)) })}
          />
        </Row>
        <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
          Example: {settings.redeem_points_per_unit} points = ${settings.redeem_unit_value.toFixed(2)} discount
        </p>
      </Card>

      <Card title="Expiry">
        <Row label="Expire points after (months)">
          <div className="flex items-center gap-2">
            <input
              type="number" min={1}
              placeholder="Never"
              className="input-base w-32"
              value={settings.expiry_months ?? ''}
              onChange={(e) => {
                const v = e.target.value;
                update({ expiry_months: v === '' ? null : Math.max(1, Math.floor(Number(v))) });
              }}
            />
            <button
              type="button"
              className="text-xs underline"
              style={{ color: 'hsl(var(--primary))' }}
              onClick={() => update({ expiry_months: null })}
            >
              Never expire
            </button>
          </div>
        </Row>
      </Card>

      <Card title="Tier thresholds">
        <Row label="Promote customers based on">
          <select
            value={settings.tier_threshold_mode}
            onChange={(e) => update({ tier_threshold_mode: e.target.value as LoyaltySettings['tier_threshold_mode'] })}
            className="input-base"
          >
            <option value="lifetime_points">Lifetime points earned</option>
            <option value="rolling_12mo_spend">Rolling 12-month spend ($)</option>
          </select>
        </Row>
      </Card>

      <Card title="Customer notifications">
        <Row label="Email when points are earned">
          <Toggle checked={settings.notify_on_earn} onChange={() => update({ notify_on_earn: !settings.notify_on_earn })} />
        </Row>
        <Row label="Email when a customer reaches a new tier">
          <Toggle checked={settings.notify_on_tier_up} onChange={() => update({ notify_on_tier_up: !settings.notify_on_tier_up })} />
        </Row>
        <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
          Emails are only sent when the customer has an email address on file and the loyalty program is enabled.
        </p>
      </Card>

      <div className="flex justify-end">
        <button
          onClick={saveSettings}
          disabled={saving}
          className="btn-primary inline-flex items-center gap-2"
        >
          {saving ? <Loader2 className="animate-spin" size={16} /> : <Save size={16} />}
          Save settings
        </button>
      </div>
    </div>
  );
}

// ─── Tiers tab ───
function TiersTab({ tiers, reload, mode }: { tiers: LoyaltyTier[]; reload: () => void; mode: string }) {
  const [editing, setEditing] = useState<LoyaltyTier | null>(null);
  const [showCreate, setShowCreate] = useState(false);

  const remove = async (t: LoyaltyTier) => {
    if (!window.confirm(`Delete tier "${t.name}"? Existing customers on this tier will be re-evaluated.`)) return;
    try {
      await deleteLoyaltyTier(t.id);
      toast.success('Tier removed');
      reload();
    } catch (e) {
      toast.error((e as Error).message || 'Delete failed');
    }
  };

  const sorted = [...tiers].sort((a, b) => a.threshold - b.threshold);

  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center gap-3 flex-wrap">
        <p className="text-sm" style={{ color: 'hsl(var(--muted-foreground))' }}>
          Threshold is measured in {mode === 'rolling_12mo_spend' ? 'rolling 12-month spend ($)' : 'lifetime points earned'}.
        </p>
        <button onClick={() => setShowCreate(true)} className="btn-primary inline-flex items-center gap-2">
          <Plus size={16} /> Add tier
        </button>
      </div>

      <div className="card overflow-hidden">
        <table className="w-full text-sm">
          <thead style={{ background: 'hsl(var(--muted))' }}>
            <tr style={{ color: 'hsl(var(--muted-foreground))' }}>
              <th className="text-left px-4 py-2 font-medium">Tier</th>
              <th className="text-left px-4 py-2 font-medium">Threshold</th>
              <th className="text-left px-4 py-2 font-medium">Earn ×</th>
              <th className="text-left px-4 py-2 font-medium">Auto discount</th>
              <th className="text-left px-4 py-2 font-medium">Free delivery</th>
              <th className="text-left px-4 py-2 font-medium">Perks</th>
              <th />
            </tr>
          </thead>
          <tbody>
            {sorted.length === 0 && (
              <tr><td colSpan={7} className="text-center py-8" style={{ color: 'hsl(var(--muted-foreground))' }}>No tiers configured.</td></tr>
            )}
            {sorted.map((t) => (
              <tr key={t.id} className="border-t" style={{ borderColor: 'hsl(var(--border))' }}>
                <td className="px-4 py-2">
                  <span className="inline-flex items-center gap-2">
                    <span className="w-3 h-3 rounded-full" style={{ background: t.badge_color || '#9ca3af' }} />
                    {t.name}
                  </span>
                </td>
                <td className="px-4 py-2">{mode === 'rolling_12mo_spend' ? `$${Number(t.threshold).toFixed(2)}` : t.threshold}</td>
                <td className="px-4 py-2">{Number(t.earn_multiplier).toFixed(2)}×</td>
                <td className="px-4 py-2">{t.auto_discount_pct ? `${t.auto_discount_pct}%` : '—'}</td>
                <td className="px-4 py-2">{t.free_delivery ? 'Yes' : '—'}</td>
                <td className="px-4 py-2 max-w-[260px] truncate" title={t.perks_text ?? ''}>{t.perks_text ?? '—'}</td>
                <td className="px-4 py-2 text-right whitespace-nowrap">
                  <button onClick={() => setEditing(t)} className="btn-secondary px-2 py-1 mr-1" title="Edit"><Edit3 size={13} /></button>
                  <button onClick={() => remove(t)} className="btn-secondary px-2 py-1" title="Delete"><Trash2 size={13} /></button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {(showCreate || editing) && (
        <TierEditor
          tier={editing}
          onClose={() => { setShowCreate(false); setEditing(null); }}
          onSaved={() => { setShowCreate(false); setEditing(null); reload(); }}
        />
      )}
    </div>
  );
}

function TierEditor({ tier, onClose, onSaved }: { tier: LoyaltyTier | null; onClose: () => void; onSaved: () => void }) {
  const [form, setForm] = useState({
    name: tier?.name ?? '',
    threshold: tier?.threshold ?? 0,
    earn_multiplier: tier?.earn_multiplier ?? 1,
    auto_discount_pct: tier?.auto_discount_pct ?? 0,
    free_delivery: tier?.free_delivery ?? false,
    perks_text: tier?.perks_text ?? '',
    badge_color: tier?.badge_color ?? '#9ca3af',
    display_order: tier?.display_order ?? 0,
  });
  const [saving, setSaving] = useState(false);

  const save = async () => {
    if (!form.name.trim()) return toast.error('Name is required');
    setSaving(true);
    try {
      const body = {
        name: form.name.trim(),
        threshold: Number(form.threshold),
        earn_multiplier: Number(form.earn_multiplier),
        auto_discount_pct: Number(form.auto_discount_pct),
        free_delivery: !!form.free_delivery,
        perks_text: form.perks_text || null,
        badge_color: form.badge_color || null,
        display_order: Number(form.display_order),
      };
      if (tier) await updateLoyaltyTier(tier.id, body);
      else await createLoyaltyTier(body);
      toast.success('Tier saved');
      onSaved();
    } catch (e) {
      toast.error((e as Error).message || 'Save 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-lg"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-lg font-semibold">{tier ? 'Edit tier' : 'New tier'}</h3>
          <button className="btn-secondary px-2 py-1" onClick={onClose}><X size={14} /></button>
        </div>
        <div className="space-y-3">
          <Field label="Name">
            <input className="input-base w-full" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
          </Field>
          <div className="grid grid-cols-2 gap-3">
            <Field label="Threshold">
              <input type="number" min={0} className="input-base w-full" value={form.threshold} onChange={(e) => setForm({ ...form, threshold: Number(e.target.value) })} />
            </Field>
            <Field label="Earn multiplier">
              <input type="number" min={0} step="0.05" className="input-base w-full" value={form.earn_multiplier} onChange={(e) => setForm({ ...form, earn_multiplier: Number(e.target.value) })} />
            </Field>
            <Field label="Auto discount %">
              <input type="number" min={0} max={100} step="0.5" className="input-base w-full" value={form.auto_discount_pct} onChange={(e) => setForm({ ...form, auto_discount_pct: Number(e.target.value) })} />
            </Field>
            <Field label="Display order">
              <input type="number" className="input-base w-full" value={form.display_order} onChange={(e) => setForm({ ...form, display_order: Number(e.target.value) })} />
            </Field>
            <Field label="Badge color">
              <input type="color" className="input-base w-full h-10 p-1" value={form.badge_color || '#9ca3af'} onChange={(e) => setForm({ ...form, badge_color: e.target.value })} />
            </Field>
            <label className="flex items-center gap-2 mt-6 text-sm">
              <input type="checkbox" checked={form.free_delivery} onChange={(e) => setForm({ ...form, free_delivery: e.target.checked })} />
              Free delivery
            </label>
          </div>
          <Field label="Perks description">
            <textarea className="input-base w-full" rows={2} value={form.perks_text ?? ''} onChange={(e) => setForm({ ...form, perks_text: e.target.value })} />
          </Field>
        </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={save} disabled={saving}>
            {saving ? <Loader2 className="animate-spin" size={16} /> : <Save size={16} />}
            Save tier
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── helpers ───
function Card({ title, children }: { title?: string; children: React.ReactNode }) {
  return (
    <div className="card p-5 space-y-4">
      {title && <div className="font-semibold">{title}</div>}
      {children}
    </div>
  );
}
function Row({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="flex items-center justify-between gap-4 flex-wrap">
      <label className="text-sm font-medium" style={{ color: 'hsl(var(--muted-foreground))' }}>{label}</label>
      <div>{children}</div>
    </div>
  );
}
function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <label className="block text-xs font-medium mb-1" style={{ color: 'hsl(var(--muted-foreground))' }}>{label}</label>
      {children}
    </div>
  );
}
function Pill({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }) {
  return (
    <button
      type="button"
      onClick={onClick}
      className="px-3 py-1 rounded-full text-xs font-medium border transition-colors"
      style={{
        background: active ? 'hsl(var(--primary))' : 'transparent',
        color: active ? 'hsl(var(--primary-foreground))' : 'hsl(var(--muted-foreground))',
        borderColor: active ? 'hsl(var(--primary))' : 'hsl(var(--border))',
      }}
    >
      {children}
    </button>
  );
}
function Toggle({ checked, onChange }: { checked: boolean; onChange: () => void }) {
  return (
    <button
      type="button"
      onClick={onChange}
      className="relative inline-flex items-center w-11 h-6 rounded-full transition-colors shrink-0"
      style={{ backgroundColor: checked ? 'hsl(var(--primary))' : 'hsl(var(--border))' }}
    >
      <span
        className="inline-block w-4 h-4 bg-white rounded-full shadow transition-transform"
        style={{ transform: checked ? 'translateX(22px)' : 'translateX(3px)' }}
      />
    </button>
  );
}
function TabButton({ active, onClick, icon, children }: { active: boolean; onClick: () => void; icon: React.ReactNode; children: React.ReactNode }) {
  return (
    <button
      onClick={onClick}
      className="px-4 py-2.5 text-sm font-medium border-b-2 -mb-px inline-flex items-center gap-2 transition-colors"
      style={{
        borderColor: active ? 'hsl(var(--primary))' : 'transparent',
        color: active ? 'hsl(var(--primary))' : 'hsl(var(--muted-foreground))',
      }}
    >
      {icon}
      {children}
    </button>
  );
}
