import React, { useState, useEffect } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useToast } from '@/hooks/use-toast';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/contexts/AuthContext';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Sparkles, Edit2, Loader2, AlertTriangle, ChevronDown, CheckCircle2, Building2 } from 'lucide-react';

function AccountSelector({ accounts, value, onChange, label, error, requiredType }) {
  const [isOpen, setIsOpen] = useState(false);
  const [search, setSearch] = useState('');
  const selected = accounts.find(a => a.id === value);
  
  const filteredAccounts = accounts.filter(a => {
    if (requiredType && !a.account_type?.toLowerCase().includes(requiredType)) return false;
    if (!search) return true;
    return `${a.account_number} ${a.account_name}`.toLowerCase().includes(search.toLowerCase());
  });

  return (
    <div className="relative flex flex-col gap-1 w-full">
      <Label>{label}</Label>
      <div 
        className={`border rounded-md p-2 bg-background cursor-pointer flex justify-between items-center transition-colors ${error ? 'border-destructive' : 'border-border hover:border-primary'}`}
        onClick={() => setIsOpen(!isOpen)}
      >
        <span className="truncate font-medium">
          {selected ? `${selected.account_number} - ${selected.account_name}` : 'Select Account...'}
        </span>
        <ChevronDown className="w-4 h-4 text-muted-foreground" />
      </div>
      
      {isOpen && (
        <div className="absolute top-full left-0 right-0 mt-1 bg-background border border-border shadow-xl rounded-md z-50 max-h-60 overflow-hidden flex flex-col">
          <div className="p-2 border-b shrink-0 bg-muted">
            <Input 
              type="text" 
              autoFocus
              placeholder="Search by number or name..." 
              className="w-full text-sm"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onClick={(e) => e.stopPropagation()}
            />
          </div>
          <div className="overflow-y-auto p-1 flex-1">
            {filteredAccounts.length === 0 ? (
              <p className="text-sm text-muted-foreground p-2 text-center">No matching accounts</p>
            ) : (
              filteredAccounts.map(acc => (
                <div 
                  key={acc.id} 
                  className="px-3 py-2 hover:bg-accent cursor-pointer rounded text-sm flex items-center justify-between"
                  onClick={() => { onChange(acc.id); setIsOpen(false); setSearch(''); }}
                >
                  <div className="truncate">
                    <span className="font-mono text-xs mr-2 text-muted-foreground">{acc.account_number}</span>
                    <span className="font-medium">{acc.account_name}</span>
                  </div>
                  <span className="ml-2 text-[10px] bg-muted border px-1.5 py-0.5 rounded text-muted-foreground uppercase shrink-0">
                    {acc.account_type}
                  </span>
                </div>
              ))
            )}
          </div>
        </div>
      )}
      {error && <span className="text-xs text-destructive mt-1">{error}</span>}
    </div>
  );
}

export default function InvoiceMappingDialog({ open, onOpenChange, invoice, onSuccess }) {
  const { toast } = useToast();
  const { user } = useAuth();
  
  const [loadingInitial, setLoadingInitial] = useState(false);
  const [loadingAccounts, setLoadingAccounts] = useState(false);
  const [saving, setSaving] = useState(false);
  
  const [associations, setAssociations] = useState([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState('');
  
  const [accounts, setAccounts] = useState([]);
  const [isAutoMapped, setIsAutoMapped] = useState(false);
  const [isFallback, setIsFallback] = useState(false);
  const [validationError, setValidationError] = useState('');

  const [formData, setFormData] = useState({
    vendor_name: '',
    bill_date: '',
    amount: '',
    category: '',
    description: '',
    fund_type: 'operating',
    debit_account_id: '',
    credit_account_id: ''
  });

  useEffect(() => {
    if (open) {
      fetchAssociationsAndInit();
    } else {
      setSelectedAssociationId('');
      setAccounts([]);
      setValidationError('');
      setAssociations([]);
      setFormData({
        vendor_name: '', bill_date: '', amount: '', category: '', description: '', fund_type: 'operating', debit_account_id: '', credit_account_id: ''
      });
    }
  }, [open, invoice]);

  useEffect(() => {
    if (open && selectedAssociationId) {
      fetchAccountsForAssociation(selectedAssociationId);
    }
  }, [selectedAssociationId]);

  const fetchAssociationsAndInit = async () => {
    setLoadingInitial(true);
    try {
      const { data, error } = await supabase
        .from('associations')
        .select('id, name')
        .order('name');
        
      if (error) throw error;
      setAssociations(data || []);

      if (invoice) {
        setFormData({
          vendor_name: invoice.vendor_name || '',
          bill_date: invoice.issue_date || new Date().toISOString().split('T')[0],
          amount: invoice.amount || 0,
          category: invoice.category || '',
          description: invoice.description || 'Parsed Invoice',
          fund_type: 'operating',
          debit_account_id: '',
          credit_account_id: ''
        });

        if (invoice.association_id) {
          setSelectedAssociationId(invoice.association_id);
        }
      }
    } catch (err) {
      console.error("Error fetching associations:", err);
      toast({ title: 'Error', description: 'Failed to load associations.', variant: 'destructive' });
    } finally {
      setLoadingInitial(false);
    }
  };

  const fetchAccountsForAssociation = async (associationId) => {
    setLoadingAccounts(true);
    setValidationError('');
    try {
      const { data: accData, error: accError } = await supabase
        .from('chart_of_accounts')
        .select('*')
        .eq('is_active', true)
        .eq('association_id', associationId)
        .order('account_number');
        
      if (accError) throw accError;
      setAccounts(accData || []);
      setIsAutoMapped(false);
      setIsFallback(false);
    } catch (err) {
      console.error(err);
      toast({ title: 'Error', description: 'Failed to load account data.', variant: 'destructive' });
    } finally {
      setLoadingAccounts(false);
    }
  };

  const handleAssociationChange = (val) => {
    if (selectedAssociationId && val !== selectedAssociationId) {
      toast({ title: "Association Changed", description: "Account mappings have been reset." });
    }
    
    setSelectedAssociationId(val);
    setFormData(prev => ({
      ...prev,
      debit_account_id: '',
      credit_account_id: ''
    }));
    setIsAutoMapped(false);
    setIsFallback(false);
  };

  const handleManualOverride = (field, value) => {
    setFormData(prev => ({ ...prev, [field]: value }));
    if (field === 'debit_account_id' || field === 'credit_account_id') {
      setIsAutoMapped(false);
    }
    setValidationError('');
  };

  const validateSubmission = () => {
    if (!selectedAssociationId) return "Please select an Association.";
    
    const debitAcc = accounts.find(a => a.id === formData.debit_account_id);
    const creditAcc = accounts.find(a => a.id === formData.credit_account_id);

    if (!debitAcc) return "Please select a Debit Account.";
    if (!creditAcc) return "Please select a Credit Account.";

    return null;
  };

  const handleSubmit = async () => {
    const vErr = validateSubmission();
    if (vErr) {
      setValidationError(vErr);
      return;
    }

    setSaving(true);
    try {
      let finalVendorId = null;
      if (formData.vendor_name) {
        const { data: vData } = await supabase
          .from('vendors')
          .select('id')
          .ilike('vendor_name', formData.vendor_name)
          .eq('association_id', selectedAssociationId)
          .maybeSingle();

        if (vData) {
          finalVendorId = vData.id;
        } else {
          const { data: newV } = await supabase
            .from('vendors')
            .insert({ vendor_name: formData.vendor_name, association_id: selectedAssociationId })
            .select('id')
            .single();
          finalVendorId = newV?.id;
        }
      }

      const { data: newBill, error: billError } = await supabase.from('bills').insert({
        vendor_id: finalVendorId,
        association_id: selectedAssociationId,
        bill_date: formData.bill_date,
        due_date: invoice?.due_date || formData.bill_date,
        amount: formData.amount,
        description: formData.description,
        status: 'pending',
        invoice_number: invoice?.invoice_number,
        expense_account_id: formData.debit_account_id,
        attachment_url: invoice?.raw_pdf_url || null,
        created_by: user?.id,
      }).select('id').single();

      if (billError) throw billError;

      if (invoice?.id) {
        await supabase.from('invoices')
          .update({ 
            status: 'converted_to_bill',
            association_id: selectedAssociationId
          })
          .eq('id', invoice.id);
      }
      
      toast({ title: 'Bill Created', description: 'Invoice successfully mapped and routed to GL.' });
      onSuccess?.();
      onOpenChange(false);
    } catch (err) {
      console.error(err);
      setValidationError(err.message || 'An error occurred while saving.');
    } finally {
      setSaving(false);
    }
  };

  const selectedAssocName = associations.find(c => c.id === selectedAssociationId)?.name;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[700px] bg-muted/30 max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="text-xl font-bold flex items-center gap-2">
            Review & Map Invoice Accounts
          </DialogTitle>
        </DialogHeader>

        {loadingInitial ? (
          <div className="flex justify-center items-center py-12"><Loader2 className="w-8 h-8 animate-spin text-primary"/></div>
        ) : (
          <div className="space-y-6 pt-4">
            
            {/* Association Selection */}
            <div className="bg-card p-5 rounded-xl border shadow-sm">
               <Label className="text-sm font-semibold flex items-center mb-2">
                 <Building2 className="w-4 h-4 mr-2 text-muted-foreground" />
                 Select Association
               </Label>
               <Select value={selectedAssociationId} onValueChange={handleAssociationChange}>
                  <SelectTrigger className={`bg-muted/50 border font-medium ${!selectedAssociationId ? 'text-muted-foreground' : ''}`}>
                    <SelectValue placeholder="Choose an association..." />
                  </SelectTrigger>
                  <SelectContent className="max-h-[250px]">
                     {associations.map(c => (
                        <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
                     ))}
                  </SelectContent>
               </Select>
               {selectedAssociationId && selectedAssocName && (
                 <p className="text-xs text-muted-foreground mt-2">Mapping accounts for: <strong>{selectedAssocName}</strong></p>
               )}
            </div>

            {!selectedAssociationId ? (
               <div className="bg-amber-50 border border-amber-200 p-6 rounded-xl text-center">
                  <AlertTriangle className="w-8 h-8 text-amber-400 mx-auto mb-2" />
                  <h3 className="text-amber-800 font-semibold mb-1">Association Selection Required</h3>
                  <p className="text-amber-700 text-sm">Please select an association above to load their chart of accounts.</p>
               </div>
            ) : loadingAccounts ? (
               <div className="flex justify-center items-center py-12 bg-card rounded-xl border"><Loader2 className="w-6 h-6 animate-spin text-primary mr-2"/> Loading accounts...</div>
            ) : (
              <div className="space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-300">
                {/* Status Banner */}
                <div className={`p-4 rounded-lg border flex items-start gap-3 shadow-sm ${
                  isAutoMapped && !isFallback ? 'bg-emerald-50 border-emerald-200' :
                  isAutoMapped && isFallback ? 'bg-amber-50 border-amber-200' :
                  'bg-blue-50 border-blue-200'
                }`}>
                  {isAutoMapped && !isFallback ? <Sparkles className="text-emerald-500 w-5 h-5 shrink-0 mt-0.5" /> :
                   isAutoMapped && isFallback ? <AlertTriangle className="text-amber-500 w-5 h-5 shrink-0 mt-0.5" /> :
                   <Edit2 className="text-blue-500 w-5 h-5 shrink-0 mt-0.5" />}
                  <div>
                    <p className={`font-semibold ${isAutoMapped && !isFallback ? 'text-emerald-800' : isAutoMapped && isFallback ? 'text-amber-800' : 'text-blue-800'}`}>
                      {isAutoMapped && !isFallback ? 'Auto-Mapped Successfully' : 
                       isAutoMapped && isFallback ? 'Fallback Rule Applied' : 
                       'Manual Mapping Required'}
                    </p>
                    <p className="text-sm text-muted-foreground mt-1">
                      {isAutoMapped ? 'Please verify the account mapping below.' : 
                       'Please manually select the Debit (Expense) and Credit (Liability) accounts.'}
                    </p>
                  </div>
                </div>

                {/* Core Invoice Details */}
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 bg-card p-4 rounded-xl border shadow-sm">
                  <div className="space-y-1.5">
                    <Label>Vendor Name</Label>
                    <Input className="bg-muted/50 font-medium" value={formData.vendor_name} onChange={e => handleManualOverride('vendor_name', e.target.value)} />
                  </div>
                  <div className="space-y-1.5">
                    <Label>Amount</Label>
                    <Input type="number" step="0.01" className="bg-muted/50 font-medium" value={formData.amount} onChange={e => handleManualOverride('amount', e.target.value)} />
                  </div>
                  <div className="space-y-1.5">
                    <Label>Bill Date</Label>
                    <Input type="date" className="bg-muted/50 font-medium" value={formData.bill_date} onChange={e => handleManualOverride('bill_date', e.target.value)} />
                  </div>
                  <div className="space-y-1.5">
                    <Label>Category</Label>
                    <Input className="bg-muted/50 font-medium" value={formData.category} onChange={e => handleManualOverride('category', e.target.value)} placeholder="e.g. landscaping" />
                  </div>
                </div>

                {/* Accounting Routing */}
                <div className="bg-card p-5 rounded-xl border shadow-sm space-y-5">
                  <h3 className="font-semibold flex items-center border-b pb-2">
                    <CheckCircle2 className="w-4 h-4 mr-2 text-muted-foreground" /> General Ledger Routing
                  </h3>
                  
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
                    <AccountSelector 
                      label="Debit Account (Expense)"
                      requiredType="expense"
                      accounts={accounts}
                      value={formData.debit_account_id}
                      onChange={(val) => handleManualOverride('debit_account_id', val)}
                    />
                    
                    <AccountSelector 
                      label="Credit Account (Liability/AP)"
                      requiredType="liability"
                      accounts={accounts}
                      value={formData.credit_account_id}
                      onChange={(val) => handleManualOverride('credit_account_id', val)}
                    />
                  </div>
                  
                  <div className="space-y-1.5 pt-2">
                    <Label>Description / Memo</Label>
                    <Input className="bg-muted/50 font-medium" value={formData.description} onChange={e => handleManualOverride('description', e.target.value)} />
                  </div>
                </div>
              </div>
            )}

            {validationError && (
              <div className="bg-destructive/10 text-destructive p-3 rounded-md text-sm font-medium flex items-center border border-destructive/20">
                <AlertTriangle className="w-4 h-4 mr-2 shrink-0" />
                {validationError}
              </div>
            )}

            <div className="flex justify-end gap-3 pt-2">
              <Button variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
              <Button onClick={handleSubmit} disabled={saving || !selectedAssociationId} className="min-w-[140px]">
                {saving ? <Loader2 className="w-4 h-4 animate-spin mx-auto" /> : 'Confirm & Create Bill'}
              </Button>
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
