import { useEffect, useMemo, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { boardFunctionItems, homeownerFunctionItems } from "@/lib/portalVisibilityConfig";
import { useToast } from "@/hooks/use-toast";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Loader2, Save, ShieldCheck } from "lucide-react";

type Association = {
  id: string;
  name: string;
};

type Rule = {
  id?: string;
  portal: "board" | "homeowner" | "rv_boat_lot";
  function_key: string;
  enabled: boolean;
  owner_user_id: string | null;
  association_id: string | null;
};

type OwnerOption = {
  user_id: string;
  first_name: string | null;
  last_name: string | null;
  email: string | null;
  association_id: string;
  unit_number?: string | null;
};

const boardItems = boardFunctionItems.map(({ key, title }) => ({ key, title }));
const homeownerItems = homeownerFunctionItems.map(({ key, title }) => ({ key, title }));

export default function PortalFunctionVisibilityPage() {
  const { toast } = useToast();
  const [rules, setRules] = useState<Rule[]>([]);
  const [associations, setAssociations] = useState<Association[]>([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState<string>("");
  const [owners, setOwners] = useState<OwnerOption[]>([]);
  const [selectedOwnerId, setSelectedOwnerId] = useState<string>("");
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  const loadData = async () => {
    setLoading(true);
    const [rulesRes, ownersRes, associationsRes] = await Promise.all([
      supabase.from("portal_function_visibility").select("id,portal,function_key,enabled,owner_user_id,association_id").in("portal", ["board", "homeowner", "rv_boat_lot"]),
      supabase
        .from("owners")
        .select("user_id,first_name,last_name,email,association_id,units(unit_number)")
        .not("user_id", "is", null)
        .eq("status", "active")
        .order("last_name"),
      supabase.from("associations").select("id,name").eq("status", "active").order("name"),
    ]);

    if (rulesRes.error) {
      toast({ variant: "destructive", title: "Error loading settings", description: rulesRes.error.message });
    } else {
      setRules((rulesRes.data as Rule[]) || []);
    }

    if (!associationsRes.error) {
      const associationList = (associationsRes.data as Association[]) || [];
      setAssociations(associationList);
      if (!selectedAssociationId && associationList[0]) setSelectedAssociationId(associationList[0].id);
    }

    if (!ownersRes.error) {
      const ownerMap = new Map<string, OwnerOption>();
      ((ownersRes.data as any[]) || []).forEach((owner) => {
        const key = `${owner.association_id}:${owner.user_id}`;
        if (!owner.user_id || ownerMap.has(key)) return;
        ownerMap.set(key, {
          user_id: owner.user_id,
          first_name: owner.first_name,
          last_name: owner.last_name,
          email: owner.email,
          association_id: owner.association_id,
          unit_number: owner.units?.unit_number,
        });
      });
      const list = Array.from(ownerMap.values());
      setOwners(list);
      if (!selectedOwnerId && list[0]) setSelectedOwnerId(list[0].user_id);
    }

    setLoading(false);
  };

  useEffect(() => {
    void loadData();
  }, []);

  useEffect(() => {
    const firstOwner = owners.find((owner) => owner.association_id === selectedAssociationId);
    if (!firstOwner) {
      setSelectedOwnerId("");
      return;
    }
    const currentOwnerStillInAssociation = owners.some((owner) => owner.association_id === selectedAssociationId && owner.user_id === selectedOwnerId);
    if (!currentOwnerStillInAssociation) setSelectedOwnerId(firstOwner.user_id);
  }, [owners, selectedAssociationId, selectedOwnerId]);

  const filteredOwners = useMemo(() => {
    const q = search.trim().toLowerCase();
    const scopedOwners = owners.filter((owner) => owner.association_id === selectedAssociationId);
    if (!q) return scopedOwners;
    return scopedOwners.filter((owner) => `${owner.first_name || ""} ${owner.last_name || ""} ${owner.email || ""} ${owner.unit_number || ""}`.toLowerCase().includes(q));
  }, [owners, search, selectedAssociationId]);

  const isEnabled = (portal: "board" | "homeowner" | "rv_boat_lot", key: string, ownerUserId: string | null = null) => {
    const scoped = rules.find((rule) => rule.portal === portal && rule.function_key === key && rule.owner_user_id === ownerUserId && rule.association_id === selectedAssociationId);
    if (scoped) return scoped.enabled;
    const global = rules.find((rule) => rule.portal === portal && rule.function_key === key && rule.owner_user_id === ownerUserId && !rule.association_id);
    if (global) return global.enabled;
    if (ownerUserId) return isEnabled(portal, key, null);
    return true;
  };

  const setEnabled = (portal: "board" | "homeowner" | "rv_boat_lot", key: string, enabled: boolean, ownerUserId: string | null = null) => {
    setRules((prev) => {
      const existing = prev.find((rule) => rule.portal === portal && rule.function_key === key && rule.owner_user_id === ownerUserId && rule.association_id === selectedAssociationId);
      if (existing) {
        return prev.map((rule) => rule === existing ? { ...rule, enabled } : rule);
      }
      return [...prev, { portal, function_key: key, enabled, owner_user_id: ownerUserId, association_id: selectedAssociationId }];
    });
  };

  const saveRule = async (rule: Rule) => {
    let query = supabase
      .from("portal_function_visibility")
      .delete()
      .eq("portal", rule.portal)
      .eq("function_key", rule.function_key);

    query = rule.owner_user_id ? query.eq("owner_user_id", rule.owner_user_id) : query.is("owner_user_id", null);
    query = rule.association_id ? query.eq("association_id", rule.association_id) : query.is("association_id", null);
    const { error: deleteError } = await query;
    if (deleteError) throw deleteError;

    const { error: insertError } = await supabase.from("portal_function_visibility").insert({
      portal: rule.portal,
      function_key: rule.function_key,
      enabled: rule.enabled,
      owner_user_id: rule.owner_user_id,
      association_id: rule.association_id,
    });
    if (insertError) throw insertError;
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      const allowedKeys = new Set([
        ...boardItems.map((item) => `board:${item.key}:${selectedAssociationId}:global`),
        ...homeownerItems.map((item) => `homeowner:${item.key}:${selectedAssociationId}:global`),
        ...homeownerItems.map((item) => `rv_boat_lot:${item.key}:${selectedAssociationId}:global`),
        ...homeownerItems.map((item) => selectedOwnerId ? `homeowner:${item.key}:${selectedAssociationId}:${selectedOwnerId}` : ""),
      ]);

      const pending = rules.filter((rule) => allowedKeys.has(`${rule.portal}:${rule.function_key}:${rule.association_id || "global"}:${rule.owner_user_id || "global"}`));
      for (const rule of pending) await saveRule(rule);
      toast({ title: "Visibility settings saved" });
      await loadData();
    } catch (err: any) {
      toast({ variant: "destructive", title: "Unable to save settings", description: err.message });
    } finally {
      setSaving(false);
    }
  };

  const selectedOwner = owners.find((owner) => owner.user_id === selectedOwnerId && owner.association_id === selectedAssociationId);

  if (loading) {
    return <div className="flex justify-center py-16"><Loader2 className="h-8 w-8 animate-spin text-primary" /></div>;
  }

  return (
    <div className="space-y-6">
      <div className="flex items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2 text-foreground">
            <ShieldCheck className="h-6 w-6 text-primary" /> Portal Visibility
          </h1>
          <p className="text-sm text-muted-foreground mt-1">Choose which portal functions board members, homeowners, and RV/Boat Lot users can see.</p>
        </div>
        <Button onClick={handleSave} disabled={saving || !selectedAssociationId} className="gap-2">
          {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
          Save Changes
        </Button>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Association / Client</CardTitle>
          <CardDescription>Visibility rules below apply only to the selected association/client.</CardDescription>
        </CardHeader>
        <CardContent>
          <Select value={selectedAssociationId} onValueChange={setSelectedAssociationId}>
            <SelectTrigger className="w-full md:w-[360px]"><SelectValue placeholder="Select association/client" /></SelectTrigger>
            <SelectContent>
              {associations.map((association) => (
                <SelectItem key={association.id} value={association.id}>{association.name}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </CardContent>
      </Card>

      <Tabs defaultValue="board">
        <TabsList>
          <TabsTrigger value="board">Board Members</TabsTrigger>
          <TabsTrigger value="homeowners">Homeowners</TabsTrigger>
          <TabsTrigger value="rv_boat_lot">RV/Boat Lot</TabsTrigger>
        </TabsList>

        <TabsContent value="board" className="mt-4">
          <Card>
            <CardHeader>
              <CardTitle>Board Member Functions</CardTitle>
              <CardDescription>These defaults apply to board members for the selected association/client.</CardDescription>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow><TableHead>Function</TableHead><TableHead className="w-24 text-center">Visible</TableHead></TableRow>
                </TableHeader>
                <TableBody>
                  {boardItems.map((item) => (
                    <TableRow key={item.key}>
                      <TableCell className="font-medium">{item.title}</TableCell>
                      <TableCell className="text-center">
                        <Checkbox checked={isEnabled("board", item.key)} onCheckedChange={(checked) => setEnabled("board", item.key, checked === true)} />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="homeowners" className="mt-4 space-y-4">
          <Card>
            <CardHeader>
              <CardTitle>Homeowner Default Functions</CardTitle>
              <CardDescription>These defaults apply to homeowners in the selected association/client unless an individual override is set below.</CardDescription>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow><TableHead>Function</TableHead><TableHead className="w-24 text-center">Visible</TableHead></TableRow>
                </TableHeader>
                <TableBody>
                  {homeownerItems.map((item) => (
                    <TableRow key={item.key}>
                      <TableCell className="font-medium">{item.title}</TableCell>
                      <TableCell className="text-center">
                        <Checkbox checked={isEnabled("homeowner", item.key)} onCheckedChange={(checked) => setEnabled("homeowner", item.key, checked === true)} />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Individual Homeowner Overrides</CardTitle>
              <CardDescription>Pick a homeowner and customize what only that homeowner sees.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="grid gap-3 md:grid-cols-[1fr_2fr]">
                <div className="space-y-2">
                  <Label>Search homeowners</Label>
                  <Input value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Name, email, or unit" />
                </div>
                <div className="space-y-2">
                  <Label>Homeowner</Label>
                  <Select value={selectedOwnerId} onValueChange={setSelectedOwnerId}>
                    <SelectTrigger><SelectValue placeholder="Select homeowner" /></SelectTrigger>
                    <SelectContent>
                      {filteredOwners.map((owner) => (
                        <SelectItem key={`${owner.association_id}:${owner.user_id}`} value={owner.user_id}>
                          {[owner.last_name, owner.first_name].filter(Boolean).join(", ") || owner.email} {owner.unit_number ? `• Unit ${owner.unit_number}` : ""}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {selectedOwner ? (
                <Table>
                  <TableHeader>
                    <TableRow><TableHead>Function</TableHead><TableHead className="w-24 text-center">Visible</TableHead></TableRow>
                  </TableHeader>
                  <TableBody>
                    {homeownerItems.map((item) => (
                      <TableRow key={item.key}>
                        <TableCell className="font-medium">{item.title}</TableCell>
                        <TableCell className="text-center">
                          <Checkbox checked={isEnabled("homeowner", item.key, selectedOwner.user_id)} onCheckedChange={(checked) => setEnabled("homeowner", item.key, checked === true, selectedOwner.user_id)} />
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              ) : (
                <div className="rounded-md border border-dashed border-border p-6 text-sm text-muted-foreground">No linked homeowner accounts found.</div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="rv_boat_lot" className="mt-4">
          <Card>
            <CardHeader>
              <CardTitle>RV/Boat Lot Default Functions</CardTitle>
              <CardDescription>These defaults apply to RV/Boat Lot users in the selected association/client.</CardDescription>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow><TableHead>Function</TableHead><TableHead className="w-24 text-center">Visible</TableHead></TableRow>
                </TableHeader>
                <TableBody>
                  {homeownerItems.map((item) => (
                    <TableRow key={item.key}>
                      <TableCell className="font-medium">{item.title}</TableCell>
                      <TableCell className="text-center">
                        <Checkbox checked={isEnabled("rv_boat_lot", item.key)} onCheckedChange={(checked) => setEnabled("rv_boat_lot", item.key, checked === true)} />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
}
