/**
 * @ai-summary API client functions for admin feature
 * @ai-context Communicates with backend admin endpoints
 */

import { apiClient } from '../../../core/api/client';
import {
  AdminAccessResponse,
  AdminUser,
  CreateAdminRequest,
  AdminAuditLog,
  CatalogMake,
  CatalogModel,
  CatalogYear,
  CatalogTrim,
  CatalogEngine,
  CreateCatalogMakeRequest,
  UpdateCatalogMakeRequest,
  CreateCatalogModelRequest,
  UpdateCatalogModelRequest,
  CreateCatalogYearRequest,
  UpdateCatalogYearRequest,
  CreateCatalogTrimRequest,
  UpdateCatalogTrimRequest,
  CreateCatalogEngineRequest,
  UpdateCatalogEngineRequest,
  CatalogSearchResponse,
  ImportPreviewResult,
  ImportApplyResult,
  CascadeDeleteResult,
  EmailTemplate,
  UpdateEmailTemplateRequest,
  PreviewTemplateResponse,
  // User management types
  ManagedUser,
  ListUsersResponse,
  ListUsersParams,
  UpdateUserTierRequest,
  DeactivateUserRequest,
  UpdateUserProfileRequest,
  PromoteToAdminRequest,
  // Backup types
  BackupHistory,
  BackupSchedule,
  BackupSettings,
  ListBackupsResponse,
  CreateBackupRequest,
  CreateScheduleRequest,
  UpdateScheduleRequest,
  RestorePreviewResponse,
  ExecuteRestoreRequest,
  // Unified Audit Log types
  UnifiedAuditLogsResponse,
  AuditLogFilters,
} from '../types/admin.types';

export interface AuditLogsResponse {
  logs: AdminAuditLog[];
  total: number;
}

// Admin stats response
export interface AdminStatsResponse {
  totalVehicles: number;
  totalUsers: number;
}

// User vehicle (admin view)
export interface AdminUserVehicle {
  year: number;
  make: string;
  model: string;
}

export interface AdminUserVehiclesResponse {
  vehicles: AdminUserVehicle[];
}

// Admin access verification
export const adminApi = {
  // Verify admin access
  verifyAccess: async (): Promise<AdminAccessResponse> => {
    const response = await apiClient.get<AdminAccessResponse>('/admin/verify');
    return response.data;
  },

  // Admin dashboard stats
  getStats: async (): Promise<AdminStatsResponse> => {
    const response = await apiClient.get<AdminStatsResponse>('/admin/stats');
    return response.data;
  },

  // Admin management
  listAdmins: async (): Promise<AdminUser[]> => {
    const response = await apiClient.get<AdminUser[]>('/admin/admins');
    return response.data;
  },

  createAdmin: async (data: CreateAdminRequest): Promise<AdminUser> => {
    const response = await apiClient.post<AdminUser>('/admin/admins', data);
    return response.data;
  },

  revokeAdmin: async (auth0Sub: string): Promise<void> => {
    await apiClient.patch(`/admin/admins/${auth0Sub}/revoke`);
  },

  reinstateAdmin: async (auth0Sub: string): Promise<void> => {
    await apiClient.patch(`/admin/admins/${auth0Sub}/reinstate`);
  },

  // Audit logs
  listAuditLogs: async (): Promise<AuditLogsResponse> => {
    const response = await apiClient.get<AuditLogsResponse>('/admin/audit-logs');
    return response.data;
  },

  // Catalog - Makes
  listMakes: async (): Promise<CatalogMake[]> => {
    const response = await apiClient.get<{ makes: CatalogMake[] }>('/admin/catalog/makes');
    return response.data.makes;
  },

  createMake: async (data: CreateCatalogMakeRequest): Promise<CatalogMake> => {
    const response = await apiClient.post<CatalogMake>('/admin/catalog/makes', data);
    return response.data;
  },

  updateMake: async (id: string, data: UpdateCatalogMakeRequest): Promise<CatalogMake> => {
    const response = await apiClient.put<CatalogMake>(`/admin/catalog/makes/${id}`, data);
    return response.data;
  },

  deleteMake: async (id: string): Promise<void> => {
    await apiClient.delete(`/admin/catalog/makes/${id}`);
  },

  // Catalog - Models
  listModels: async (makeId: string): Promise<CatalogModel[]> => {
    const response = await apiClient.get<{ models: CatalogModel[] }>(
      `/admin/catalog/makes/${makeId}/models`
    );
    return response.data.models;
  },

  createModel: async (data: CreateCatalogModelRequest): Promise<CatalogModel> => {
    const response = await apiClient.post<CatalogModel>('/admin/catalog/models', data);
    return response.data;
  },

  updateModel: async (id: string, data: UpdateCatalogModelRequest): Promise<CatalogModel> => {
    const response = await apiClient.put<CatalogModel>(`/admin/catalog/models/${id}`, data);
    return response.data;
  },

  deleteModel: async (id: string): Promise<void> => {
    await apiClient.delete(`/admin/catalog/models/${id}`);
  },

  // Catalog - Years
  listYears: async (modelId: string): Promise<CatalogYear[]> => {
    const response = await apiClient.get<{ years: CatalogYear[] }>(
      `/admin/catalog/models/${modelId}/years`
    );
    return response.data.years;
  },

  createYear: async (data: CreateCatalogYearRequest): Promise<CatalogYear> => {
    const response = await apiClient.post<CatalogYear>('/admin/catalog/years', data);
    return response.data;
  },

  updateYear: async (id: string, data: UpdateCatalogYearRequest): Promise<CatalogYear> => {
    const response = await apiClient.put<CatalogYear>(`/admin/catalog/years/${id}`, data);
    return response.data;
  },

  deleteYear: async (id: string): Promise<void> => {
    await apiClient.delete(`/admin/catalog/years/${id}`);
  },

  // Catalog - Trims
  listTrims: async (yearId: string): Promise<CatalogTrim[]> => {
    const response = await apiClient.get<{ trims: CatalogTrim[] }>(
      `/admin/catalog/years/${yearId}/trims`
    );
    return response.data.trims;
  },

  createTrim: async (data: CreateCatalogTrimRequest): Promise<CatalogTrim> => {
    const response = await apiClient.post<CatalogTrim>('/admin/catalog/trims', data);
    return response.data;
  },

  updateTrim: async (id: string, data: UpdateCatalogTrimRequest): Promise<CatalogTrim> => {
    const response = await apiClient.put<CatalogTrim>(`/admin/catalog/trims/${id}`, data);
    return response.data;
  },

  deleteTrim: async (id: string): Promise<void> => {
    await apiClient.delete(`/admin/catalog/trims/${id}`);
  },

  // Catalog - Engines
  listEngines: async (trimId: string): Promise<CatalogEngine[]> => {
    const response = await apiClient.get<{ engines: CatalogEngine[] }>(
      `/admin/catalog/trims/${trimId}/engines`
    );
    return response.data.engines;
  },

  createEngine: async (data: CreateCatalogEngineRequest): Promise<CatalogEngine> => {
    const response = await apiClient.post<CatalogEngine>('/admin/catalog/engines', data);
    return response.data;
  },

  updateEngine: async (id: string, data: UpdateCatalogEngineRequest): Promise<CatalogEngine> => {
    const response = await apiClient.put<CatalogEngine>(`/admin/catalog/engines/${id}`, data);
    return response.data;
  },

  deleteEngine: async (id: string): Promise<void> => {
    await apiClient.delete(`/admin/catalog/engines/${id}`);
  },

  // Catalog Search
  searchCatalog: async (
    query: string,
    page: number = 1,
    pageSize: number = 50
  ): Promise<CatalogSearchResponse> => {
    const response = await apiClient.get<CatalogSearchResponse>('/admin/catalog/search', {
      params: { q: query, page, pageSize },
    });
    return response.data;
  },

  // Catalog Import/Export
  importPreview: async (file: File): Promise<ImportPreviewResult> => {
    const formData = new FormData();
    formData.append('file', file);
    const response = await apiClient.post<ImportPreviewResult>(
      '/admin/catalog/import/preview',
      formData,
      {
        headers: { 'Content-Type': 'multipart/form-data' },
      }
    );
    return response.data;
  },

  importApply: async (previewId: string): Promise<ImportApplyResult> => {
    const response = await apiClient.post<ImportApplyResult>('/admin/catalog/import/apply', {
      previewId,
    });
    return response.data;
  },

  exportCatalog: async (): Promise<Blob> => {
    const response = await apiClient.get('/admin/catalog/export', {
      responseType: 'blob',
    });
    return response.data;
  },

  // Cascade Delete
  deleteMakeCascade: async (id: string): Promise<CascadeDeleteResult> => {
    const response = await apiClient.delete<CascadeDeleteResult>(
      `/admin/catalog/makes/${id}/cascade`
    );
    return response.data;
  },

  deleteModelCascade: async (id: string): Promise<CascadeDeleteResult> => {
    const response = await apiClient.delete<CascadeDeleteResult>(
      `/admin/catalog/models/${id}/cascade`
    );
    return response.data;
  },

  deleteYearCascade: async (id: string): Promise<CascadeDeleteResult> => {
    const response = await apiClient.delete<CascadeDeleteResult>(
      `/admin/catalog/years/${id}/cascade`
    );
    return response.data;
  },

  deleteTrimCascade: async (id: string): Promise<CascadeDeleteResult> => {
    const response = await apiClient.delete<CascadeDeleteResult>(
      `/admin/catalog/trims/${id}/cascade`
    );
    return response.data;
  },

  // Email Templates
  emailTemplates: {
    list: async (): Promise<EmailTemplate[]> => {
      const response = await apiClient.get<EmailTemplate[]>('/admin/email-templates');
      return response.data;
    },
    get: async (key: string): Promise<EmailTemplate> => {
      const response = await apiClient.get<EmailTemplate>(`/admin/email-templates/${key}`);
      return response.data;
    },
    update: async (key: string, data: UpdateEmailTemplateRequest): Promise<EmailTemplate> => {
      const response = await apiClient.put<EmailTemplate>(`/admin/email-templates/${key}`, data);
      return response.data;
    },
    preview: async (key: string, variables: Record<string, string>): Promise<PreviewTemplateResponse> => {
      const response = await apiClient.post<PreviewTemplateResponse>(
        `/admin/email-templates/${key}/preview`,
        { variables }
      );
      return response.data;
    },
    sendTest: async (key: string): Promise<{ message?: string; error?: string }> => {
      const response = await apiClient.post<{ message?: string; error?: string }>(
        `/admin/email-templates/${key}/test`
      );
      return response.data;
    },
  },

  // User Management
  users: {
    list: async (params: ListUsersParams = {}): Promise<ListUsersResponse> => {
      const response = await apiClient.get<ListUsersResponse>('/admin/users', { params });
      return response.data;
    },

    get: async (auth0Sub: string): Promise<ManagedUser> => {
      const response = await apiClient.get<ManagedUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}`
      );
      return response.data;
    },

    getVehicles: async (auth0Sub: string): Promise<AdminUserVehiclesResponse> => {
      const response = await apiClient.get<AdminUserVehiclesResponse>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/vehicles`
      );
      return response.data;
    },

    updateTier: async (auth0Sub: string, data: UpdateUserTierRequest): Promise<ManagedUser> => {
      const response = await apiClient.patch<ManagedUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/tier`,
        data
      );
      return response.data;
    },

    deactivate: async (auth0Sub: string, data?: DeactivateUserRequest): Promise<ManagedUser> => {
      const response = await apiClient.patch<ManagedUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/deactivate`,
        data || {}
      );
      return response.data;
    },

    reactivate: async (auth0Sub: string): Promise<ManagedUser> => {
      const response = await apiClient.patch<ManagedUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/reactivate`
      );
      return response.data;
    },

    updateProfile: async (auth0Sub: string, data: UpdateUserProfileRequest): Promise<ManagedUser> => {
      const response = await apiClient.patch<ManagedUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/profile`,
        data
      );
      return response.data;
    },

    promoteToAdmin: async (auth0Sub: string, data?: PromoteToAdminRequest): Promise<AdminUser> => {
      const response = await apiClient.patch<AdminUser>(
        `/admin/users/${encodeURIComponent(auth0Sub)}/promote`,
        data || {}
      );
      return response.data;
    },

    hardDelete: async (auth0Sub: string, reason?: string): Promise<{ message: string }> => {
      const response = await apiClient.delete<{ message: string }>(
        `/admin/users/${encodeURIComponent(auth0Sub)}`,
        { params: reason ? { reason } : undefined }
      );
      return response.data;
    },
  },

  // Backup & Restore
  backups: {
    // List backups with pagination
    list: async (params: { page?: number; pageSize?: number } = {}): Promise<ListBackupsResponse> => {
      const response = await apiClient.get<ListBackupsResponse>('/admin/backups', { params });
      return response.data;
    },

    // Get backup details
    get: async (id: string): Promise<BackupHistory> => {
      const response = await apiClient.get<BackupHistory>(`/admin/backups/${id}`);
      return response.data;
    },

    // Create manual backup
    create: async (data: CreateBackupRequest = {}): Promise<BackupHistory> => {
      const response = await apiClient.post<BackupHistory>('/admin/backups', data);
      return response.data;
    },

    // Download backup file
    download: async (id: string): Promise<Blob> => {
      const response = await apiClient.get(`/admin/backups/${id}/download`, {
        responseType: 'blob',
      });
      return response.data;
    },

    // Delete backup
    delete: async (id: string): Promise<void> => {
      await apiClient.delete(`/admin/backups/${id}`);
    },

    // Upload backup file
    upload: async (file: File): Promise<BackupHistory> => {
      const formData = new FormData();
      formData.append('file', file);
      const response = await apiClient.post<BackupHistory>('/admin/backups/upload', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      return response.data;
    },

    // Preview restore
    previewRestore: async (id: string): Promise<RestorePreviewResponse> => {
      const response = await apiClient.post<RestorePreviewResponse>(
        `/admin/backups/${id}/restore/preview`
      );
      return response.data;
    },

    // Execute restore (longer timeout since this is a long-running operation)
    restore: async (id: string, options?: ExecuteRestoreRequest): Promise<{ message: string }> => {
      try {
        const response = await apiClient.post<{ message: string }>(
          `/admin/backups/${id}/restore`,
          options,
          { timeout: 120000 } // 2 minute timeout for restore operations
        );
        return response.data;
      } catch (error: any) {
        // If a restore is already in progress, treat it as success since it will complete
        const errorMessage = error?.response?.data?.error || error?.message || '';
        if (errorMessage.includes('already in progress')) {
          return { message: 'Restore is in progress and will complete shortly' };
        }
        throw error;
      }
    },

    // Schedules
    schedules: {
      list: async (): Promise<BackupSchedule[]> => {
        const response = await apiClient.get<BackupSchedule[]>('/admin/backups/schedules');
        return response.data;
      },

      get: async (id: string): Promise<BackupSchedule> => {
        const response = await apiClient.get<BackupSchedule>(`/admin/backups/schedules/${id}`);
        return response.data;
      },

      create: async (data: CreateScheduleRequest): Promise<BackupSchedule> => {
        const response = await apiClient.post<BackupSchedule>('/admin/backups/schedules', data);
        return response.data;
      },

      update: async (id: string, data: UpdateScheduleRequest): Promise<BackupSchedule> => {
        const response = await apiClient.put<BackupSchedule>(
          `/admin/backups/schedules/${id}`,
          data
        );
        return response.data;
      },

      delete: async (id: string): Promise<void> => {
        await apiClient.delete(`/admin/backups/schedules/${id}`);
      },

      toggle: async (id: string): Promise<BackupSchedule> => {
        const response = await apiClient.patch<BackupSchedule>(
          `/admin/backups/schedules/${id}/toggle`
        );
        return response.data;
      },
    },

    // Settings
    settings: {
      get: async (): Promise<BackupSettings> => {
        const response = await apiClient.get<BackupSettings>('/admin/backups/settings');
        return response.data;
      },

      update: async (data: Partial<BackupSettings>): Promise<BackupSettings> => {
        const response = await apiClient.put<BackupSettings>('/admin/backups/settings', data);
        return response.data;
      },
    },
  },

  // Unified Audit Logs (new centralized audit system)
  unifiedAuditLogs: {
    list: async (filters: AuditLogFilters = {}): Promise<UnifiedAuditLogsResponse> => {
      const params: Record<string, string | number> = {};
      if (filters.search) params.search = filters.search;
      if (filters.category) params.category = filters.category;
      if (filters.severity) params.severity = filters.severity;
      if (filters.startDate) params.startDate = filters.startDate;
      if (filters.endDate) params.endDate = filters.endDate;
      if (filters.limit) params.limit = filters.limit;
      if (filters.offset) params.offset = filters.offset;

      const response = await apiClient.get<UnifiedAuditLogsResponse>('/admin/audit-logs', { params });
      return response.data;
    },

    export: async (filters: AuditLogFilters = {}): Promise<Blob> => {
      const params: Record<string, string | number> = {};
      if (filters.search) params.search = filters.search;
      if (filters.category) params.category = filters.category;
      if (filters.severity) params.severity = filters.severity;
      if (filters.startDate) params.startDate = filters.startDate;
      if (filters.endDate) params.endDate = filters.endDate;

      const response = await apiClient.get('/admin/audit-logs/export', {
        params,
        responseType: 'blob',
      });
      return response.data;
    },
  },
};
