import { useState, useEffect, useCallback } from "react";
import {
  AccessLog,
  AccessLogQuery,
  AccessLogStatsQueryDto,
  AccessLogsResponse,
  OperationStatsResponse,
  TopUsersResponse,
} from "../types/AccessLogTypes";
import { accessLogsService } from "../service/AccessLogService";

export const useAccessLogs = () => {
  const [logs, setLogs] = useState<AccessLog[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [total, setTotal] = useState(0);
  const [filters, setFilters] = useState<AccessLogQuery>({
    page: 1,
    limit: 20,
    sortBy: "createdAt",
    sortOrder: "DESC",
  });

  const fetchLogs = useCallback(
    async (newFilters?: AccessLogQuery) => {
      setLoading(true);
      setError(null);

      try {
        const currentFilters = newFilters || filters;
        const response: AccessLogsResponse = await accessLogsService.getLogs(
          currentFilters
        );
        setLogs(response.accessLogs || []);
        setTotal(response.count || 0);
      } catch (err) {
        setError((err as Error)?.message || "خطا در دریافت لاگ‌ها");
        setLogs([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    },
    [filters]
  );

  const updateFilters = useCallback(
    (newFilters: Partial<AccessLogQuery>) => {
      const updatedFilters = { ...filters, ...newFilters };
      if (newFilters.page === undefined && Object.keys(newFilters).length > 0) {
        updatedFilters.page = 1;
      }
      setFilters(updatedFilters);
    },
    [filters]
  );

  const resetFilters = useCallback(() => {
    setFilters({
      page: 1,
      limit: 20,
      sortBy: "createdAt",
      sortOrder: "DESC",
    });
  }, []);

  const exportLogs = useCallback(async () => {
    try {
      const blob = await accessLogsService.exportLogs(filters);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `access-logs-${new Date().toISOString().split("T")[0]}.csv`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    } catch (err) {
      setError((err as Error)?.message || "خطا در خروجی گرفتن از لاگ‌ها");
    }
  }, [filters]);

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

  return {
    logs,
    loading,
    error,
    total,
    filters,
    updateFilters,
    resetFilters,
    fetchLogs,
    exportLogs,
    refetch: () => fetchLogs(),
  };
};

export const useAccessLogStats = () => {
  const [stats, setStats] = useState<OperationStatsResponse | null>(null);
  const [topUsers, setTopUsers] = useState<TopUsersResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchStats = useCallback(
    async (filters: AccessLogStatsQueryDto = {}) => {
      setLoading(true);
      setError(null);

      try {
        const [statsResponse, topUsersResponse] = await Promise.all([
          accessLogsService.getStats(filters),
          accessLogsService.getTopUsers(filters),
        ]);

        setStats(statsResponse);
        setTopUsers(topUsersResponse);
      } catch (err) {
        setError((err as Error)?.message || "خطا در دریافت آمار");
      } finally {
        setLoading(false);
      }
    },
    []
  );

  return {
    stats,
    topUsers,
    loading,
    error,
    fetchStats,
  };
};

export const useAccessLogDetail = () => {
  const [log, setLog] = useState<AccessLog | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchLog = useCallback(async (id: string) => {
    setLoading(true);
    setError(null);

    try {
      const response = await accessLogsService.getLogById(id);
      setLog(response.accessLog);
    } catch (err) {
      setError((err as Error)?.message || "خطا در دریافت جزئیات لاگ");
      setLog(null);
    } finally {
      setLoading(false);
    }
  }, []);

  const clearLog = useCallback(() => {
    setLog(null);
    setError(null);
  }, []);

  return {
    log,
    loading,
    error,
    fetchLog,
    clearLog,
  };
};

export const useErrorLogs = () => {
  const [errorLogs, setErrorLogs] = useState<AccessLog[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [total, setTotal] = useState(0);
  const [filters, setFilters] = useState<AccessLogQuery>({
    page: 1,
    limit: 20,
    sortBy: "createdAt",
    sortOrder: "DESC",
  });

  const fetchErrorLogs = useCallback(
    async (newFilters?: AccessLogQuery) => {
      setLoading(true);
      setError(null);

      try {
        const currentFilters = newFilters || filters;
        const response: AccessLogsResponse = await accessLogsService.getErrorLogs(
          currentFilters
        );
        setErrorLogs(response.accessLogs || []);
        setTotal(response.count || 0);
      } catch (err) {
        setError((err as Error)?.message || "خطا در دریافت لاگ‌های خطا");
        setErrorLogs([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    },
    [filters]
  );

  const updateFilters = useCallback(
    (newFilters: Partial<AccessLogQuery>) => {
      const updatedFilters = { ...filters, ...newFilters };
      if (newFilters.page === undefined && Object.keys(newFilters).length > 0) {
        updatedFilters.page = 1;
      }
      setFilters(updatedFilters);
    },
    [filters]
  );

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

  return {
    errorLogs,
    loading,
    error,
    total,
    filters,
    updateFilters,
    fetchErrorLogs,
    refetch: () => fetchErrorLogs(),
  };
};
