import React, { createContext, useContext, useEffect, useState, useCallback } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import type { Tables } from "@/integrations/supabase/types";

type Owner = Tables<"owners">;

interface AssociationInfo {
  id: string;
  name: string;
  phone: string | null;
  email: string | null;
  address: string | null;
  website?: string | null;
}

interface UnitInfo {
  id: string;
  unit_number: string | null;
  address: string | null;
  account_number: string | null;
}

interface HomeownerContextType {
  /** All owner records linked to this user */
  ownerRecords: Owner[];
  /** Map of association id -> name for owner records */
  associationNames: Record<string, string>;
  /** The currently selected owner record */
  currentOwner: Owner | null;
  /** Association info for the current owner */
  association: AssociationInfo | null;
  /** Unit info for the current owner */
  unit: UnitInfo | null;
  /** Switch to a different owner record (for users with multiple properties) */
  selectOwner: (ownerId: string) => void;
  loading: boolean;
}

const HomeownerContext = createContext<HomeownerContextType>({
  ownerRecords: [],
  associationNames: {},
  currentOwner: null,
  association: null,
  unit: null,
  selectOwner: () => {},
  loading: true,
});

export function HomeownerProvider({ children }: { children: React.ReactNode }) {
  const { user, isViewingAs, viewAsRole, realIsAdmin } = useAuth();
  const [ownerRecords, setOwnerRecords] = useState<Owner[]>([]);
  const [currentOwner, setCurrentOwner] = useState<Owner | null>(null);
  const [association, setAssociation] = useState<AssociationInfo | null>(null);
  const [unit, setUnit] = useState<UnitInfo | null>(null);
  const [associationNames, setAssociationNames] = useState<Record<string, string>>({});
  const [loading, setLoading] = useState(true);

  // Fetch all owner records for this user
  useEffect(() => {
    if (!user) {
      setOwnerRecords([]);
      setCurrentOwner(null);
      setAssociation(null);
      setUnit(null);
      setLoading(false);
      return;
    }

    const fetchOwners = async () => {
      setLoading(true);
      // Admin View-As: pull a sample (dummy) owner record so the admin can preview
      // the homeowner experience without needing their own owner row.
      const useDummy = realIsAdmin && isViewingAs && (
        viewAsRole === "homeowner" ||
        viewAsRole === "board_member" ||
        viewAsRole === "association_management"
      );
      const baseQuery = supabase
        .from("owners")
        .select("*")
        .neq("status", "archived");
      const { data, error } = useDummy
        ? await baseQuery.eq("status", "active").order("created_at", { ascending: false }).limit(1)
        : await baseQuery.eq("user_id", user.id);

      if (error) {
        console.error("Error fetching owner records:", error);
        setLoading(false);
        return;
      }

      // Deduplicate by id, then by unit_id so multiple owner rows on the
      // same unit do not produce duplicate switcher entries.
      const byId = Array.from(
        new Map((data || []).map((o) => [o.id, o])).values()
      );
      const seenUnits = new Set<string>();
      const owners = byId.filter((o) => {
        const key = o.unit_id || o.id;
        if (seenUnits.has(key)) return false;
        seenUnits.add(key);
        return true;
      });
      setOwnerRecords(owners);

      // Fetch association names for the dropdown labels
      const assocIds = Array.from(new Set(owners.map((o) => o.association_id).filter(Boolean)));
      if (assocIds.length > 0) {
        const { data: assocs } = await supabase
          .from("associations")
          .select("id, name")
          .in("id", assocIds);
        const map: Record<string, string> = {};
        (assocs || []).forEach((a: any) => { map[a.id] = a.name; });
        setAssociationNames(map);
      } else {
        setAssociationNames({});
      }

      // Look up user's designated primary owner from profile
      const { data: profileData } = await supabase
        .from("profiles")
        .select("primary_owner_id, primary_association_id")
        .eq("user_id", user.id)
        .maybeSingle();

      // Restore previous selection, fall back to profile primary, then first owner
      const savedOwnerId = localStorage.getItem("homeowner_selected_owner");
      const savedOwner = owners.find((o) => o.id === savedOwnerId);
      const primaryOwner = profileData?.primary_owner_id
        ? owners.find((o) => o.id === profileData.primary_owner_id)
        : null;
      const primaryAssocOwner = profileData?.primary_association_id
        ? owners.find((o) => o.association_id === profileData.primary_association_id)
        : null;
      const selected = savedOwner || primaryOwner || primaryAssocOwner || owners[0] || null;
      setCurrentOwner(selected);
      setLoading(false);
    };

    fetchOwners();
  }, [user, isViewingAs, viewAsRole, realIsAdmin]);

  // Fetch association and unit when current owner changes
  useEffect(() => {
    if (!currentOwner) {
      setAssociation(null);
      setUnit(null);
      return;
    }

    const fetchDetails = async () => {
      // Fetch association
      const { data: assocData } = await supabase
        .from("associations")
        .select("id, name, phone, email, contact_email, address, website")
        .eq("id", currentOwner.association_id)
        .single();

      if (assocData) {
        setAssociation({
          id: assocData.id,
          name: assocData.name,
          phone: assocData.phone,
          email: assocData.contact_email || assocData.email,
          address: assocData.address,
          website: (assocData as any).website,
        });
      }

      // Fetch unit if linked
      if (currentOwner.unit_id) {
        const { data: unitData } = await supabase
          .from("units")
          .select("id, unit_number, address, account_number")
          .eq("id", currentOwner.unit_id)
          .single();

        if (unitData) {
          setUnit({
            id: unitData.id,
            unit_number: unitData.unit_number,
            address: unitData.address,
            account_number: unitData.account_number,
          });
        }
      } else {
        setUnit(null);
      }
    };

    fetchDetails();
  }, [currentOwner]);

  const selectOwner = useCallback((ownerId: string) => {
    const owner = ownerRecords.find((o) => o.id === ownerId);
    if (owner) {
      setCurrentOwner(owner);
      localStorage.setItem("homeowner_selected_owner", ownerId);
    }
  }, [ownerRecords]);

  return (
    <HomeownerContext.Provider
      value={{ ownerRecords, associationNames, currentOwner, association, unit, selectOwner, loading }}
    >
      {children}
    </HomeownerContext.Provider>
  );
}

export function useHomeowner() {
  return useContext(HomeownerContext);
}
