/**
 * User Management Custom Hooks
 *
 * Reusable React hooks for user management feature.
 * Handles data fetching, state management, and API interactions.
 *
 * @module hooks/useUserManagement
 */

import { useState, useEffect, useCallback } from "react";
import type {
  UserListItem,
  UserFilters,
  UserStats,
  GeographyData,
} from "@/lib/types/user-management.types";
import {
  API_ENDPOINTS,
  TIME_PERIODS,
} from "@/lib/constants/user-management.constants";

// ============================================
// USER LIST HOOK
// ============================================

/**
 * Hook for fetching and managing user list
 *
 * @param initialFilters - Initial filter values
 * @returns User list state and actions
 *
 * @example
 * const { users, loading, fetchUsers, filters, setFilters } = useUserList();
 */
export function useUserList(
  initialFilters: UserFilters = {
    search: "",
    status: "all",
    role: "all",
    country: "",
  },
) {
  const [users, setUsers] = useState<UserListItem[]>([]);
  const [filteredUsers, setFilteredUsers] = useState<UserListItem[]>([]);
  const [stats, setStats] = useState<UserStats | null>(null);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [filters, setFilters] = useState<UserFilters>(initialFilters);

  /**
   * Fetch users from API
   */
  const fetchUsers = useCallback(async (showRefreshIndicator = false) => {
    if (showRefreshIndicator) {
      setRefreshing(true);
    } else {
      setLoading(true);
    }

    setError(null);

    try {
      const response = await fetch(API_ENDPOINTS.LIST_USERS);

      if (!response.ok) {
        throw new Error("Failed to fetch users");
      }

      const data = await response.json();

      // Transform and set users
      const enhancedUsers: UserListItem[] = data.users.map((u: any) => ({
        ...u,
        accountStatus: u.accountStatus || "active",
      }));

      setUsers(enhancedUsers);

      // Set analytics
      if (data.analytics) {
        const topCountryEntry = Object.entries(
          data.analytics.byCountry || {},
        ).sort((a: any, b: any) => b[1] - a[1])[0];

        const topIndustryEntry = Object.entries(
          data.analytics.byIndustry || {},
        ).sort((a: any, b: any) => b[1] - a[1])[0];

        setStats({
          total: data.analytics.total || 0,
          active: data.analytics.active || 0,
          suspended: data.analytics.suspended || 0,
          locked: data.analytics.locked || 0,
          topCountry: topCountryEntry
            ? { name: topCountryEntry[0], count: topCountryEntry[1] as number }
            : null,
          topIndustry: topIndustryEntry
            ? {
                name: topIndustryEntry[0],
                count: topIndustryEntry[1] as number,
              }
            : null,
        });
      }
    } catch (err) {
      console.error("Failed to fetch users:", err);
      setError("Failed to load users. Please try again.");
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

  // Apply filters client-side
  useEffect(() => {
    let filtered = [...users];

    if (filters.search) {
      const searchLower = filters.search.toLowerCase();
      filtered = filtered.filter(
        (u) =>
          u.name.toLowerCase().includes(searchLower) ||
          u.email.toLowerCase().includes(searchLower) ||
          u.companyName?.toLowerCase().includes(searchLower),
      );
    }

    if (filters.status !== "all") {
      filtered = filtered.filter((u) => u.accountStatus === filters.status);
    }

    if (filters.role !== "all") {
      filtered = filtered.filter((u) => u.role === filters.role);
    }

    if (filters.country) {
      filtered = filtered.filter((u) => u.lastLoginCountry === filters.country);
    }

    setFilteredUsers(filtered);
  }, [users, filters]);

  // Initial fetch
  useEffect(() => {
    fetchUsers();
  }, [fetchUsers]);

  return {
    users,
    filteredUsers,
    stats,
    loading,
    refreshing,
    error,
    filters,
    setFilters,
    fetchUsers,
  };
}

// ============================================
// AUTO-REFRESH HOOK
// ============================================

/**
 * Hook for auto-refreshing data
 *
 * @param enabled - Whether auto-refresh is enabled
 * @param callback - Function to call on refresh
 * @param interval - Refresh interval in ms
 *
 * @example
 * useAutoRefresh(autoRefreshEnabled, () => fetchUsers(true), 30000);
 */
export function useAutoRefresh(
  enabled: boolean,
  callback: () => void,
  interval: number = TIME_PERIODS.AUTO_REFRESH_INTERVAL_MS,
) {
  useEffect(() => {
    if (!enabled) return;

    const timer = setInterval(callback, interval);

    return () => clearInterval(timer);
  }, [enabled, callback, interval]);
}

// ============================================
// USER DETAILS HOOK
// ============================================

/**
 * Hook for fetching user details
 *
 * @param userId - User ID to fetch details for
 * @returns User details and loading state
 *
 * @example
 * const { user, analytics, loading } = useUserDetails(userId);
 */
export function useUserDetails(userId: string | null) {
  const [user, setUser] = useState<any>(null);
  const [analytics, setAnalytics] = useState<any>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchDetails = useCallback(async () => {
    if (!userId) return;

    setLoading(true);
    setError(null);

    try {
      const response = await fetch(
        API_ENDPOINTS.USER_DETAILS.replace(":id", userId),
      );

      if (!response.ok) {
        throw new Error("Failed to fetch user details");
      }

      const data = await response.json();
      setUser(data.user);
      setAnalytics(data.analytics);
    } catch (err) {
      console.error("Failed to fetch user details:", err);
      setError("Failed to load user details");
    } finally {
      setLoading(false);
    }
  }, [userId]);

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

  return {
    user,
    analytics,
    loading,
    error,
    refetch: fetchDetails,
  };
}

// ============================================
// COPY TO CLIPBOARD HOOK
// ============================================

/**
 * Hook for copy-to-clipboard functionality with feedback
 *
 * @returns Copy function and copied state
 *
 * @example
 * const { copy, copied } = useCopyToClipboard();
 * <button onClick={() => copy('text@example.com')}>Copy</button>
 */
export function useCopyToClipboard() {
  const [copiedText, setCopiedText] = useState<string | null>(null);

  const copy = async (text: string) => {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedText(text);

      // Clear after 2 seconds
      setTimeout(() => {
        setCopiedText(null);
      }, TIME_PERIODS.CLIPBOARD_FEEDBACK_MS);
    } catch (err) {
      console.error("Failed to copy to clipboard:", err);
    }
  };

  return {
    copy,
    copied: copiedText,
    isCopied: (text: string) => copiedText === text,
  };
}

// ============================================
// GEOGRAPHY DATA HOOK
// ============================================

/**
 * Hook for preparing geography visualization data
 *
 * @param users - User list
 * @returns Geography data for map view
 */
export function useGeographyData(users: UserListItem[]): GeographyData[] {
  const [data, setData] = useState<GeographyData[]>([]);

  useEffect(() => {
    const countryCount = users.reduce(
      (acc, user) => {
        const country = user.lastLoginCountry || user.country || "Unknown";
        acc[country] = (acc[country] || 0) + 1;
        return acc;
      },
      {} as Record<string, number>,
    );

    const total = users.length;

    const geoData: GeographyData[] = Object.entries(countryCount)
      .map(([country, count]) => ({
        country,
        count,
        percentage: total > 0 ? (count / total) * 100 : 0,
      }))
      .sort((a, b) => b.count - a.count);

    setData(geoData);
  }, [users]);

  return data;
}

// ============================================
// FILTER COUNT HOOK
// ============================================

/**
 * Hook to count active filters
 *
 * @param filters - Current filter state
 * @returns Number of active filters
 */
export function useFilterCount(filters: UserFilters): number {
  return [
    filters.search !== "",
    filters.status !== "all",
    filters.role !== "all",
    filters.country !== "",
  ].filter(Boolean).length;
}

// ============================================
// CSV EXPORT HOOK
// ============================================

/**
 * Hook for CSV export functionality
 *
 * @returns Export function
 *
 * @example
 * const { exportToCSV, exporting } = useCSVExport();
 * <button onClick={() => exportToCSV(users)}>Export</button>
 */
export function useCSVExport() {
  const [exporting, setExporting] = useState(false);

  const exportToCSV = useCallback((users: UserListItem[]) => {
    setExporting(true);

    try {
      const csvData = users.map((u) => ({
        Name: u.name,
        Email: u.email,
        Role: u.role,
        Status: u.accountStatus,
        Company: u.companyName || "",
        Industry: u.industry || "",
        Country: u.lastLoginCountry || u.country || "",
        City: u.lastLoginCity || u.city || "",
        "Login Count": u.loginCount,
        "Last Login": u.lastLoginAt
          ? new Date(u.lastLoginAt).toISOString()
          : "",
        Registered: new Date(u.createdAt).toISOString(),
      }));

      const headers = Object.keys(csvData[0] || {});
      const csvRows = [
        headers.join(","),
        ...csvData.map((row) =>
          headers
            .map((header) => `"${row[header as keyof typeof row]}"`)
            .join(","),
        ),
      ];

      const csvString = csvRows.join("\n");
      const blob = new Blob([csvString], { type: "text/csv;charset=utf-8;" });
      const url = URL.createObjectURL(blob);

      const link = document.createElement("a");
      link.href = url;
      link.download = `users-export-${new Date().toISOString().split("T")[0]}.csv`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      URL.revokeObjectURL(url);

      console.log(`📥 Exported ${users.length} users to CSV`);
    } catch (err) {
      console.error("Failed to export CSV:", err);
    } finally {
      setExporting(false);
    }
  }, []);

  return {
    exportToCSV,
    exporting,
  };
}

// ============================================
// MODAL STATE HOOK
// ============================================

/**
 * Hook for managing modal state
 *
 * @returns Modal state and controls
 *
 * @example
 * const { isOpen, selectedItem, open, close } = useModal<UserListItem>();
 */
export function useModal<T = any>() {
  const [isOpen, setIsOpen] = useState(false);
  const [selectedItem, setSelectedItem] = useState<T | null>(null);

  const open = (item: T) => {
    setSelectedItem(item);
    setIsOpen(true);
  };

  const close = () => {
    setIsOpen(false);
    // Delay clearing selected item to allow close animation
    setTimeout(() => setSelectedItem(null), 300);
  };

  return {
    isOpen,
    selectedItem,
    open,
    close,
  };
}
