import { useState, useEffect, useMemo } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useToast } from "@/hooks/use-toast";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { CalendarClock, DollarSign, Percent, Search, Save, RefreshCw } from "lucide-react";
import AccountDropdown from "@/components/AccountDropdown";
import { useCentralChartOfAccounts } from "@/hooks/useCentralChartOfAccounts";

interface FeeRules {
  id?: string;
  association_id: string;
  default_assessment_amount: number;
  assessment_day: number;
  assessment_frequency: string;
  late_fee_enabled: boolean;
  late_fee_amount: number;
  late_fee_type: string;
  late_fee_trigger_days: number;
  late_fee_recurring: boolean;
  late_fee_max: number | null;
  interest_enabled: boolean;
  interest_rate: number;
  interest_compound: string;
  interest_grace_days: number;
  interest_apply_to: string;
  auto_apply_enabled: boolean;
  auto_apply_day: number;
  auto_apply_schedule: string;
  billing_start_date: string | null;
  auto_post_enabled: boolean;
  next_run_date: string | null;
  last_run_date: string | null;
}

const DEFAULT_RULES: Omit<FeeRules, "association_id"> = {
  default_assessment_amount: 0,
  assessment_day: 1,
  assessment_frequency: "monthly",
  late_fee_enabled: false,
  late_fee_amount: 25,
  late_fee_type: "flat",
  late_fee_trigger_days: 15,
  late_fee_recurring: false,
  late_fee_max: null,
  interest_enabled: false,
  interest_rate: 18,
  interest_compound: "monthly",
  interest_grace_days: 30,
  interest_apply_to: "total_balance",
  auto_apply_enabled: false,
  auto_apply_day: 1,
  auto_apply_schedule: "monthly",
  billing_start_date: null,
  auto_post_enabled: false,
  next_run_date: null,
  last_run_date: null,
};

interface UnitRow {
  id: string;
  unit_number: string;
  address: string | null;
  monthly_assessment: number | null;
  assessment_amount_one: number | null;
  assessment_account_id: string | null;
}

interface OwnerRow {
  id: string;
  first_name: string | null;
  last_name: string | null;
  unit_id: string | null;
}

export default function RecurringRulesPage() {
  const { toast } = useToast();
  const { user } = useAuth();
  const [associations, setAssociations] = useState<{ id: string; name: string }[]>([]);
  const [selectedAssociation, setSelectedAssociation] = useState<string>("");
  const [rules, setRules] = useState<FeeRules | null>(null);
  const [units, setUnits] = useState<UnitRow[]>([]);
  const [owners, setOwners] = useState<OwnerRow[]>([]);
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);
  const [unitSearch, setUnitSearch] = useState("");
  const [selectedUnitIds, setSelectedUnitIds] = useState<Set<string>>(new Set());
  const [postingAssessments, setPostingAssessments] = useState(false);

  const { accounts: coaAccounts } = useCentralChartOfAccounts(selectedAssociation || null);

  useEffect(() => {
    supabase.from("associations").select("id, name").eq("status", "active").order("name")
      .then(({ data }) => {
        setAssociations(data || []);
        if (data?.length) setSelectedAssociation(data[0].id);
        setLoading(false);
      });
  }, []);

  useEffect(() => {
    if (!selectedAssociation) return;
    loadData();
  }, [selectedAssociation]);

  const loadData = async () => {
    setLoading(true);
    const [rulesRes, unitsRes, ownersRes] = await Promise.all([
      supabase.from("association_fee_rules").select("*").eq("association_id", selectedAssociation).maybeSingle(),
      supabase.from("units").select("id, unit_number, address, monthly_assessment, assessment_amount_one, assessment_account_id").eq("association_id", selectedAssociation).order("unit_number") as any,
      supabase.from("owners").select("id, first_name, last_name, unit_id").eq("association_id", selectedAssociation).eq("status", "active").order("last_name") as any,
    ]);

    if (rulesRes.data) {
      setRules(rulesRes.data as any);
    } else {
      setRules({ ...DEFAULT_RULES, association_id: selectedAssociation });
    }
    setUnits((unitsRes.data || []) as UnitRow[]);
    setOwners((ownersRes.data || []) as OwnerRow[]);
    setLoading(false);
  };

  const handleSaveRules = async () => {
    if (!rules) return;
    setSaving(true);
    const payload = { ...rules, association_id: selectedAssociation };

    const { error } = rules.id
      ? await supabase.from("association_fee_rules").update(payload as any).eq("id", rules.id)
      : await supabase.from("association_fee_rules").insert(payload as any);

    setSaving(false);
    if (error) {
      toast({ variant: "destructive", title: "Error saving rules", description: error.message });
    } else {
      toast({ title: "Rules saved" });
      loadData();
    }
  };

  const handleUnitAssessmentChange = async (unitId: string, value: string) => {
    const num = value === "" ? null : parseFloat(value);
    const { error } = await supabase.from("units").update({ monthly_assessment: num, assessment_amount_one: num } as any).eq("id", unitId);
    if (error) {
      toast({ variant: "destructive", title: "Error", description: error.message });
    } else {
      setUnits((prev) => prev.map((u) => (u.id === unitId ? { ...u, monthly_assessment: num, assessment_amount_one: num } : u)));
    }
  };

  const handleUnitAssessmentAmountChange = async (unitId: string, value: string) => {
    const num = value === "" ? null : parseFloat(value);
    const payload = { assessment_amount_one: num, monthly_assessment: num };
    const { error } = await supabase.from("units").update(payload as any).eq("id", unitId);
    if (error) {
      toast({ variant: "destructive", title: "Error", description: error.message });
    } else {
      setUnits((prev) => prev.map((u) => (u.id === unitId ? { ...u, ...payload } : u)));
    }
  };

  const handleUnitAssessmentAccountChange = async (unitId: string, accountId: string | null) => {
    const { error } = await supabase
      .from("units")
      .update({ assessment_account_id: accountId } as any)
      .eq("id", unitId);
    if (error) {
      toast({ variant: "destructive", title: "Error", description: error.message });
    } else {
      setUnits((prev) => prev.map((u) => (u.id === unitId ? { ...u, assessment_account_id: accountId } : u)));
    }
  };

  const filteredUnits = useMemo(() => {
    if (!unitSearch) return units;
    const q = unitSearch.toLowerCase();
    return units.filter((u) => u.unit_number.toLowerCase().includes(q) || u.address?.toLowerCase().includes(q));
  }, [units, unitSearch]);

  const updateRule = (field: string, value: any) => {
    if (!rules) return;
    setRules({ ...rules, [field]: value });
  };

  const toggleUnitSelection = (unitId: string) => {
    setSelectedUnitIds((prev) => {
      const next = new Set(prev);
      next.has(unitId) ? next.delete(unitId) : next.add(unitId);
      return next;
    });
  };

  const postSelectedAssessments = async () => {
    const selectedUnits = units.filter((unit) => selectedUnitIds.has(unit.id));
    if (!selectedUnits.length) {
      toast({ variant: "destructive", title: "Select at least one unit" });
      return;
    }

    const date = new Date().toISOString().split("T")[0];
    const accountById = new Map(coaAccounts.map((a) => [a.id, a]));
    const entries = selectedUnits.flatMap((unit) => {
      const owner = owners.find((o) => o.unit_id === unit.id);
      if (!owner) return [];
      const amount = unit.assessment_amount_one ?? unit.monthly_assessment ?? rules?.default_assessment_amount ?? 0;
      if (!amount || amount <= 0) return [];
      const acct = unit.assessment_account_id ? accountById.get(unit.assessment_account_id) : null;
      const description = acct
        ? `${acct.account_number ? acct.account_number + " - " : ""}${acct.account_name}`
        : "Assessment";
      return [{
        association_id: selectedAssociation,
        owner_id: owner.id,
        unit_id: unit.id,
        date,
        credit: 0,
        debit: amount,
        transaction_type: "assessment",
        description,
        created_by: user?.id || null,
      }];
    });

    if (!entries.length) {
      toast({ variant: "destructive", title: "No assessment amounts found" });
      return;
    }

    setPostingAssessments(true);
    const { error } = await supabase.from("owner_ledger_entries").insert(entries as any[]);
    setPostingAssessments(false);

    if (error) {
      toast({ variant: "destructive", title: "Error posting assessments", description: error.message });
    } else {
      toast({ title: "Assessments posted", description: `Posted ${entries.length} assessment line(s).` });
      setSelectedUnitIds(new Set());
    }
  };

  if (loading && !selectedAssociation) {
    return (
      <div className="flex min-h-[40vh] items-center justify-center">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold flex items-center gap-2">
          <CalendarClock className="h-6 w-6 text-primary" />
          Recurring Rules
        </h1>
        <p className="text-sm text-muted-foreground mt-1">Configure automatic assessments, late fees, and interest charges</p>
      </div>

      {/* Association selector */}
      <div className="max-w-xs">
        <Label>Association</Label>
        <Select value={selectedAssociation} onValueChange={setSelectedAssociation}>
          <SelectTrigger>
            <SelectValue placeholder="Select association" />
          </SelectTrigger>
          <SelectContent>
            {associations.map((a) => (
              <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {loading ? (
        <div className="flex justify-center py-12">
          <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
        </div>
      ) : rules ? (
        <Tabs defaultValue="assessments" className="space-y-4">
          <TabsList>
            <TabsTrigger value="assessments" className="gap-2"><DollarSign className="h-4 w-4" /> Assessments</TabsTrigger>
            <TabsTrigger value="late-fees" className="gap-2"><CalendarClock className="h-4 w-4" /> Late Fees</TabsTrigger>
            <TabsTrigger value="interest" className="gap-2"><Percent className="h-4 w-4" /> Interest</TabsTrigger>
          </TabsList>

          {/* ─── ASSESSMENTS TAB ─── */}
          <TabsContent value="assessments" className="space-y-6">
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">Association Defaults</CardTitle>
                <CardDescription>Set the default assessment amount and schedule for all units in this association</CardDescription>
              </CardHeader>
              <CardContent className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                <div>
                  <Label>Default Amount ($)</Label>
                  <Input
                    type="number"
                    min={0}
                    step="0.01"
                    value={rules.default_assessment_amount || ""}
                    onChange={(e) => updateRule("default_assessment_amount", parseFloat(e.target.value) || 0)}
                  />
                </div>
                <div>
                  <Label>Day of Month</Label>
                  <Input
                    type="number"
                    min={1}
                    max={28}
                    value={rules.assessment_day}
                    onChange={(e) => updateRule("assessment_day", parseInt(e.target.value) || 1)}
                  />
                </div>
                <div>
                  <Label>Frequency</Label>
                  <Select value={rules.assessment_frequency} onValueChange={(v) => updateRule("assessment_frequency", v)}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="monthly">Monthly</SelectItem>
                      <SelectItem value="quarterly">Quarterly</SelectItem>
                      <SelectItem value="semi-annual">Semi-Annual</SelectItem>
                      <SelectItem value="annual">Annual</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </CardContent>
            </Card>

            {/* Billing Cycle */}
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">Billing Cycle</CardTitle>
                <CardDescription>
                  Define when assessments begin and let the system automatically post each cycle. The next run date advances by the selected frequency after each posting.
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                  <div>
                    <Label>Billing Start Date</Label>
                    <Input
                      type="date"
                      value={rules.billing_start_date || ""}
                      onChange={(e) => {
                        const start = e.target.value || null;
                        updateRule("billing_start_date", start);
                        if (start && !rules.next_run_date) updateRule("next_run_date", start);
                      }}
                    />
                  </div>
                  <div>
                    <Label>Next Run Date</Label>
                    <Input
                      type="date"
                      value={rules.next_run_date || ""}
                      onChange={(e) => updateRule("next_run_date", e.target.value || null)}
                    />
                  </div>
                  <div>
                    <Label>Last Posted</Label>
                    <Input type="date" value={rules.last_run_date || ""} disabled />
                  </div>
                </div>
                <div className="flex items-center justify-between rounded-md border p-3">
                  <div>
                    <Label className="text-sm">Auto-post assessments</Label>
                    <p className="text-xs text-muted-foreground mt-1">
                      When enabled, the system posts assessments to all units on the next run date, then advances by the selected frequency ({rules.assessment_frequency}).
                    </p>
                  </div>
                  <Switch
                    checked={rules.auto_post_enabled}
                    onCheckedChange={(v) => updateRule("auto_post_enabled", v)}
                  />
                </div>
              </CardContent>
            </Card>

            {/* Per-unit overrides */}
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">Unit-Level Assessment Amounts</CardTitle>
                <CardDescription>
                  For each unit, choose a Chart of Accounts entry and the assessment amount. Falls back to the association default (${rules.default_assessment_amount?.toFixed(2) || "0.00"}) if no amount is set.
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-3">
                <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                  <div className="relative max-w-xs flex-1">
                    <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                    <Input className="pl-9" placeholder="Search units…" value={unitSearch} onChange={(e) => setUnitSearch(e.target.value)} />
                  </div>
                  <Button onClick={postSelectedAssessments} disabled={postingAssessments || selectedUnitIds.size === 0} className="gap-2">
                    <DollarSign className="h-4 w-4" /> {postingAssessments ? "Posting…" : `Post Selected (${selectedUnitIds.size})`}
                  </Button>
                </div>
                <div className="rounded-md border max-h-[400px] overflow-auto">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead className="w-12"></TableHead>
                        <TableHead>Unit</TableHead>
                        <TableHead>Address</TableHead>
                        <TableHead className="min-w-[260px]">Account</TableHead>
                        <TableHead className="w-44">Amount</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {filteredUnits.map((u) => (
                        <TableRow key={u.id}>
                          <TableCell>
                            <Checkbox checked={selectedUnitIds.has(u.id)} onCheckedChange={() => toggleUnitSelection(u.id)} />
                          </TableCell>
                          <TableCell className="font-medium">{u.unit_number}</TableCell>
                          <TableCell className="text-muted-foreground text-sm">{u.address || "—"}</TableCell>
                          <TableCell>
                            <AccountDropdown
                              associationId={selectedAssociation}
                              value={u.assessment_account_id || undefined}
                              onChange={(v) => handleUnitAssessmentAccountChange(u.id, v || null)}
                              placeholder="Select account..."
                              className="h-8"
                            />
                          </TableCell>
                          <TableCell>
                            <Input
                              type="number"
                              min={0}
                              step="0.01"
                              placeholder={rules.default_assessment_amount?.toString() || "0"}
                              value={u.assessment_amount_one ?? u.monthly_assessment ?? ""}
                              onChange={(e) => handleUnitAssessmentAmountChange(u.id, e.target.value)}
                              className="h-8 w-36"
                            />
                          </TableCell>
                        </TableRow>
                      ))}
                      {filteredUnits.length === 0 && (
                        <TableRow><TableCell colSpan={5} className="text-center text-muted-foreground py-8">No units found</TableCell></TableRow>
                      )}
                    </TableBody>
                  </Table>
                </div>
              </CardContent>
            </Card>

            <div className="flex justify-end">
              <Button onClick={handleSaveRules} disabled={saving} className="gap-2">
                <Save className="h-4 w-4" /> {saving ? "Saving…" : "Save Assessment Rules"}
              </Button>
            </div>
          </TabsContent>

          {/* ─── LATE FEES TAB ─── */}
          <TabsContent value="late-fees" className="space-y-6">
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">Late Fee Configuration</CardTitle>
                <CardDescription>Define how and when late fees are applied to delinquent accounts</CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="flex items-center justify-between">
                  <Label>Enable Late Fees</Label>
                  <Switch checked={rules.late_fee_enabled} onCheckedChange={(v) => updateRule("late_fee_enabled", v)} />
                </div>

                {rules.late_fee_enabled && (
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-2">
                    <div>
                      <Label>Fee Type</Label>
                      <Select value={rules.late_fee_type} onValueChange={(v) => updateRule("late_fee_type", v)}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="flat">Flat Amount</SelectItem>
                          <SelectItem value="percentage">Percentage of Balance</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                    <div>
                      <Label>{rules.late_fee_type === "flat" ? "Amount ($)" : "Percentage (%)"}</Label>
                      <Input
                        type="number"
                        min={0}
                        step={rules.late_fee_type === "flat" ? "0.01" : "0.1"}
                        value={rules.late_fee_amount}
                        onChange={(e) => updateRule("late_fee_amount", parseFloat(e.target.value) || 0)}
                      />
                    </div>
                    <div>
                      <Label>Trigger After (Days Past Due)</Label>
                      <Input
                        type="number"
                        min={1}
                        value={rules.late_fee_trigger_days}
                        onChange={(e) => updateRule("late_fee_trigger_days", parseInt(e.target.value) || 15)}
                      />
                    </div>
                    <div>
                      <Label>Maximum Late Fee ($)</Label>
                      <Input
                        type="number"
                        min={0}
                        step="0.01"
                        placeholder="No max"
                        value={rules.late_fee_max ?? ""}
                        onChange={(e) => updateRule("late_fee_max", e.target.value ? parseFloat(e.target.value) : null)}
                      />
                    </div>
                    <div className="flex items-center gap-3 sm:col-span-2">
                      <Switch checked={rules.late_fee_recurring} onCheckedChange={(v) => updateRule("late_fee_recurring", v)} />
                      <Label>Apply recurring late fees each billing cycle</Label>
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>

            <div className="flex justify-end">
              <Button onClick={handleSaveRules} disabled={saving} className="gap-2">
                <Save className="h-4 w-4" /> {saving ? "Saving…" : "Save Late Fee Rules"}
              </Button>
            </div>
          </TabsContent>

          {/* ─── INTEREST TAB ─── */}
          <TabsContent value="interest" className="space-y-6">
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">Interest Configuration</CardTitle>
                <CardDescription>Define the interest rate and calculation method</CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="flex items-center justify-between">
                  <Label>Enable Interest</Label>
                  <Switch checked={rules.interest_enabled} onCheckedChange={(v) => updateRule("interest_enabled", v)} />
                </div>

                {rules.interest_enabled && (
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-2">
                    <div>
                      <Label>Annual Interest Rate (%)</Label>
                      <Input
                        type="number"
                        min={0}
                        step="0.1"
                        value={rules.interest_rate}
                        onChange={(e) => updateRule("interest_rate", parseFloat(e.target.value) || 0)}
                      />
                    </div>
                    <div>
                      <Label>Compounding</Label>
                      <Select value={rules.interest_compound} onValueChange={(v) => updateRule("interest_compound", v)}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="monthly">Monthly</SelectItem>
                          <SelectItem value="daily">Daily</SelectItem>
                          <SelectItem value="simple">Simple (no compounding)</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                    <div>
                      <Label>Grace Period (Days)</Label>
                      <Input
                        type="number"
                        min={0}
                        value={rules.interest_grace_days}
                        onChange={(e) => updateRule("interest_grace_days", parseInt(e.target.value) || 0)}
                      />
                    </div>
                    <div>
                      <Label>Apply Interest To</Label>
                      <Select value={rules.interest_apply_to} onValueChange={(v) => updateRule("interest_apply_to", v)}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="total_balance">Total Outstanding Balance</SelectItem>
                          <SelectItem value="assessments_only">Assessments Only</SelectItem>
                          <SelectItem value="assessments_and_late">Assessments + Late Fees</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>

            <div className="flex justify-end">
              <Button onClick={handleSaveRules} disabled={saving} className="gap-2">
                <Save className="h-4 w-4" /> {saving ? "Saving…" : "Save Interest Rules"}
              </Button>
            </div>
          </TabsContent>
        </Tabs>
      ) : null}
    </div>
  );
}
