import { useState, useEffect, useCallback, useRef } from "react";
import { useRouter } from "next/navigation";
import { apiCall } from "@/lib/api/client";
import { AuthLogger } from "@/lib/authLogger";
import { TokenManager } from "@/lib/auth/tokenManager";

interface UserInfo {
  user_id?: string;
  user_name?: string;
  userNameEng?: string;
  userNameCn?: string;
  deptCode?: string;
  dept_name?: string;
  positionCode?: string;
  position_name?: string;
  email?: string;
  tel?: string;
  cellPhone?: string;
  user_type?: string;
  userTypeName?: string;
  authName?: string;
  partnerCd?: string;
  locale?: string;
  isAdmin: boolean;
  sabun?: string;
  photo?: string | null;
  company_code?: string;
  force_password_change?: boolean;
}

interface AuthStatus {
  isLoggedIn: boolean;
  isAdmin: boolean;
  userId?: string;
  deptCode?: string;
}

interface ApiResponse<T = any> {
  success: boolean;
  message: string;
  data?: T;
  errorCode?: string;
}

/**
 * 인증 상태 관리 훅
 * - 401 처리는 client.ts의 응답 인터셉터에서 통합 관리
 * - 이 훅은 상태 관리와 사용자 정보 조회에만 집중
 */
export const useAuth = () => {
  const router = useRouter();

  const [user, setUser] = useState<UserInfo | null>(null);
  const [authStatus, setAuthStatus] = useState<AuthStatus>({
    isLoggedIn: false,
    isAdmin: false,
  });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const initializedRef = useRef(false);

  /**
   * 현재 사용자 정보 조회
   */
  const fetchCurrentUser = useCallback(async (): Promise<UserInfo | null> => {
    try {
      const response = await apiCall<UserInfo>("GET", "/auth/me");

      if (response.success && response.data) {
        const userLocale = response.data.locale || "KR";
        (window as any).__GLOBAL_USER_LANG = userLocale;
        (window as any).__GLOBAL_USER_LOCALE_LOADED = true;
        localStorage.setItem("userLocale", userLocale);
        localStorage.setItem("userLocaleLoaded", "true");

        const data = response.data;
        return {
          ...data,
          user_type: data.user_type,
          company_code: data.company_code,
          user_id: data.user_id,
          user_name: data.user_name,
        };
      }

      return null;
    } catch {
      return null;
    }
  }, []);

  /**
   * 사용자 데이터 새로고침
   * - 백엔드 /auth/me 가 성공해야만 로그인 상태 유지
   * - /auth/me 응답에 is_admin, locale, force_password_change 등이 모두 포함되므로
   *   이전에 별도로 호출하던 /auth/status, /admin/user-locale 은 제거됨 (라운드트립 절약)
   */
  const refreshUserData = useCallback(async () => {
    try {
      setLoading(true);

      const token = TokenManager.getToken();
      if (!token) {
        AuthLogger.log("AUTH_CHECK_FAIL", "refreshUserData: 토큰 없음");
        setUser(null);
        setAuthStatus({ isLoggedIn: false, isAdmin: false });
        setLoading(false);
        return;
      }
      // 만료된 토큰이라도 apiClient 요청 인터셉터가 자동 갱신하므로 여기서 차단하지 않음

      AuthLogger.log("AUTH_CHECK_START", "refreshUserData: API로 인증 상태 확인 시작");

      setAuthStatus({
        isLoggedIn: true,
        isAdmin: false,
      });

      const userInfo = await fetchCurrentUser();

      if (userInfo) {
        setUser(userInfo);

        // 백엔드 AuthService.checkAuthStatus 와 동일한 판정 로직을 user_type 기반으로 적용.
        // (별도 /auth/status 호출 없이 동일 결과)
        const userType = userInfo.user_type;
        const isAdmin = userInfo.user_id === "plm_admin"
          || userType === "ADMIN"
          || userType === "SUPER_ADMIN"
          || userType === "COMPANY_ADMIN";
        const finalAuthStatus = {
          isLoggedIn: true,
          isAdmin,
        };

        setAuthStatus(finalAuthStatus);
        AuthLogger.log("AUTH_CHECK_SUCCESS", `사용자: ${userInfo.user_id}, 인증: ${finalAuthStatus.isLoggedIn}`);
      } else {
        AuthLogger.log("AUTH_CHECK_FAIL", "userInfo 조회 실패 → 비인증 전환");
        TokenManager.removeToken();
        setUser(null);
        setAuthStatus({ isLoggedIn: false, isAdmin: false });
      }
    } catch {
      AuthLogger.log("AUTH_CHECK_FAIL", "API 호출 예외 → 비인증 전환");
      TokenManager.removeToken();
      setUser(null);
      setAuthStatus({ isLoggedIn: false, isAdmin: false });
      setError("사용자 정보를 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  }, [fetchCurrentUser]);

  /**
   * 회사 전환 처리 (Invyone 관리자 전용)
   */
  const switchCompany = useCallback(
    async (companyCode: string): Promise<{ success: boolean; message: string }> => {
      try {
        setLoading(true);
        setError(null);

        const response = await apiCall<any>("POST", "/auth/switch-company", {
          company_code: companyCode,
        });

        if (response.success && response.data?.token) {
          TokenManager.setToken(response.data.token);

          return {
            success: true,
            message: response.message || "회사 전환에 성공했습니다.",
          };
        } else {
          return {
            success: false,
            message: response.message || "회사 전환에 실패했습니다.",
          };
        }
      } catch (error: any) {
        const errorMessage = error.message || "회사 전환 중 오류가 발생했습니다.";
        setError(errorMessage);

        return {
          success: false,
          message: errorMessage,
        };
      } finally {
        setLoading(false);
      }
    },
    [],
  );

  /**
   * 로그아웃 처리
   */
  const logout = useCallback(async (): Promise<boolean> => {
    try {
      setLoading(true);

      const response = await apiCall("POST", "/auth/logout");

      TokenManager.removeToken();

      localStorage.removeItem("userLocale");
      localStorage.removeItem("userLocaleLoaded");
      (window as any).__GLOBAL_USER_LANG = undefined;
      (window as any).__GLOBAL_USER_LOCALE_LOADED = undefined;

      setUser(null);
      setAuthStatus({ isLoggedIn: false, isAdmin: false });
      setError(null);

      router.push("/login");

      return response.success;
    } catch {
      TokenManager.removeToken();

      localStorage.removeItem("userLocale");
      localStorage.removeItem("userLocaleLoaded");
      (window as any).__GLOBAL_USER_LANG = undefined;
      (window as any).__GLOBAL_USER_LOCALE_LOADED = undefined;

      setUser(null);
      setAuthStatus({ isLoggedIn: false, isAdmin: false });
      router.push("/login");

      return false;
    } finally {
      setLoading(false);
    }
  }, [router]);

  /**
   * 메뉴 접근 권한 확인
   */
  const checkMenuAuth = useCallback(async (menuUrl: string): Promise<boolean> => {
    try {
      const response = await apiCall<{ menuUrl: string; hasAuth: boolean }>("GET", "/auth/menu-auth");

      if (response.success && response.data) {
        return response.data.hasAuth;
      }

      return false;
    } catch {
      return false;
    }
  }, []);

  /**
   * 초기 인증 상태 확인
   */
  useEffect(() => {
    if (initializedRef.current) return;
    initializedRef.current = true;

    if (typeof window === "undefined") return;

    // 로그인 페이지에서는 인증 상태 확인하지 않음
    if (window.location.pathname === "/login") {
      setLoading(false);
      return;
    }

    const token = TokenManager.getToken();

    if (token) {
      // 유효/만료 모두 refreshUserData로 처리
      // apiClient 요청 인터셉터가 만료 토큰을 자동 갱신하므로 여기서 삭제하지 않음
      const isExpired = TokenManager.isTokenExpired(token);
      AuthLogger.log(
        "AUTH_CHECK_START",
        `초기 인증 확인: 토큰 ${isExpired ? "만료됨 → 갱신 시도" : "유효"} (경로: ${window.location.pathname})`,
      );
      setAuthStatus({
        isLoggedIn: true,
        isAdmin: false,
      });
      refreshUserData();
    } else {
      AuthLogger.log("AUTH_CHECK_FAIL", `초기 확인: 토큰 없음 (경로: ${window.location.pathname})`);
      setAuthStatus({ isLoggedIn: false, isAdmin: false });
      setLoading(false);
    }
  }, []);

  return {
    user,
    authStatus,
    loading,
    error,

    isLoggedIn: authStatus.isLoggedIn,
    isAdmin: authStatus.isAdmin,
    forcePasswordChange: user?.force_password_change === true,
    userId: user?.user_id,
    userName: user?.user_name,
    companyCode: user?.company_code,

    logout,
    switchCompany,
    checkMenuAuth,
    refreshUserData,

    clearError: () => setError(null),
  };
};

export default useAuth;
