import React, { useState, useEffect, useRef } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Badge } from '@/components/ui/badge';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { useAuth } from '@/contexts/AuthContext';
import { Upload, FileText, X, PlusCircle, Trash2, Plus, RefreshCw, Loader2 } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';

let lastUsedContext = {
  association_id: '',
  address: 'Association-level',
  date: new Date().toISOString().split('T')[0],
  receipt_url: ''
};

function ExpenseDialog({ open, onOpenChange, onSuccess, expense }) {
  const { user } = useAuth();
  const { toast } = useToast();
  
  const [loading, setLoading] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [associations, setAssociations] = useState([]);
  
  const saveAndAddRef = useRef(false);

  const [headerData, setHeaderData] = useState({
    association_id: '',
    date: new Date().toISOString().split('T')[0],
    address: 'Association-level',
    receipt_url: '',
  });
  
  const [isCredit, setIsCredit] = useState(false);
  const [creditReason, setCreditReason] = useState('');

  const [lineItems, setLineItems] = useState([]);

  const fetchInitialData = async () => {
    try {
      const { data: assocData } = await supabase.from('associations').select('id, name').eq('status', 'active').order('name');
      setAssociations(assocData || []);
    } catch (err) {
      console.error('Failed to fetch initial data:', err);
    }
  };

  useEffect(() => {
    if (open) {
      fetchInitialData();

      if (expense) {
        setHeaderData({
          association_id: expense.association_id,
          date: expense.date ? expense.date.split('T')[0] : new Date().toISOString().split('T')[0],
          address: expense.address || 'Association-level',
          receipt_url: expense.receipt_url || '',
        });
        
        setIsCredit(expense.is_credit || false);
        setCreditReason(expense.credit_reason || '');

        setLineItems([{
          id: expense.id, 
          category: expense.category || 'General',
          description: expense.description || '',
          billable_type: expense.billable_type || 'Expense',
          unit_price: Math.abs(expense.unit_price || 0), 
          quantity: expense.quantity || 1,
          amount: Math.abs(expense.amount || 0) 
        }]);
      } else {
        setHeaderData({
          association_id: lastUsedContext.association_id || '',
          date: lastUsedContext.date || new Date().toISOString().split('T')[0],
          address: lastUsedContext.address || 'Association-level',
          receipt_url: '', 
        });
        
        setIsCredit(false);
        setCreditReason('');

        setLineItems([{
          id: crypto.randomUUID(),
          category: 'General',
          description: '',
          billable_type: 'Expense',
          quantity: 1,
          unit_price: 0,
          amount: 0
        }]);
      }
    }
  }, [open, expense]); 

  const updateLineItem = (id, field, value) => {
    setLineItems(prev => prev.map(item => {
      if (item.id === id) {
        let updated = { ...item, [field]: value };
        if (field === 'quantity' || field === 'unit_price') {
          const q = field === 'quantity' ? parseFloat(value) : parseFloat(item.quantity);
          const p = field === 'unit_price' ? parseFloat(value) : parseFloat(item.unit_price);
          updated.amount = (isNaN(q) ? 0 : q) * (isNaN(p) ? 0 : p);
        }
        if (field === 'amount') {
          updated.amount = parseFloat(value);
        }
        return updated;
      }
      return item;
    }));
  };

  const addLineItem = () => {
    setLineItems(prev => [...prev, {
      id: crypto.randomUUID(),
      category: 'General',
      description: '',
      billable_type: 'Expense',
      quantity: 1,
      unit_price: 0,
      amount: 0
    }]);
  };

  const removeLineItem = (id) => {
    if (lineItems.length <= 1) {
      setLineItems([{
        id: crypto.randomUUID(),
        category: 'General',
        description: '',
        billable_type: 'Expense',
        quantity: 1,
        unit_price: 0,
        amount: 0
      }]);
      return;
    }
    setLineItems(prev => prev.filter(item => item.id !== id));
  };

  const handleFileUpload = async (e) => {
    if (!e.target.files || !e.target.files[0]) return;
    const file = e.target.files[0];
    const fileExt = file.name.split('.').pop();
    const fileName = `${Math.random().toString(36).substring(2)}-${Date.now()}.${fileExt}`;

    setUploading(true);
    try {
      const { error: uploadError } = await supabase.storage
        .from('files')
        .upload(fileName, file);
      if (uploadError) throw uploadError;

      const { data: urlData } = supabase.storage
        .from('files')
        .getPublicUrl(fileName);

      setHeaderData(prev => ({ ...prev, receipt_url: urlData.publicUrl }));
      toast({ title: "Receipt attached successfully" });
    } catch (error) {
      toast({ variant: "destructive", title: "Upload failed", description: error.message });
    } finally {
      setUploading(false);
    }
  };

  const handleRemoveReceipt = () => {
    setHeaderData(prev => ({ ...prev, receipt_url: '' }));
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);

    if (!headerData.association_id) {
      toast({ variant: "destructive", title: "Error", description: "Please select an association." });
      setLoading(false);
      return;
    }

    if (lineItems.length === 0) {
      toast({ variant: "destructive", title: "Error", description: "Add at least one expense item." });
      setLoading(false);
      return;
    }

    try {
      const baseData = {
        association_id: headerData.association_id,
        date: headerData.date,
        address: headerData.address || 'Association-level',
        receipt_url: headerData.receipt_url,
        created_by: user?.id,
        is_credit: isCredit,
        credit_reason: isCredit ? creditReason : null,
      };

      const processedItems = lineItems.map(item => {
        let finalAmount = Math.abs(parseFloat(item.amount));
        if (isCredit) finalAmount = -finalAmount;
        let finalUnitPrice = Math.abs(parseFloat(item.unit_price));
        if (isCredit) finalUnitPrice = -finalUnitPrice;

        return {
          ...item,
          amount: finalAmount,
          unit_price: finalUnitPrice,
          quantity: Math.abs(parseFloat(item.quantity)) 
        };
      });

      if (expense) {
        const item = processedItems[0]; 
        const { error } = await supabase
          .from('billable_expenses')
          .update({
            ...baseData,
            category: item.category || 'General',
            description: item.description,
            amount: item.amount,
            quantity: item.quantity,
            unit_price: item.unit_price,
            billable_type: item.billable_type,
          })
          .eq('id', expense.id);
        if (error) throw error;
      } else {
        const rowsToInsert = processedItems.map(item => ({
          ...baseData,
          category: item.category || 'General',
          description: item.description,
          amount: item.amount,
          quantity: item.quantity,
          unit_price: item.unit_price,
          billable_type: item.billable_type,
          status: 'pending'
        }));

        const { error } = await supabase.from('billable_expenses').insert(rowsToInsert);
        if (error) throw error;

        lastUsedContext = {
          association_id: headerData.association_id,
          address: headerData.address,
          date: headerData.date,
        };
      }

      toast({
        title: expense ? "Expense Updated" : "Expenses Saved",
        description: saveAndAddRef.current ? "Saved! Ready for the next entry." : "Expense records have been successfully saved.",
      });

      onSuccess();

      if (saveAndAddRef.current) {
        setLineItems([{
          id: crypto.randomUUID(),
          category: 'General',
          description: '',
          billable_type: 'Expense',
          quantity: 1,
          unit_price: 0,
          amount: 0
        }]);
        setIsCredit(false);
        setCreditReason('');
        setHeaderData(prev => ({ ...prev, receipt_url: '' }));
        saveAndAddRef.current = false;
      } else {
        onOpenChange(false);
      }
    } catch (error) {
      console.error("Submit error:", error);
      toast({ variant: "destructive", title: "Error", description: error.message });
    } finally {
      setLoading(false);
    }
  };

  const formatCurrency = (amount) => {
    return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount);
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[1000px] max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>{expense ? 'Edit Expense' : 'Add Expenses'}</DialogTitle>
          <DialogDescription>
            {expense ? 'Update the details for this expense record.' : 'Create one or more billable expense records.'}
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-6 py-2">
          
          <div className="grid grid-cols-2 gap-4 p-4 bg-muted/50 rounded-lg border">
            <div className="space-y-2">
              <Label htmlFor="association">Association</Label>
              <Select
                value={headerData.association_id}
                onValueChange={(val) => {
                  setHeaderData({ ...headerData, association_id: val, address: 'Association-level' });
                }}
                disabled={!!expense}
              >
                <SelectTrigger className="bg-background">
                  <SelectValue placeholder="Select Association..." />
                </SelectTrigger>
                <SelectContent>
                  {(associations || []).map(a => (
                    <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label htmlFor="date">Date</Label>
              <Input
                id="date"
                type="date"
                value={headerData.date}
                onChange={(e) => setHeaderData({ ...headerData, date: e.target.value })}
                required
                className="bg-background"
              />
            </div>
          </div>

          <div className="flex flex-col gap-4 p-4 border rounded-lg bg-accent/20">
            <div className="flex items-center justify-between">
              <div className="flex items-center space-x-2">
                <Switch 
                  id="credit-mode" 
                  checked={isCredit} 
                  onCheckedChange={setIsCredit} 
                />
                <Label htmlFor="credit-mode" className="flex items-center gap-2 font-medium cursor-pointer">
                  <RefreshCw className={`w-4 h-4 ${isCredit ? 'text-primary' : 'text-muted-foreground'}`} />
                  Mark as Credit/Refund
                </Label>
              </div>
              {isCredit && (
                <Badge variant="outline">Amounts will be negative</Badge>
              )}
            </div>

            {isCredit && (
              <div className="space-y-2">
                <Label className="text-xs text-muted-foreground">Credit Reason / Notes</Label>
                <Textarea 
                  value={creditReason}
                  onChange={(e) => setCreditReason(e.target.value)}
                  placeholder="Reason for refund..."
                  className="h-[38px] min-h-[38px] py-2 text-xs bg-background resize-none"
                />
              </div>
            )}
          </div>

          <div className="space-y-2">
            <div className="flex justify-between items-center mb-1">
              <Label>Line Items</Label>
              {!expense && (
                <Button type="button" size="sm" variant="ghost" onClick={addLineItem} className="h-7 text-xs">
                  <Plus className="w-3 h-3 mr-1" /> Add Row
                </Button>
              )}
            </div>
            
            <div className="space-y-3">
              {(lineItems || []).map((item, index) => (
                <div key={item.id} className="rounded-lg border bg-background p-4 space-y-3">
                  <div className="flex items-center justify-between">
                    <span className="text-xs font-medium text-muted-foreground">Item {index + 1}</span>
                    {!expense && (
                      <Button 
                        type="button" variant="ghost" size="icon" 
                        className="h-7 w-7 text-muted-foreground hover:text-destructive"
                        onClick={() => removeLineItem(item.id)}
                      >
                        <Trash2 className="w-3.5 h-3.5" />
                      </Button>
                    )}
                  </div>
                  <div className="grid grid-cols-2 gap-3">
                    <div className="space-y-1.5">
                      <Label className="text-xs text-muted-foreground">Category</Label>
                      <Input
                        value={item.category}
                        onChange={(e) => updateLineItem(item.id, 'category', e.target.value)}
                        placeholder="Category..."
                      />
                    </div>
                    <div className="space-y-1.5">
                      <Label className="text-xs text-muted-foreground">Description</Label>
                      <Input
                        value={item.description}
                        onChange={(e) => updateLineItem(item.id, 'description', e.target.value)}
                        placeholder="Item description..."
                      />
                    </div>
                  </div>
                  <div className="grid grid-cols-3 gap-3">
                    <div className="space-y-1.5">
                      <Label className="text-xs text-muted-foreground">Qty</Label>
                      <Input 
                        type="number" min="0" step="0.01"
                        value={item.quantity}
                        onChange={(e) => updateLineItem(item.id, 'quantity', e.target.value)}
                      />
                    </div>
                    <div className="space-y-1.5">
                      <Label className="text-xs text-muted-foreground">Rate</Label>
                      <Input 
                        type="number" min="0" step="0.01"
                        value={item.unit_price}
                        onChange={(e) => updateLineItem(item.id, 'unit_price', e.target.value)}
                      />
                    </div>
                    <div className="space-y-1.5">
                      <Label className="text-xs text-muted-foreground">Amount</Label>
                      <div className={`h-9 flex items-center justify-end px-3 text-sm font-semibold rounded-md border ${isCredit ? 'bg-destructive/10 text-destructive' : 'bg-muted'}`}>
                        {isCredit && '-'}${parseFloat(item.amount || 0).toFixed(2)}
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="space-y-2 border-t pt-4">
            <Label>Receipt Attachment</Label>
            {!headerData.receipt_url ? (
              <div className="border-2 border-dashed rounded-lg p-4 flex flex-col items-center justify-center bg-muted/30 hover:bg-muted/50 transition-colors cursor-pointer relative">
                <input 
                  type="file" accept="image/*,application/pdf" 
                  className="absolute inset-0 opacity-0 cursor-pointer"
                  onChange={handleFileUpload} disabled={uploading}
                />
                <Upload className={`w-6 h-6 mb-2 ${uploading ? 'text-muted-foreground animate-pulse' : 'text-muted-foreground'}`} />
                <span className="text-sm font-medium">{uploading ? 'Uploading...' : 'Click to upload receipt'}</span>
                <span className="text-xs text-muted-foreground mt-1">PDF, PNG, JPG up to 5MB</span>
              </div>
            ) : (
              <div className="flex items-center justify-between p-3 bg-accent/30 border rounded-lg">
                <div className="flex items-center space-x-3">
                  <div className="bg-background p-2 rounded-md border">
                    <FileText className="w-5 h-5 text-primary" />
                  </div>
                  <div className="flex flex-col">
                    <span className="text-sm font-medium">Receipt Attached</span>
                    <a href={headerData.receipt_url} target="_blank" rel="noopener noreferrer" className="text-xs text-primary hover:underline truncate max-w-[200px]">
                      View File
                    </a>
                  </div>
                </div>
                <Button type="button" variant="ghost" size="icon" onClick={handleRemoveReceipt}>
                  <X className="w-4 h-4" />
                </Button>
              </div>
            )}
          </div>

          <DialogFooter className="flex items-center justify-between sm:justify-between w-full pt-4">
            <Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>Cancel</Button>
            <div className="flex gap-2">
              {!expense && (
                <Button 
                  type="submit" variant="outline"
                  disabled={loading || uploading} 
                  onClick={() => { saveAndAddRef.current = true; }}
                >
                  <PlusCircle className="w-4 h-4 mr-2" />
                  Save & Add Another
                </Button>
              )}
              <Button 
                type="submit" 
                disabled={loading || uploading} 
                onClick={() => { saveAndAddRef.current = false; }}
                className="min-w-[120px]"
              >
                {loading ? 'Saving...' : (expense ? 'Update Expense' : `Save ${lineItems.length} Expenses`)}
              </Button>
            </div>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export default ExpenseDialog;
