import { useState, useEffect, useCallback } from 'react';
import { toast } from 'sonner';
import { ChevronDown, Trash2, ToggleLeft, ToggleRight, Settings2 } from 'lucide-react';
import { api } from '@/api';
import { errMessage } from '@/lib/utils';
import { Badge } from '@/components/ui/badge';

interface MerchantRule {
  id: number;
  bill_id: number;
  bill_name?: string;
  merchant: string;
  auto_attribute_late?: number;
}

interface RuleGroup {
  bill_name?: string;
  bill_id: number;
  rules: MerchantRule[];
}

export default function BillRulesManager() {
  const [open,    setOpen]    = useState(false);
  const [rules,   setRules]   = useState<MerchantRule[]>([]);
  const [loading, setLoading] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const d = await api.allBillMerchantRules() as { rules?: MerchantRule[] };
      setRules(d.rules || []);
    } catch (err) {
      toast.error(errMessage(err, 'Failed to load bill matching rules'));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleDelete = async (billId: number, ruleId: number, merchant: string) => {
    try {
      await api.deleteMerchantRule(billId, ruleId);
      setRules(prev => prev.filter(r => r.id !== ruleId));
      toast.success(`Rule "${merchant}" removed`);
    } catch (err) {
      toast.error(errMessage(err, 'Failed to delete rule'));
    }
  };

  const handleToggleAutoLate = async (billId: number, ruleId: number, current: boolean) => {
    try {
      await api.toggleRuleAutoAttribute(billId, ruleId, !current);
      setRules(prev => prev.map(r =>
        r.id === ruleId ? { ...r, auto_attribute_late: current ? 0 : 1 } : r
      ));
    } catch (err) {
      toast.error(errMessage(err, 'Failed to update rule'));
    }
  };

  // Group rules by bill
  const byBill = rules.reduce<Record<number, RuleGroup>>((acc, r) => {
    const key = r.bill_id;
    const g = acc[key] ?? (acc[key] = { bill_name: r.bill_name, bill_id: r.bill_id, rules: [] });
    g.rules.push(r);
    return acc;
  }, {});
  const groups = Object.values(byBill);

  return (
    <div className="rounded-xl border border-border/60 bg-card/80 overflow-hidden">
      <button
        type="button"
        onClick={() => setOpen(v => !v)}
        className="w-full flex items-center gap-2 px-4 py-3 text-left hover:bg-muted/20 transition-colors"
      >
        <Settings2 className="h-4 w-4 text-muted-foreground" />
        <span className="text-sm font-medium flex-1">Bill Matching Rules</span>
        {!open && rules.length > 0 && (
          <Badge variant="secondary" className="text-xs">{rules.length}</Badge>
        )}
        <ChevronDown className={`h-4 w-4 text-muted-foreground transition-transform ${open ? 'rotate-180' : ''}`} />
      </button>

      {open && (
        <div className="border-t border-border/40">
          {loading ? (
            <p className="text-sm text-muted-foreground text-center py-6">Loading…</p>
          ) : groups.length === 0 ? (
            <p className="text-sm text-muted-foreground text-center py-6 px-4">
              No rules saved yet. Open a bill and add merchant matching rules to auto-match bank transactions.
            </p>
          ) : (
            <div className="divide-y divide-border/30 max-h-96 overflow-y-auto">
              {groups.map(group => (
                <div key={group.bill_id}>
                  <div className="px-4 py-2 bg-muted/20">
                    <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide truncate">
                      {group.bill_name}
                    </p>
                  </div>
                  {group.rules.map(rule => (
                    <div key={rule.id} className="flex items-center gap-3 px-4 py-2.5 hover:bg-muted/10 transition-colors">
                      <span className="font-mono text-xs flex-1 truncate">{rule.merchant}</span>
                      <button
                        type="button"
                        title={rule.auto_attribute_late ? 'Auto-apply late attribution — click to disable' : 'Enable auto late attribution'}
                        onClick={() => handleToggleAutoLate(group.bill_id, rule.id, !!rule.auto_attribute_late)}
                        className={`shrink-0 transition-colors ${rule.auto_attribute_late ? 'text-primary' : 'text-muted-foreground/40 hover:text-muted-foreground'}`}
                      >
                        {rule.auto_attribute_late
                          ? <ToggleRight className="h-4 w-4" />
                          : <ToggleLeft className="h-4 w-4" />
                        }
                      </button>
                      <button
                        type="button"
                        onClick={() => handleDelete(group.bill_id, rule.id, rule.merchant)}
                        className="shrink-0 text-muted-foreground hover:text-destructive transition-colors"
                      >
                        <Trash2 className="h-3.5 w-3.5" />
                      </button>
                    </div>
                  ))}
                </div>
              ))}
            </div>
          )}
          <p className="px-4 py-2 text-[11px] text-muted-foreground border-t border-border/30">
            Merchant patterns are matched with word-boundary rules. Toggle icon = auto-apply late month attribution.
          </p>
        </div>
      )}
    </div>
  );
}
