import React, { useState, useEffect } from 'react';
import { useForm, Controller, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { useAuth } from '@/contexts/AuthContext';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  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 { Textarea } from '@/components/ui/textarea';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Loader2, DollarSign, AlertCircle, Upload, X } from 'lucide-react';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';

const formSchema = z.object({
  association_id: z.string().min(1, "Association is required."),
  expense_account_id: z.string().min(1, "GL Account is required."),
  invoice_number: z.string().min(1, "Invoice number is required."),
  vendor_name: z.string().min(2, "Vendor name must be at least 2 characters."),
  bill_date: z.string().min(1, "Bill date is required."),
  due_date: z.string().min(1, "Due date is required."),
  amount: z.coerce.number().positive("Amount must be greater than 0."),
  description: z.string().optional(),
}).refine(data => {
  if (!data.bill_date || !data.due_date) return true;
  return new Date(data.due_date) >= new Date(data.bill_date);
}, {
  message: "Due date must be greater than or equal to bill date.",
  path: ["due_date"]
});

export default function EditBillDialog({ open, onOpenChange, bill, onSuccess }) {
  const { toast } = useToast();
  const { user } = useAuth();
  
  const [associations, setAssociations] = useState([]);
  const [coas, setCoas] = useState([]);
  const [loadingAssociations, setLoadingAssociations] = useState(false);
  const [loadingCoas, setLoadingCoas] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [fetchError, setFetchError] = useState(null);
  const [pdfFile, setPdfFile] = useState(null);

  const { register, handleSubmit, control, reset, formState: { errors, isValid } } = useForm({
    resolver: zodResolver(formSchema),
    defaultValues: {
      association_id: '',
      expense_account_id: '',
      invoice_number: '',
      vendor_name: '',
      bill_date: '',
      due_date: '',
      amount: '',
      description: '',
    },
    mode: 'onChange'
  });

  useEffect(() => {
    if (open && bill) {
      reset({
        association_id: bill.association_id || '',
        expense_account_id: bill.expense_account_id || '',
        invoice_number: bill.invoice_number || '',
        vendor_name: bill.vendor_name || '',
        bill_date: bill.bill_date || new Date().toISOString().split('T')[0],
        due_date: bill.due_date || new Date().toISOString().split('T')[0],
        amount: bill.amount || '',
        description: bill.description || '',
      });
      setPdfFile(null);
      setFetchError(null);
    }
  }, [open, bill, reset]);

  // Watch the selected association so we can re-load the COA
  // scoped to its accounting system (zoho vs buildium).
  const watchedAssociationId = useWatch({ control, name: 'association_id' });

  useEffect(() => {
    if (!open) return;

    async function fetchAssociations() {
      setLoadingAssociations(true);
      try {
        const { data: aData, error: aErr } = await supabase
          .from('associations')
          .select('id, name, zoho_organization_id')
          .eq('status', 'active')
          .order('name');
        if (aErr) throw aErr;
        setAssociations(aData || []);
      } catch (err) {
        console.error('Error fetching associations:', err);
        setFetchError('Failed to load associations.');
      } finally {
        setLoadingAssociations(false);
      }
    }

    fetchAssociations();
  }, [open]);

  useEffect(() => {
    if (!open) return;
    if (!watchedAssociationId) { setCoas([]); return; }

    async function fetchCoas() {
      setLoadingCoas(true);
      try {
        const assoc = associations.find(a => a.id === watchedAssociationId);
        const system = assoc?.zoho_organization_id ? 'zoho' : 'buildium';
        const { data: coaData, error: coaErr } = await supabase
          .from('chart_of_accounts')
          .select('id, account_name, account_number, account_type')
          .eq('is_active', true)
          .eq('accounting_system', system)
          .order('account_number');
        if (coaErr) throw coaErr;
        setCoas(coaData || []);
      } catch (err) {
        console.error('Error fetching chart of accounts:', err);
        setFetchError('Failed to load chart of accounts.');
      } finally {
        setLoadingCoas(false);
      }
    }

    fetchCoas();
  }, [open, watchedAssociationId, associations]);

  const uploadPdf = async () => {
    if (!pdfFile) return null;
    const fileExt = pdfFile.name.split('.').pop();
    const fileName = `${crypto.randomUUID()}.${fileExt}`;
    const filePath = `bills/${fileName}`;

    const { error: uploadError } = await supabase.storage
      .from('files')
      .upload(filePath, pdfFile);

    if (uploadError) throw uploadError;

    const { data } = supabase.storage.from('files').getPublicUrl(filePath);
    return data.publicUrl;
  };

  const onSubmit = async (data) => {
    setIsSubmitting(true);
    try {
      let pdfUrl = bill.attachment_url;
      if (pdfFile) {
        pdfUrl = await uploadPdf();
      }

      const { error: billError } = await supabase
        .from('bills')
        .update({
          association_id: data.association_id,
          expense_account_id: data.expense_account_id,
          bill_date: data.bill_date,
          due_date: data.due_date,
          amount: data.amount,
          description: data.description || `Invoice ${data.invoice_number} from ${data.vendor_name}`,
          invoice_number: data.invoice_number,
          attachment_url: pdfUrl,
        })
        .eq('id', bill.id);

      if (billError) throw billError;

      toast({
        title: "Bill Updated Successfully",
        description: "The bill has been updated.",
      });

      onSuccess();
      onOpenChange(false);
    } catch (err) {
      console.error('Update error:', err);
      toast({
        title: "Failed to update bill",
        description: err.message || "An unexpected error occurred.",
        variant: "destructive"
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px] max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="text-xl">Edit Bill {bill?.invoice_number ? `(${bill.invoice_number})` : ''}</DialogTitle>
          <DialogDescription>
            Update bill details and ensure accounting records remain balanced.
          </DialogDescription>
        </DialogHeader>

        {fetchError && (
          <Alert variant="destructive" className="mt-2">
            <AlertCircle className="h-4 w-4" />
            <AlertTitle>Error</AlertTitle>
            <AlertDescription>{fetchError}</AlertDescription>
          </Alert>
        )}

        <form onSubmit={handleSubmit(onSubmit)} className="space-y-5 py-4">
          
          <div className="space-y-2">
            <Label htmlFor="association_id" className="font-semibold">Association <span className="text-destructive">*</span></Label>
            <Controller
              control={control}
              name="association_id"
              render={({ field }) => (
                <Select onValueChange={field.onChange} value={field.value} disabled={loadingAssociations || isSubmitting}>
                  <SelectTrigger className={errors.association_id ? 'border-destructive' : ''}>
                    <SelectValue placeholder={loadingAssociations ? "Loading..." : "Select Association"} />
                  </SelectTrigger>
                  <SelectContent>
                    {associations.map(a => (
                      <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              )}
            />
            {errors.association_id && <p className="text-xs text-destructive">{errors.association_id.message}</p>}
          </div>

          <div className="space-y-2">
            <Label htmlFor="expense_account_id" className="font-semibold">GL Account (Expense) <span className="text-destructive">*</span></Label>
            <Controller
              control={control}
              name="expense_account_id"
              render={({ field }) => (
                <Select onValueChange={field.onChange} value={field.value} disabled={isSubmitting || loadingCoas}>
                  <SelectTrigger className={errors.expense_account_id ? 'border-destructive' : ''}>
                    <SelectValue placeholder={loadingCoas ? "Loading..." : "Select Expense Account"} />
                  </SelectTrigger>
                  <SelectContent>
                    {coas.map(acc => (
                      <SelectItem key={acc.id} value={acc.id}>
                        {acc.account_number} - {acc.account_name}
                      </SelectItem>
                    ))}
                    {coas.length === 0 && !loadingCoas && (
                       <SelectItem value="none" disabled>No expense accounts found.</SelectItem>
                    )}
                  </SelectContent>
                </Select>
              )}
            />
            {errors.expense_account_id && <p className="text-xs text-destructive">{errors.expense_account_id.message}</p>}
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="invoice_number" className="font-semibold">Bill/Invoice Number <span className="text-destructive">*</span></Label>
              <Input 
                id="invoice_number" 
                {...register('invoice_number')} 
                className={errors.invoice_number ? 'border-destructive' : ''}
              />
              {errors.invoice_number && <p className="text-xs text-destructive">{errors.invoice_number.message}</p>}
            </div>

            <div className="space-y-2">
              <Label htmlFor="vendor_name" className="font-semibold">Vendor Name <span className="text-destructive">*</span></Label>
              <Input 
                id="vendor_name" 
                {...register('vendor_name')} 
                className={errors.vendor_name ? 'border-destructive' : ''}
              />
              {errors.vendor_name && <p className="text-xs text-destructive">{errors.vendor_name.message}</p>}
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="bill_date" className="font-semibold">Bill Date <span className="text-destructive">*</span></Label>
              <Input 
                id="bill_date" 
                type="date" 
                {...register('bill_date')} 
                className={errors.bill_date ? 'border-destructive' : ''}
              />
              {errors.bill_date && <p className="text-xs text-destructive">{errors.bill_date.message}</p>}
            </div>

            <div className="space-y-2">
              <Label htmlFor="due_date" className="font-semibold">Due Date <span className="text-destructive">*</span></Label>
              <Input 
                id="due_date" 
                type="date" 
                {...register('due_date')} 
                className={errors.due_date ? 'border-destructive' : ''}
              />
              {errors.due_date && <p className="text-xs text-destructive">{errors.due_date.message}</p>}
            </div>
          </div>

          <div className="space-y-2">
            <Label htmlFor="amount" className="font-semibold">Amount <span className="text-destructive">*</span></Label>
            <div className="relative">
              <DollarSign className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
              <Input 
                id="amount" 
                type="number" 
                step="0.01" 
                className={`pl-9 ${errors.amount ? 'border-destructive' : ''}`}
                placeholder="0.00" 
                {...register('amount')} 
              />
            </div>
            {errors.amount && <p className="text-xs text-destructive">{errors.amount.message}</p>}
          </div>

          <div className="space-y-2">
            <Label htmlFor="description" className="font-semibold">Description / Notes</Label>
            <Textarea 
              id="description" 
              placeholder="Optional notes about this bill..." 
              {...register('description')} 
              className="min-h-[80px]"
            />
          </div>

           <div className="space-y-2">
              <Label className="font-semibold">Supporting Document (PDF)</Label>
              <div className="border-2 border-dashed rounded-lg p-4 hover:bg-muted/50 transition-colors text-center cursor-pointer relative">
                <Input 
                  type="file" 
                  onChange={(e) => setPdfFile(e.target.files?.[0] || null)} 
                  className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10" 
                  accept=".pdf,.png,.jpg,.jpeg"
                />
                {pdfFile ? (
                  <div className="flex flex-col items-center gap-2 text-primary">
                    <div className="font-medium truncate max-w-[250px]">{pdfFile.name}</div>
                    <Button 
                      type="button" 
                      variant="ghost" 
                      size="sm" 
                      className="h-8 text-destructive hover:text-destructive z-20 relative"
                      onClick={(e) => {
                        e.stopPropagation();
                        setPdfFile(null);
                      }}
                    >
                      <X className="w-4 h-4 mr-1" /> Remove
                    </Button>
                  </div>
                ) : (
                  <div className="flex flex-col items-center gap-2 text-muted-foreground">
                    <div className="bg-primary/10 p-2 rounded-full">
                      <Upload className="w-5 h-5 text-primary" />
                    </div>
                    {bill?.attachment_url ? (
                       <span className="text-sm font-medium">Existing PDF attached. Click to replace.</span>
                    ) : (
                       <span className="text-sm font-medium">Click to upload or drag and drop</span>
                    )}
                  </div>
                )}
              </div>
            </div>

          <div className="pt-4 mt-6 border-t flex justify-end gap-3">
            <Button 
              type="button" 
              variant="outline" 
              onClick={() => onOpenChange(false)}
              disabled={isSubmitting}
            >
              Cancel
            </Button>
            <Button 
              type="submit" 
              disabled={isSubmitting || !isValid}
              className="min-w-[120px]"
            >
              {isSubmitting ? (
                <><Loader2 className="mr-2 h-4 w-4 animate-spin" /> Saving...</>
              ) : (
                'Save Changes'
              )}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}
