"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";

import {
  getAdminPlayTypes,
  getAllConfigVersions,
  getOddsVersion,
  getOddsVersions,
} from "@/api/admin-config";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { ensureAdminPlayTypesLoaded } from "@/lib/admin-play-types";
import { pickDefaultConfigVersionId } from "@/lib/config-version-auto-pick";
import { LotteryApiBizError } from "@/types/api/errors";
import type {
  AdminPlayTypeRow,
  ConfigVersionSummary,
  OddsItemRow,
  OddsVersionDetail,
} from "@/types/api/admin-config";

export type OddsConfigWorkspace = {
  types: AdminPlayTypeRow[];
  list: ConfigVersionSummary[];
  selectedId: string;
  setSelectedId: (id: string) => void;
  detail: OddsVersionDetail | null;
  draftRows: OddsItemRow[];
  setDraftRows: React.Dispatch<React.SetStateAction<OddsItemRow[]>>;
  applyDetail: (detail: OddsVersionDetail) => void;
  loadingTypes: boolean;
  loadingList: boolean;
  loadingDetail: boolean;
  error: string | null;
  refreshTypes: () => Promise<void>;
  refreshList: () => Promise<void>;
  reloadDetail: () => Promise<void>;
};

/** 赔率/回水合并页：版本列表与详情只加载一次，避免双组件重复请求导致卡顿。 */
export function useOddsConfigWorkspace(
  selectedId: string,
  onSelectedIdChange: (id: string) => void,
): OddsConfigWorkspace {
  const tRef = useTranslationRef("common");
  const [types, setTypes] = useState<AdminPlayTypeRow[]>([]);
  const [list, setList] = useState<ConfigVersionSummary[]>([]);
  const [detail, setDetail] = useState<OddsVersionDetail | null>(null);
  const [draftRows, setDraftRows] = useState<OddsItemRow[]>([]);
  const [loadingTypes, setLoadingTypes] = useState(true);
  const [loadingList, setLoadingList] = useState(true);
  const [loadingDetail, setLoadingDetail] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const detailRequestSeq = useRef(0);
  const bootstrappedRef = useRef(false);

  const applyDetail = useCallback((next: OddsVersionDetail) => {
    setDetail(next);
    setDraftRows(next.items.map((it) => ({ ...it })));
  }, []);

  const refreshTypes = useCallback(async () => {
    setLoadingTypes(true);
    try {
      setTypes(await ensureAdminPlayTypesLoaded(getAdminPlayTypes));
    } catch (e) {
      toast.error(e instanceof LotteryApiBizError ? e.message : tRef.current("errors.loadFailed"));
      setTypes([]);
    } finally {
      setLoadingTypes(false);
    }
  }, [tRef]);

  const refreshList = useCallback(async () => {
    setLoadingList(true);
    setError(null);
    try {
      const d = await getAllConfigVersions(getOddsVersions);
      setList(d.items);
    } catch (e) {
      const msg = e instanceof LotteryApiBizError ? e.message : tRef.current("errors.loadFailed");
      setError(msg);
      setList([]);
    } finally {
      setLoadingList(false);
    }
  }, [tRef]);

  const loadDetail = useCallback(
    async (id: number) => {
      const seq = ++detailRequestSeq.current;
      setLoadingDetail(true);
      try {
        const d = await getOddsVersion(id);
        if (seq !== detailRequestSeq.current) {
          return;
        }
        applyDetail(d);
      } catch (e) {
        if (seq !== detailRequestSeq.current) {
          return;
        }
        toast.error(e instanceof LotteryApiBizError ? e.message : tRef.current("errors.loadFailed"));
        setDetail(null);
        setDraftRows([]);
      } finally {
        if (seq === detailRequestSeq.current) {
          setLoadingDetail(false);
        }
      }
    },
    [applyDetail, tRef],
  );

  const reloadDetail = useCallback(async () => {
    if (selectedId === "") {
      return;
    }
    const id = Number(selectedId);
    if (!Number.isFinite(id)) {
      return;
    }
    await loadDetail(id);
  }, [loadDetail, selectedId]);

  useEffect(() => {
    if (bootstrappedRef.current) {
      return;
    }
    bootstrappedRef.current = true;
    void Promise.all([refreshTypes(), refreshList()]);
  }, [refreshTypes, refreshList]);

  useEffect(() => {
    if (list.length === 0) {
      if (selectedId !== "") {
        onSelectedIdChange("");
        setDetail(null);
        setDraftRows([]);
      }
      return;
    }
    if (selectedId !== "" && list.some((x) => String(x.id) === selectedId)) {
      return;
    }
    const pickId = pickDefaultConfigVersionId(list);
    if (pickId) {
      onSelectedIdChange(pickId);
    }
  }, [list, onSelectedIdChange, selectedId]);

  useEffect(() => {
    if (selectedId === "") {
      return;
    }
    const id = Number(selectedId);
    if (!Number.isFinite(id)) {
      return;
    }
    void loadDetail(id);
  }, [loadDetail, selectedId]);

  return {
    types,
    list,
    selectedId,
    setSelectedId: onSelectedIdChange,
    detail,
    draftRows,
    setDraftRows,
    applyDetail,
    loadingTypes,
    loadingList,
    loadingDetail,
    error,
    refreshTypes,
    refreshList,
    reloadDetail,
  };
}
