
import React, { useState, useEffect } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectGroup, SelectLabel } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { Badge } from '@/components/ui/badge';
import { Plus, Trash2, ArrowRight, Save, LayoutTemplate } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/contexts/AuthContext';
import { useToast } from '@/hooks/use-toast';
import { RULE_TYPES, OPERATORS, ACTION_TYPES, getAvailableFields } from '@/lib/ruleEngineFields';
import RuleTestDialog from './RuleTestDialog';

export default function RuleBuilderDialog({ open, onOpenChange, existingRule, onSuccess }) {
  const { user } = useAuth();
  const { toast } = useToast();
  const [step, setStep] = useState(1);
  const [isSaving, setIsSaving] = useState(false);
  const [testerOpen, setTesterOpen] = useState(false);
  const [customParams, setCustomParams] = useState([]);

  const [ruleData, setRuleData] = useState({ name: '', description: '', rule_type: 'journal_entry', priority: 10, status: 'active' });
  const [conditions, setConditions] = useState([{ id: Date.now(), field: 'amount', operator: 'greater_than', value: '', logical_operator: 'AND' }]);
  const [actions, setActions] = useState([{ id: Date.now(), action_type: 'set_field', field: 'category', value: '' }]);

  useEffect(() => {
    if (open) {
      setStep(1);
      fetchCustomParameters();
      if (existingRule) {
        setRuleData({ name: existingRule.name || '', description: existingRule.description || '', rule_type: existingRule.rule_type || 'journal_entry', priority: existingRule.priority || 10, status: existingRule.status || 'active' });
        setConditions(existingRule.rule_conditions?.length ? existingRule.rule_conditions.map(c => ({...c, id: c.id || Date.now() + Math.random()})) : [{ id: Date.now(), field: 'amount', operator: 'greater_than', value: '', logical_operator: 'AND' }]);
        setActions(existingRule.rule_actions?.length ? existingRule.rule_actions.map(a => ({...a, id: a.id || Date.now() + Math.random()})) : [{ id: Date.now(), action_type: 'set_field', field: 'category', value: '' }]);
      } else {
        setRuleData({ name: '', description: '', rule_type: 'journal_entry', priority: 10, status: 'active' });
        setConditions([{ id: Date.now(), field: 'amount', operator: 'greater_than', value: '', logical_operator: 'AND' }]);
        setActions([{ id: Date.now(), action_type: 'set_field', field: 'category', value: '' }]);
      }
    }
  }, [open, existingRule, user]);

  const fetchCustomParameters = async () => {
    if (!user) return;
    try {
      const { data, error } = await supabase.from('custom_parameters').select('*');
      if (error) throw error;
      setCustomParams(data || []);
    } catch (err) { console.error('Error fetching custom parameters:', err); }
  };

  const predefinedFields = getAvailableFields(ruleData.rule_type);
  const allFields = [...predefinedFields, ...customParams.map(cp => ({ value: cp.name, label: `${cp.name} (Custom)`, type: cp.type, isCustom: true }))];

  const renderFieldOptions = () => (
    <>
      <SelectGroup><SelectLabel>Standard Fields</SelectLabel>{predefinedFields.map(f => <SelectItem key={f.value} value={f.value}>{f.label}</SelectItem>)}</SelectGroup>
      {customParams.length > 0 && (<SelectGroup><SelectLabel>Global Parameters</SelectLabel>{customParams.map(cp => <SelectItem key={`custom_${cp.name}`} value={cp.name}>{cp.name}</SelectItem>)}</SelectGroup>)}
    </>
  );

  const getFieldLabel = (fieldValue) => { const field = allFields.find(f => f.value === fieldValue); return field ? field.label : fieldValue; };

  const handleSave = async () => {
    if (!ruleData.name.trim()) return toast({ variant: 'destructive', description: 'Rule name is required.' });
    if (conditions.length === 0) return toast({ variant: 'destructive', description: 'At least one condition is required.' });
    if (actions.length === 0) return toast({ variant: 'destructive', description: 'At least one action is required.' });

    setIsSaving(true);
    try {
      let savedRuleId = existingRule?.id;
      const rulePayload = { name: ruleData.name, description: ruleData.description, rule_type: ruleData.rule_type, priority: parseInt(ruleData.priority) || 10, status: ruleData.status, updated_at: new Date().toISOString() };

      if (savedRuleId) {
        await supabase.from('accounting_rules').update(rulePayload).eq('id', savedRuleId);
      } else {
        const { data, error } = await supabase.from('accounting_rules').insert([rulePayload]).select().single();
        if (error) throw error;
        savedRuleId = data.id;
      }

      await supabase.from('rule_conditions').delete().eq('rule_id', savedRuleId);
      const condPayload = conditions.map((c, i) => ({ rule_id: savedRuleId, field: c.field, operator: c.operator, value: c.value, logical_operator: i === 0 ? 'AND' : c.logical_operator, order_index: i }));
      await supabase.from('rule_conditions').insert(condPayload);

      await supabase.from('rule_actions').delete().eq('rule_id', savedRuleId);
      const actPayload = actions.map((a, i) => ({ rule_id: savedRuleId, action_type: a.action_type, field: a.field, value: a.value, order_index: i }));
      await supabase.from('rule_actions').insert(actPayload);

      toast({ title: 'Success', description: `Global rule ${existingRule ? 'updated' : 'created'} successfully.` });
      onSuccess();
      onOpenChange(false);
    } catch (err) {
      console.error(err);
      toast({ variant: 'destructive', title: 'Error', description: err.message });
    } finally { setIsSaving(false); }
  };

  return (
    <>
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl">
        <DialogHeader>
          <DialogTitle>{existingRule ? 'Edit Global Rule' : 'Build Global Accounting Rule'}</DialogTitle>
          <DialogDescription>Automate categorization, flagging, and blocking of entries globally across all associations.</DialogDescription>
        </DialogHeader>

        <div className="flex mb-4 border-b">
          {[1, 2, 3, 4].map(s => (
            <div key={s} className={`flex-1 text-center py-2 text-sm font-medium border-b-2 ${step === s ? 'border-primary text-primary' : step > s ? 'border-emerald-500 text-emerald-600' : 'border-transparent text-muted-foreground'}`}>
              {s === 1 ? '1. Basics' : s === 2 ? '2. Conditions' : s === 3 ? '3. Actions' : '4. Review'}
            </div>
          ))}
        </div>

        <div className="py-2 min-h-[300px]">
          {step === 1 && (
            <div className="space-y-4 animate-in fade-in">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2 col-span-2"><Label>Global Rule Name *</Label><Input value={ruleData.name} onChange={e => setRuleData({...ruleData, name: e.target.value})} placeholder="e.g., Auto-categorize Home Depot to Maintenance" /></div>
                <div className="space-y-2">
                  <Label>Target Entity Type</Label>
                  <Select value={ruleData.rule_type} onValueChange={v => setRuleData({...ruleData, rule_type: v})}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>{RULE_TYPES.map(t => <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>)}</SelectContent>
                  </Select>
                  <p className="text-[10px] text-muted-foreground">Determines which entry stream this global rule applies to.</p>
                </div>
                <div className="space-y-2">
                  <Label>Priority (Execution Order)</Label>
                  <Input type="number" value={ruleData.priority} onChange={e => setRuleData({...ruleData, priority: e.target.value})} />
                  <p className="text-[10px] text-muted-foreground">Higher numbers run first.</p>
                </div>
                <div className="space-y-2 col-span-2"><Label>Description</Label><Textarea value={ruleData.description} onChange={e => setRuleData({...ruleData, description: e.target.value})} className="h-20" /></div>
                <div className="flex items-center gap-2 pt-2">
                  <Switch checked={ruleData.status === 'active'} onCheckedChange={v => setRuleData({...ruleData, status: v ? 'active' : 'inactive'})} />
                  <Label>Rule Active Globally</Label>
                </div>
              </div>
            </div>
          )}

          {step === 2 && (
            <div className="space-y-4 animate-in fade-in">
              <div className="flex justify-between items-center bg-primary/5 p-3 rounded border border-primary/10">
                <div><h4 className="font-semibold text-sm">IF these conditions are met...</h4><p className="text-xs text-muted-foreground">Define the triggers for this rule.</p></div>
                <Button variant="outline" size="sm" onClick={() => setConditions([...conditions, { id: Date.now(), field: predefinedFields[0]?.value, operator: 'equals', value: '', logical_operator: 'AND' }])}><Plus className="w-4 h-4 mr-1" /> Add Condition</Button>
              </div>
              {conditions.map((cond, index) => (
                <div key={cond.id} className="flex items-center gap-3 bg-muted/50 p-3 rounded border">
                  {index > 0 ? (
                    <Select value={cond.logical_operator} onValueChange={v => { const n = [...conditions]; n[index].logical_operator = v; setConditions(n); }}>
                      <SelectTrigger className="w-24"><SelectValue /></SelectTrigger>
                      <SelectContent><SelectItem value="AND">AND</SelectItem><SelectItem value="OR">OR</SelectItem></SelectContent>
                    </Select>
                  ) : <div className="w-24 text-center font-bold text-muted-foreground">WHERE</div>}
                  <Select value={cond.field} onValueChange={v => { const n = [...conditions]; n[index].field = v; setConditions(n); }}>
                    <SelectTrigger className="w-40"><SelectValue /></SelectTrigger>
                    <SelectContent>{renderFieldOptions()}</SelectContent>
                  </Select>
                  <Select value={cond.operator} onValueChange={v => { const n = [...conditions]; n[index].operator = v; setConditions(n); }}>
                    <SelectTrigger className="w-40"><SelectValue /></SelectTrigger>
                    <SelectContent>{OPERATORS.map(o => <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>)}</SelectContent>
                  </Select>
                  <Input placeholder="Value..." value={cond.value} onChange={e => { const n = [...conditions]; n[index].value = e.target.value; setConditions(n); }} className="flex-1" />
                  <Button variant="ghost" size="icon" className="text-destructive shrink-0" onClick={() => setConditions(conditions.filter(c => c.id !== cond.id))} disabled={conditions.length === 1}><Trash2 className="w-4 h-4" /></Button>
                </div>
              ))}
            </div>
          )}

          {step === 3 && (
            <div className="space-y-4 animate-in fade-in">
              <div className="flex justify-between items-center bg-emerald-50 p-3 rounded border border-emerald-100">
                <div><h4 className="font-semibold text-emerald-900 text-sm">THEN perform these actions...</h4><p className="text-xs text-emerald-700">What happens when the conditions match.</p></div>
                <Button variant="outline" size="sm" onClick={() => setActions([...actions, { id: Date.now(), action_type: 'set_field', field: predefinedFields[0]?.value, value: '' }])}><Plus className="w-4 h-4 mr-1" /> Add Action</Button>
              </div>
              {actions.map((act, index) => (
                <div key={act.id} className="flex items-center gap-3 bg-muted/50 p-3 rounded border">
                  <Select value={act.action_type} onValueChange={v => { const n = [...actions]; n[index].action_type = v; setActions(n); }}>
                    <SelectTrigger className="w-56"><SelectValue /></SelectTrigger>
                    <SelectContent>{ACTION_TYPES.map(a => <SelectItem key={a.value} value={a.value}>{a.label}</SelectItem>)}</SelectContent>
                  </Select>
                  {act.action_type === 'set_field' && (
                    <Select value={act.field} onValueChange={v => { const n = [...actions]; n[index].field = v; setActions(n); }}>
                      <SelectTrigger className="w-40"><SelectValue placeholder="Select Field" /></SelectTrigger>
                      <SelectContent>{renderFieldOptions()}</SelectContent>
                    </Select>
                  )}
                  {act.action_type !== 'flag_review' && (
                    <Input placeholder={act.action_type === 'prevent_save' ? "Rejection reason..." : "Value..."} value={act.value} onChange={e => { const n = [...actions]; n[index].value = e.target.value; setActions(n); }} className="flex-1" />
                  )}
                  <Button variant="ghost" size="icon" className="text-destructive shrink-0" onClick={() => setActions(actions.filter(a => a.id !== act.id))} disabled={actions.length === 1}><Trash2 className="w-4 h-4" /></Button>
                </div>
              ))}
            </div>
          )}

          {step === 4 && (
            <div className="space-y-6 animate-in fade-in">
              <div className="bg-muted/50 p-5 rounded-lg border">
                <h3 className="font-bold text-lg mb-1">{ruleData.name || 'Unnamed Rule'}</h3>
                <div className="flex gap-2 mb-4">
                  <Badge variant="outline">{RULE_TYPES.find(t=>t.value===ruleData.rule_type)?.label}</Badge>
                  <Badge variant="outline">Priority: {ruleData.priority}</Badge>
                  <Badge variant={ruleData.status==='active'?'default':'secondary'}>{ruleData.status.toUpperCase()}</Badge>
                </div>
                <div className="space-y-4">
                  <div>
                    <h4 className="font-semibold text-sm uppercase tracking-wider mb-2">If</h4>
                    <ul className="space-y-1 text-sm bg-background p-3 rounded border">
                      {conditions.map((c, i) => (
                        <li key={c.id}>
                          {i > 0 && <strong className="text-primary mr-2">{c.logical_operator}</strong>}
                          <span className="bg-muted px-1 rounded">{getFieldLabel(c.field)}</span>
                          <i className="mx-2 text-muted-foreground">{OPERATORS.find(o=>o.value===c.operator)?.label.toLowerCase()}</i>
                          <strong>"{c.value}"</strong>
                        </li>
                      ))}
                    </ul>
                  </div>
                  <div>
                    <h4 className="font-semibold text-sm uppercase tracking-wider mb-2">Then</h4>
                    <ul className="space-y-1 text-sm bg-background p-3 rounded border">
                      {actions.map((a) => (
                        <li key={a.id}>
                          <ArrowRight className="w-3 h-3 inline mr-2 text-emerald-500" />
                          {a.action_type === 'set_field' && <span>Set <span className="bg-muted px-1 rounded">{getFieldLabel(a.field)}</span> to <strong>"{a.value}"</strong></span>}
                          {a.action_type === 'append_description' && <span>Append <strong>"{a.value}"</strong> to description</span>}
                          {a.action_type === 'prevent_save' && <span>Block entry saving. Reason: <strong>"{a.value}"</strong></span>}
                          {a.action_type === 'flag_review' && <span>Flag entry for review</span>}
                        </li>
                      ))}
                    </ul>
                  </div>
                </div>
              </div>
              <div className="flex justify-end gap-2">
                <Button variant="outline" onClick={() => setTesterOpen(true)} className="bg-primary/5 text-primary border-primary/20 hover:bg-primary/10">
                  <LayoutTemplate className="w-4 h-4 mr-2" /> Test Rule Logic
                </Button>
              </div>
            </div>
          )}
        </div>

        <DialogFooter className="mt-6 border-t pt-4 flex justify-between sm:justify-between items-center w-full">
          <Button variant="ghost" onClick={() => onOpenChange(false)}>Cancel</Button>
          <div className="flex gap-2">
            {step > 1 && <Button variant="outline" onClick={() => setStep(s => s - 1)}>Back</Button>}
            {step < 4 ? (
              <Button onClick={() => setStep(s => s + 1)}>Next Step <ArrowRight className="w-4 h-4 ml-2" /></Button>
            ) : (
              <Button onClick={handleSave} disabled={isSaving}>
                {isSaving ? 'Saving...' : <><Save className="w-4 h-4 mr-2"/> Save Global Rule</>}
              </Button>
            )}
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>

    <RuleTestDialog open={testerOpen} onOpenChange={setTesterOpen} ruleType={ruleData.rule_type} />
    </>
  );
}
