import React, { useState, useEffect, useMemo } from 'react';
import { groupOwnersByUnit, combineOwnerNames, collectAllAddresses } from '@/lib/ownerAddressUtils';
import { supabase } from '@/integrations/supabase/client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Loader2, User, Search, Copy, ArrowLeft, Eye, Download } from 'lucide-react';
import { Switch } from '@/components/ui/switch';
import { useToast } from '@/hooks/use-toast';
import { ScrollArea } from '@/components/ui/scroll-area';
import { PaymentCouponPreview } from '@/components/forms/PaymentCouponPreview';
import { PaymentCouponHTMLPreview } from '@/components/forms/PaymentCouponHTMLPreview';
import { Textarea } from '@/components/ui/textarea';
import { jsPDF } from 'jspdf';
import html2canvas from 'html2canvas';

export default function PaymentCouponForm() {
  const { toast } = useToast();
  const [associations, setAssociations] = useState([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState('');
  const [selectedAssociationData, setSelectedAssociationData] = useState(null);
  const [owners, setOwners] = useState([]);
  const [selectedOwnerIds, setSelectedOwnerIds] = useState([]);
  const [isLoadingOwners, setIsLoadingOwners] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const [showPrintPreview, setShowPrintPreview] = useState(false);
  const [associationAddress, setAssociationAddress] = useState('');
  const [isGeneratingPDF, setIsGeneratingPDF] = useState(false);
  const [useCompanyAsSender, setUseCompanyAsSender] = useState(false);
  const [companySettings, setCompanySettings] = useState({});

  const [couponData, setCouponData] = useState([
    { id: 1, amount: '', paymentNumber: '', dueDate: '', lateFeeDate: '' },
    { id: 2, amount: '', paymentNumber: '', dueDate: '', lateFeeDate: '' },
    { id: 3, amount: '', paymentNumber: '', dueDate: '', lateFeeDate: '' },
  ]);

  // Fetch Associations
  useEffect(() => {
    const fetchAssociations = async () => {
      const { data } = await supabase
        .from('associations')
        .select('id, name, mailing_address, care_of_address, address, city, state, zip')
        .eq('status', 'active')
        .order('name');
      setAssociations(data || []);
    };
    fetchAssociations();

    // Load company settings
    supabase.from('company_settings').select('key, value')
      .then(({ data }) => {
        const s = {};
        (data || []).forEach(r => { s[r.key] = r.value; });
        setCompanySettings(s);
      });
  }, []);

  // Fetch Owners when association changes
  useEffect(() => {
    if (selectedAssociationId) {
      const fetchOwners = async () => {
        setIsLoadingOwners(true);
        const { data } = await supabase
          .from('owners')
          .select('*, units(unit_number, account_number, address)')
          .eq('association_id', selectedAssociationId)
          .eq('status', 'active')
          .order('last_name');
        setOwners(data || []);
        setIsLoadingOwners(false);
        
        const assoc = associations.find(a => a.id === selectedAssociationId);
        setSelectedAssociationData(assoc);
        // Build association address — only use name, c/o, and mailing address
        const addrParts = [];
        if (assoc?.name) addrParts.push(assoc.name);
        if (assoc?.care_of_address) addrParts.push(`C/O ${assoc.care_of_address}`);
        if (assoc?.mailing_address) addrParts.push(assoc.mailing_address);
        setAssociationAddress(addrParts.join('\n'));
      };
      fetchOwners();
    } else {
      setOwners([]);
      setSelectedOwnerIds([]);
      setSelectedAssociationData(null);
      setAssociationAddress('');
    }
  }, [selectedAssociationId, associations]);

  const handleOwnerToggle = (id) => {
    setSelectedOwnerIds(prev => 
      prev.includes(id) ? prev.filter(oid => oid !== id) : [...prev, id]
    );
  };

  const handleSelectAll = () => {
    if (filteredOwners.length === 0) return;
    const allFilteredSelected = filteredOwners.every(o => selectedOwnerIds.includes(o.id));
    if (allFilteredSelected) {
      const filteredIds = filteredOwners.map(o => o.id);
      setSelectedOwnerIds(prev => prev.filter(id => !filteredIds.includes(id)));
    } else {
      const filteredIds = filteredOwners.map(o => o.id);
      setSelectedOwnerIds(prev => [...new Set([...prev, ...filteredIds])]);
    }
  };

  const handleCouponChange = (index, field, value) => {
    const newData = [...couponData];
    newData[index][field] = value;
    setCouponData(newData);
  };

  const copyFirstToOthers = () => {
    const first = couponData[0];
    const newData = couponData.map((c, i) => {
      if (i === 0) return c;
      return { ...c, amount: first.amount, lateFeeDate: first.lateFeeDate };
    });
    setCouponData(newData);
    toast({ description: "Copied Amount and Late Fee Date to all coupons." });
  };

  const handleGeneratePDF = async () => {
    if (selectedOwnerIds.length === 0) {
      toast({ variant: "destructive", title: "Validation Error", description: "Please select at least one owner." });
      return;
    }

    setIsGeneratingPDF(true);
    toast({ title: "Generating PDF", description: "Please wait while we prepare your document." });

    try {
      const pages = document.querySelectorAll('.coupon-pdf-page');
      if (!pages || pages.length === 0) {
        throw new Error("Could not find coupon pages to render.");
      }

      const pdf = new jsPDF({ orientation: 'portrait', unit: 'in', format: 'letter', compress: true });

      for (let i = 0; i < pages.length; i++) {
        if (i > 0) pdf.addPage();
        const canvas = await html2canvas(pages[i], {
          scale: 2, useCORS: true, logging: false, backgroundColor: '#ffffff'
        });
        const imgData = canvas.toDataURL('image/jpeg', 0.95);
        pdf.addImage(imgData, 'JPEG', 0, 0, 8.5, 11);
      }

      const dateStr = new Date().toISOString().split('T')[0].replace(/-/g, '');
      pdf.save(`PaymentCoupon_${dateStr}.pdf`);
      
      toast({ title: "Success", description: "PDF has been generated and downloaded." });
    } catch (error) {
      console.error('[PaymentCouponForm] PDF Generation Failed:', error);
      toast({ variant: "destructive", title: "Generation Failed", description: error.message });
    } finally {
      setIsGeneratingPDF(false);
    }
  };
  
  const getOwnerDisplayName = (owner) => {
    return owner.owner_name || `${owner.first_name || ''} ${owner.last_name || ''}`.trim();
  };

  const filteredOwners = owners.filter(o => {
    const name = getOwnerDisplayName(o).toLowerCase();
    const term = searchTerm.toLowerCase();
    return name.includes(term) || 
      (o.property_address || '').toLowerCase().includes(term) ||
      (o.units?.account_number || '').includes(searchTerm);
  });

  const previewOwner = owners.find(o => selectedOwnerIds.includes(o.id)) || owners[0];
  const selectedOwnersList = owners.filter(o => selectedOwnerIds.includes(o.id));

  // ─── Print Preview Mode ───
  if (showPrintPreview) {
    return (
      <div className="min-h-screen bg-muted flex flex-col items-center p-6">
        <div className="w-full max-w-[8.5in] flex justify-between items-center mb-6 bg-card p-4 rounded-lg shadow-sm sticky top-4 z-50 border">
          <div className="flex items-center gap-4">
            <Button variant="outline" onClick={() => setShowPrintPreview(false)} disabled={isGeneratingPDF}>
              <ArrowLeft className="w-4 h-4 mr-2" /> Back to Edit
            </Button>
            <div className="text-sm text-muted-foreground">
              Previewing coupons for <span className="font-bold text-foreground">{selectedOwnersList.length}</span> owners
            </div>
          </div>
          <Button 
            onClick={handleGeneratePDF} 
            disabled={isGeneratingPDF || selectedOwnersList.length === 0}
            className="min-w-[160px]"
          >
            {isGeneratingPDF ? (
              <><Loader2 className="w-4 h-4 mr-2 animate-spin" /> Generating PDF...</>
            ) : (
              <><Download className="w-4 h-4 mr-2" /> Download PDF</>
            )}
          </Button>
        </div>

        <div id="printable-coupons-container" className="w-full max-w-[8.5in] mb-20 flex flex-col items-center">
          <PaymentCouponHTMLPreview 
            selectedClientData={selectedAssociationData}
            selectedOwners={selectedOwnersList}
            couponData={couponData}
            associationAddress={associationAddress}
          />
        </div>
      </div>
    );
  }

  // ─── Edit Mode ───
  return (
    <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
      <div className="space-y-6">
        {/* Step 1: Association & Address */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">1. Association & Owners</CardTitle>
            <CardDescription>Select the association to begin.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label>Association</Label>
              <Select value={selectedAssociationId} onValueChange={setSelectedAssociationId}>
                <SelectTrigger><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="association-address">Association Return Address</Label>
              <Textarea 
                id="association-address"
                value={associationAddress}
                onChange={(e) => setAssociationAddress(e.target.value)}
                placeholder="Enter multi-line address for the association"
                className="min-h-[80px] font-mono"
              />
            </div>
            <div className="flex items-center gap-2">
              <Switch checked={useCompanyAsSender} onCheckedChange={(checked) => {
                setUseCompanyAsSender(checked);
                if (checked) {
                  setAssociationAddress(companySettings.company_address || '');
                } else {
                  const assoc = selectedAssociationData;
                  const addrParts = [];
                  if (assoc?.name) addrParts.push(assoc.name);
                  if (assoc?.care_of_address) addrParts.push(`C/O ${assoc.care_of_address}`);
                  if (assoc?.mailing_address) addrParts.push(assoc.mailing_address);
                  setAssociationAddress(addrParts.join('\n'));
                }
              }} />
              <Label className="text-xs text-muted-foreground">Send from company address instead of association</Label>
            </div>
          </CardContent>
        </Card>

        {/* Step 2: Coupon Config */}
        <div className="space-y-4">
          <div className="flex justify-between items-center">
            <h3 className="text-lg font-semibold text-foreground">2. Coupon Configuration</h3>
            <Button variant="outline" size="sm" onClick={copyFirstToOthers} className="text-xs h-8">
              <Copy className="w-3 h-3 mr-2" /> Copy #1 to All
            </Button>
          </div>

          {couponData.map((coupon, index) => (
            <Card key={coupon.id} className="relative overflow-hidden">
              <div className="absolute top-0 left-0 w-1 h-full bg-primary"></div>
              <CardHeader className="py-3 px-4 bg-muted/50 border-b">
                <CardTitle className="text-sm font-medium">Coupon #{index + 1}</CardTitle>
              </CardHeader>
              <CardContent className="p-4 grid gap-4">
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label className="text-xs">Payment Amount ($)</Label>
                    <Input type="number" value={coupon.amount} onChange={(e) => handleCouponChange(index, 'amount', e.target.value)} className="h-8 font-mono" placeholder="0.00" />
                  </div>
                  <div className="space-y-2">
                    <Label className="text-xs">Payment Number</Label>
                    <Input value={coupon.paymentNumber} onChange={(e) => handleCouponChange(index, 'paymentNumber', e.target.value)} className="h-8 font-mono" placeholder="e.g. 001" />
                  </div>
                </div>
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label className="text-xs">Due Date</Label>
                    <Input type="date" value={coupon.dueDate} onChange={(e) => handleCouponChange(index, 'dueDate', e.target.value)} className="h-8 font-mono" />
                  </div>
                  <div className="space-y-2">
                    <Label className="text-xs">Late Fees Begin</Label>
                    <Input type="date" value={coupon.lateFeeDate} onChange={(e) => handleCouponChange(index, 'lateFeeDate', e.target.value)} className="h-8 font-mono" />
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>

        {/* Preview Card */}
        <Card className="bg-muted/30">
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium uppercase text-muted-foreground">Preview (Coupon #1 Style)</CardTitle>
            <CardDescription>
              This is a visual preview. Click "Switch to Print Mode" to generate the final pages.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div className="overflow-x-auto pb-4">
              <PaymentCouponPreview 
                clientName={selectedAssociationData?.name}
                clientAddress={associationAddress} 
                owner={previewOwner}
                formData={couponData[0]}
              />
            </div>
          </CardContent>
        </Card>

        <Button 
          className="w-full" 
          size="lg"
          onClick={() => setShowPrintPreview(true)}
          disabled={selectedOwnerIds.length === 0}
        >
          <Eye className="w-4 h-4 mr-2" />
          Switch to Print Mode ({selectedOwnerIds.length} Owners)
        </Button>
      </div>

      {/* Step 3: Owner Selection */}
      <div className="h-full">
        <Card className="h-full flex flex-col min-h-[500px]">
          <CardHeader className="pb-3 border-b">
            <div className="flex flex-col gap-4">
              <div className="flex justify-between items-start">
                <div>
                  <CardTitle className="text-lg">3. Select Owners</CardTitle>
                  <CardDescription>
                    {selectedAssociationId 
                      ? `${filteredOwners.length} owners found. ${selectedOwnerIds.length} selected.` 
                      : "Select an association first."}
                  </CardDescription>
                </div>
                {filteredOwners.length > 0 && (
                  <Button variant="outline" size="sm" onClick={handleSelectAll}>
                    Select All Shown
                  </Button>
                )}
              </div>
              <div className="relative">
                <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
                <Input 
                  placeholder="Search owners..." 
                  className="pl-9"
                  value={searchTerm}
                  onChange={e => setSearchTerm(e.target.value)}
                />
              </div>
            </div>
          </CardHeader>
          <CardContent className="flex-1 p-0 overflow-hidden relative">
            {isLoadingOwners ? (
              <div className="flex justify-center items-center h-40 absolute inset-0">
                <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
              </div>
            ) : filteredOwners.length > 0 ? (
              <ScrollArea className="h-[600px] xl:h-[calc(100vh-100px)]">
                <div className="p-4 space-y-1">
                  {filteredOwners.map(owner => (
                    <div 
                      key={owner.id} 
                      className={`flex items-start space-x-3 p-3 rounded-lg border cursor-pointer transition-colors ${selectedOwnerIds.includes(owner.id) ? 'bg-primary/5 border-primary/30' : 'hover:bg-accent border-border'}`}
                      onClick={() => handleOwnerToggle(owner.id)}
                    >
                      <Checkbox 
                        id={`owner-${owner.id}`} 
                        checked={selectedOwnerIds.includes(owner.id)} 
                        onCheckedChange={() => handleOwnerToggle(owner.id)}
                      />
                      <div className="grid gap-1.5 leading-none w-full">
                        <label 
                          htmlFor={`owner-${owner.id}`} 
                          className="text-sm font-medium leading-none cursor-pointer"
                        >
                          {getOwnerDisplayName(owner)}
                        </label>
                        <p className="text-xs text-muted-foreground">
                          {owner.property_address}
                        </p>
                        {owner.account_number && (
                          <p className="text-[10px] font-mono text-muted-foreground/70">Acct: {owner.account_number}</p>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </ScrollArea>
            ) : (
              <div className="flex flex-col items-center justify-center h-full min-h-[200px] text-muted-foreground">
                <User className="w-8 h-8 mb-2 opacity-50" />
                <p>No owners found</p>
              </div>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
