"use client";

import { useCallback, useState } from "react";

import { getAdminIntegrationSites } from "@/api/admin-integration-sites";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_INTEGRATION_ACCESS_ANY, PRD_USERS_MANAGE } from "@/lib/admin-prd";
import { useAdminProfile } from "@/stores/admin-session";
import { useAsyncEffect } from "@/hooks/use-async-effect";

export type AdminSiteCodeOption = {
  id: number;
  code: string;
  name: string;
};

let cachedSites: AdminSiteCodeOption[] | null = null;
let inflightSites: Promise<AdminSiteCodeOption[]> | null = null;

export function clearCachedAdminSiteCodeOptions(): void {
  cachedSites = null;
  inflightSites = null;
}

async function fetchSiteCodeOptions(): Promise<AdminSiteCodeOption[]> {
  if (cachedSites !== null) {
    return cachedSites;
  }
  if (inflightSites !== null) {
    return inflightSites;
  }

  inflightSites = getAdminIntegrationSites()
    .then((data) => {
      const byId = new Map<number, AdminSiteCodeOption>();
      for (const row of data.items) {
        if (!byId.has(row.id)) {
          byId.set(row.id, { id: row.id, code: row.code, name: row.name });
        }
      }
      cachedSites = [...byId.values()];
      return cachedSites;
    })
    .catch(() => {
      cachedSites = [];
      return [];
    })
    .finally(() => {
      inflightSites = null;
    });

  return inflightSites;
}

/**
 * 接入站点下拉（已按当前管理员站点权限过滤；模块级缓存避免多页重复 GET）。
 */
export function useAdminSiteCodeOptions(): {
  sites: AdminSiteCodeOption[];
  loading: boolean;
  canChooseSite: boolean;
  reload: () => Promise<void>;
} {
  const profile = useAdminProfile();
  const canLoad = adminHasAnyPermission(profile?.permissions, [
    ...PRD_INTEGRATION_ACCESS_ANY,
    PRD_USERS_MANAGE,
  ]);

  const [sites, setSites] = useState<AdminSiteCodeOption[]>(cachedSites ?? []);
  const [loading, setLoading] = useState(canLoad && cachedSites === null);

  const reload = useCallback(async () => {
    if (!canLoad) {
      setSites([]);
      setLoading(false);
      return;
    }

    setLoading(true);
    try {
      clearCachedAdminSiteCodeOptions();
      const next = await fetchSiteCodeOptions();
      setSites(next);
    } catch {
      setSites([]);
    } finally {
      setLoading(false);
    }
  }, [canLoad]);

  useAsyncEffect(() => {
    if (!canLoad) {
      setSites([]);
      setLoading(false);
      return;
    }
    if (cachedSites !== null) {
      setSites(cachedSites);
      setLoading(false);
      return;
    }
    void (async () => {
      setLoading(true);
      const next = await fetchSiteCodeOptions();
      setSites(next);
      setLoading(false);
    })();
  }, [canLoad]);

  return {
    sites,
    loading,
    canChooseSite: canLoad && sites.length > 0,
    reload,
  };
}
