"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import DataService from "@/config/axios";
import type { ActiveTenantContext, MembershipSummary } from "../types/tenancy";
import { ALL_UNITS_SCOPE } from "../types/tenancy";

const STORAGE_ORG_KEY = "nizamify_active_org";
const STORAGE_UNIT_KEY = "nizamify_active_unit";

type ActiveTenantContextValue = ActiveTenantContext & {
  loading: boolean;
  setActiveOrganization: (organizationKey: string) => void;
  setUnitScope: (unitId: string) => void;
  refreshMemberships: () => Promise<void>;
};

const defaultState: ActiveTenantContextValue = {
  organizationId: null,
  organizationKey: null,
  organizationName: null,
  unitLabel: "Unit",
  unitScope: ALL_UNITS_SCOPE,
  unitName: null,
  memberships: [],
  isSuperAdmin: false,
  loading: true,
  setActiveOrganization: () => {},
  setUnitScope: () => {},
  refreshMemberships: async () => {},
};

const ActiveTenantContext = createContext<ActiveTenantContextValue>(defaultState);

export function ActiveTenantProvider({ children }: { children: ReactNode }) {
  const [loading, setLoading] = useState(true);
  const [memberships, setMemberships] = useState<MembershipSummary[]>([]);
  const [organizationKey, setOrganizationKey] = useState<string | null>(null);
  const [unitScope, setUnitScopeState] = useState<string>(ALL_UNITS_SCOPE);
  const [isSuperAdmin, setIsSuperAdmin] = useState(false);

  const refreshMemberships = useCallback(async () => {
    try {
      const meRes = await DataService.get("/user/me");
      const isSuperAdmin = meRes.data?.data?.type === "super_admin";

      const res = await DataService.get("/platform/me/memberships");
      const rows: MembershipSummary[] = res.data?.data || [];
      setMemberships(rows);

      const storedOrg = typeof window !== "undefined" ? localStorage.getItem(STORAGE_ORG_KEY) : null;
      const storedUnit = typeof window !== "undefined" ? localStorage.getItem(STORAGE_UNIT_KEY) : null;

      if (storedOrg && rows.some((m) => m.organization?.clientId === storedOrg)) {
        setOrganizationKey(storedOrg);
      } else if (rows[0]?.organization?.clientId) {
        setOrganizationKey(rows[0].organization.clientId);
      }

      if (storedUnit) setUnitScopeState(storedUnit);
      setIsSuperAdmin(isSuperAdmin);
    } catch {
      setMemberships([]);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    refreshMemberships();
  }, [refreshMemberships]);

  const activeMembership = useMemo(
    () => memberships.find((m) => m.organization?.clientId === organizationKey) || null,
    [memberships, organizationKey],
  );

  const setActiveOrganization = useCallback((key: string) => {
    setOrganizationKey(key);
    if (typeof window !== "undefined") {
      localStorage.setItem(STORAGE_ORG_KEY, key);
    }
  }, []);

  const setUnitScope = useCallback((unitId: string) => {
    setUnitScopeState(unitId);
    if (typeof window !== "undefined") {
      localStorage.setItem(STORAGE_UNIT_KEY, unitId);
    }
  }, []);

  const value = useMemo<ActiveTenantContextValue>(
    () => ({
      organizationId: activeMembership?.organization?._id ?? null,
      organizationKey,
      organizationName: activeMembership?.organization?.name ?? null,
      unitLabel: activeMembership?.organization?.unitLabel || "Unit",
      unitScope,
      unitName: null,
      memberships,
      isSuperAdmin,
      loading,
      setActiveOrganization,
      setUnitScope,
      refreshMemberships,
    }),
    [
      activeMembership,
      organizationKey,
      unitScope,
      memberships,
      loading,
      isSuperAdmin,
      setActiveOrganization,
      setUnitScope,
      refreshMemberships,
    ],
  );

  return <ActiveTenantContext.Provider value={value}>{children}</ActiveTenantContext.Provider>;
}

export function useActiveTenant() {
  return useContext(ActiveTenantContext);
}

/** Attach org + unit headers to axios for platform-aware APIs. */
export function applyTenantHeaders(
  organizationKey: string | null,
  unitScope: string,
): Record<string, string> {
  const headers: Record<string, string> = {};
  if (organizationKey) headers["X-Organization-Id"] = organizationKey;
  if (unitScope && unitScope !== ALL_UNITS_SCOPE) headers["X-Unit-Id"] = unitScope;
  return headers;
}
