import axios from "../../../config/axios";
import {
  AccessLog,
  AccessLogQuery,
  AccessLogStatsQueryDto,
  EntityIdQueryDto,
  AccessLogsResponse,
  OperationStatsResponse,
  TopUsersResponse,
} from "../types/AccessLogTypes";

type QueryParams = Record<string, string | number | boolean | undefined | null>;

class AccessLogsService {
  private baseUrl = "/access-logs";

  private buildQueryParams(params: QueryParams): URLSearchParams {
    const queryParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null && value !== "") {
        queryParams.append(key, value.toString());
      }
    });
    return queryParams;
  }

  // Get all access logs with filtering
  async getLogs(filters: AccessLogQuery = {}): Promise<AccessLogsResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(`${this.baseUrl}?${params}`);
    // Handle both response structures
    if (response.data.data) {
      return {
        accessLogs: response.data.data.accessLogs,
        count: response.data.data.pager.totalItems,
        paginate: true,
        data: response.data.data,
      };
    }
    return response.data;
  }

  // Get operation statistics
  async getStats(
    filters: AccessLogStatsQueryDto = {}
  ): Promise<OperationStatsResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(`${this.baseUrl}/stats?${params}`);
    return response.data;
  }

  // Get top users by activity
  async getTopUsers(
    filters: AccessLogStatsQueryDto = {}
  ): Promise<TopUsersResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(`${this.baseUrl}/top-users?${params}`);
    return response.data;
  }

  // Get error logs only
  async getErrorLogs(
    filters: AccessLogQuery = {}
  ): Promise<AccessLogsResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(`${this.baseUrl}/errors?${params}`);
    // Handle both response structures
    if (response.data.data) {
      return {
        accessLogs: response.data.data.accessLogs,
        count: response.data.data.pager.totalItems,
        paginate: true,
        data: response.data.data,
      };
    }
    return response.data;
  }

  // Get specific log by ID
  async getLogById(id: string): Promise<{ accessLog: AccessLog }> {
    const response = await axios.get(`${this.baseUrl}/${id}`);

    // Handle the nested data structure
    if (response.data.data && response.data.data.accessLog) {
      return {
        accessLog: response.data.data.accessLog,
      };
    }

    return response.data;
  }

  // Get logs for specific user
  async getUserLogs(
    userId: string,
    filters: AccessLogQuery = {}
  ): Promise<AccessLogsResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(
      `${this.baseUrl}/user/${userId}?${params}`
    );
    return response.data;
  }

  // Get logs for specific entity
  async getEntityLogs(
    entityName: string,
    filters: EntityIdQueryDto = {}
  ): Promise<AccessLogsResponse> {
    const params = this.buildQueryParams(filters as QueryParams);
    const response = await axios.get(
      `${this.baseUrl}/entity/${entityName}?${params}`
    );
    return response.data;
  }

  // Export logs to CSV
  async exportLogs(filters: AccessLogQuery = {}): Promise<Blob> {
    const params = this.buildQueryParams({
      ...filters,
      format: "csv",
    } as QueryParams);
    const response = await axios.get(`${this.baseUrl}/export?${params}`, {
      responseType: "blob",
    });
    return response.data;
  }

  // Get logs count for dashboard
  async getLogsCount(filters: AccessLogQuery = {}): Promise<{ count: number }> {
    const params = this.buildQueryParams({
      ...filters,
      countOnly: true,
    } as QueryParams);
    const response = await axios.get(`${this.baseUrl}/count?${params}`);
    return response.data;
  }

  // Get recent logs (for real-time updates)
  async getRecentLogs(lastId?: string): Promise<AccessLogsResponse> {
    const params = new URLSearchParams();
    if (lastId) params.append("after", lastId);
    params.append("limit", "20");
    params.append("sortBy", "createdAt");
    params.append("sortOrder", "DESC");

    const response = await axios.get(`${this.baseUrl}?${params}`);
    return response.data;
  }
}

export const accessLogsService = new AccessLogsService();
