/**
 * Authentication Hooks
 * Custom hooks for authentication functionality
 */

"use client";

import { useCallback, useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAuthStore } from "../services/auth.store";
import { getPostLoginRedirect } from "@/features/auth/utils/route-protection";
import type { SignupRequest, LoginRequest } from "@customer-portal/domain/auth";
import type { LogoutReason } from "@/features/auth/utils/logout-reason";

/**
 * Main authentication hook
 */
export function useAuth() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const {
    isAuthenticated,
    user,
    loading,
    hasCheckedAuth,
    error,
    login: loginAction,
    signup: signupAction,
    logout: logoutAction,
    requestPasswordReset,
    resetPassword,
    changePassword,
    checkPasswordNeeded,
    linkWhmcs,
    setPassword,
    checkAuth,
    refreshSession,
    clearError,
    clearLoading,
  } = useAuthStore();

  // Enhanced login with redirect handling
  const login = useCallback(
    async (credentials: LoginRequest) => {
      await loginAction(credentials);
      // Keep loading state active during redirect
      const redirectTo = getPostLoginRedirect(searchParams);
      router.push(redirectTo);
      // Note: loading will be cleared when the new page loads
    },
    [loginAction, router, searchParams]
  );

  // Enhanced signup with redirect handling
  const signup = useCallback(
    async (data: SignupRequest) => {
      await signupAction(data);
      const redirectTo = getPostLoginRedirect(searchParams);
      router.push(redirectTo);
    },
    [signupAction, router, searchParams]
  );

  // Enhanced logout with redirect
  const logout = useCallback(
    async (options?: { reason?: LogoutReason }) => {
      const reason = options?.reason ?? ("manual" as const);
      await logoutAction({ reason });
      const reasonQuery = reason ? `?reason=${reason}` : "";
      router.push(`/auth/login${reasonQuery}`);
    },
    [logoutAction, router]
  );

  return {
    // State
    isAuthenticated,
    user,
    loading,
    hasCheckedAuth,
    error,

    // Actions
    login,
    signup,
    logout,
    requestPasswordReset,
    resetPassword,
    changePassword,
    checkPasswordNeeded,
    linkWhmcs,
    setPassword,
    checkAuth,
    refreshSession,
    clearError,
    clearLoading,
  };
}

/**
 * Hook for login functionality
 */
export function useLogin() {
  const { login, loading, error, clearError } = useAuth();

  return {
    login,
    loading,
    error,
    clearError,
  };
}

/**
 * Hook for signup functionality
 */
export function useSignup() {
  const { signup, loading, error, clearError } = useAuth();

  return {
    signup,
    loading,
    error,
    clearError,
  };
}

/**
 * Hook for password reset functionality
 */
export function usePasswordReset() {
  const { requestPasswordReset, resetPassword, loading, error, clearError } = useAuth();

  return {
    requestPasswordReset,
    resetPassword,
    loading,
    error,
    clearError,
  };
}

/**
 * Hook for password change functionality
 */
export function usePasswordChange() {
  const { changePassword, loading, error, clearError } = useAuth();

  return {
    changePassword,
    loading,
    error,
    clearError,
  };
}

/**
 * Hook for WHMCS linking functionality
 */
export function useWhmcsLink() {
  const { checkPasswordNeeded, linkWhmcs, setPassword, loading, error, clearError } = useAuth();

  return {
    checkPasswordNeeded,
    linkWhmcs,
    setPassword,
    loading,
    error,
    clearError,
  };
}

/**
 * Hook for session management
 */
export function useSession() {
  const { isAuthenticated, user, checkAuth, refreshSession, logout } = useAuth();

  // Auto-check auth on mount
  useEffect(() => {
    void checkAuth();
  }, [checkAuth]);

  // Auto-refresh session periodically
  useEffect(() => {
    if (!isAuthenticated) {
      return undefined;
    }

    const interval = setInterval(
      () => {
        void refreshSession();
      },
      5 * 60 * 1000
    ); // Check every 5 minutes

    return () => clearInterval(interval);
  }, [isAuthenticated, refreshSession]);

  useEffect(() => {
    if (!isAuthenticated || typeof window === "undefined") {
      return undefined;
    }

    let lastRefresh = 0;
    const minInterval = 60 * 1000;

    const triggerRefresh = () => {
      const now = Date.now();
      if (now - lastRefresh < minInterval) {
        return;
      }
      lastRefresh = now;
      void refreshSession();
    };

    const handleVisibility = () => {
      if (document.visibilityState === "visible") {
        triggerRefresh();
      }
    };

    const handleFocus = () => {
      triggerRefresh();
    };

    window.addEventListener("focus", handleFocus);
    document.addEventListener("visibilitychange", handleVisibility);

    triggerRefresh();

    return () => {
      window.removeEventListener("focus", handleFocus);
      document.removeEventListener("visibilitychange", handleVisibility);
    };
  }, [isAuthenticated, refreshSession]);

  return {
    isAuthenticated,
    user,
    checkAuth,
    refreshSession,
    logout,
  };
}

/**
 * Hook for user profile information
 */
export function useUser() {
  const { user, isAuthenticated } = useAuth();

  const fullName = user ? `${user.firstname || ""} ${user.lastname || ""}`.trim() : "";
  const initials = user
    ? `${user.firstname?.[0] || ""}${user.lastname?.[0] || ""}`.toUpperCase()
    : "";

  return {
    user,
    isAuthenticated,
    fullName,
    initials,
    email: user?.email,
    company: user?.companyname,
    phone: user?.phonenumber,
    avatar: undefined, // Not in current schema
    preferences: undefined, // Not in current schema
  };
}

/**
 * Hook for checking user permissions
 */
export function usePermissions() {
  const { user } = useAuth();

  const hasRole = useCallback(
    (role: string) => {
      if (!user?.role) return false;
      return user.role === role;
    },
    [user?.role]
  );

  const hasAnyRole = useCallback((roles: string[]) => roles.some(role => hasRole(role)), [hasRole]);

  const hasPermission = useCallback(() => false, []);
  const hasAnyPermission = useCallback(() => false, []);

  return {
    role: user?.role,
    hasRole,
    hasAnyRole,
    hasPermission,
    hasAnyPermission,
  };
}
