import api from "../axios";
import { extractFileId } from "../config";
import { API_ENDPOINTS } from "../endpoints";
import { fileService } from "./file-service";
import {
  ApiResponse,
  IAdminListResponse,
  ICreateAdminCredentials,
  ILoginCredentials,
  ILoginResponse,
  ILogoutResponse,
  LoginResponseSchema,
  LogoutResponseSchema,
  TChangeAdminStatusCredentials,
  TResetPasswordResponse,
} from "../types";

export const userService = {
  login: async (
    credentials: ILoginCredentials,
  ): Promise<ApiResponse<ILoginResponse>> => {
    try {
      const response = await api.post(API_ENDPOINTS.USER.LOGIN, credentials);

      const result = LoginResponseSchema.safeParse(response.data);
      if (!result.success) {
        throw new Error(result.error.message);
      }
      return result.data;
    } catch (error) {
      console.error("ERROR caught in User Service Login:", error);
      throw error;
    }
  },
  logout: async (): Promise<ApiResponse<ILogoutResponse>> => {
    try {
      const response = await api.delete(API_ENDPOINTS.USER.LOGOUT);
      return LogoutResponseSchema.parse(response.data);
    } catch (error) {
      console.error("ERROR caught in User Service Logout", error);
      throw error;
    }
  },
  adminsList: async (
    params?: Record<string, any>,
  ): Promise<ApiResponse<IAdminListResponse>> => {
    try {
      const response = await api.get(API_ENDPOINTS.USER.ADMINS, { params });
      return response.data;
    } catch (error) {
      console.error("ERROR caught in User Service User List", error);
      throw error;
    }
  },
  createAdmin: async (credentials: ICreateAdminCredentials) => {
    try {
      return (await api.post(API_ENDPOINTS.USER.ADMINS, credentials)).data
        .message;
    } catch (error) {
      console.error("ERROR caught in User Service Create Admin", error);
      throw error;
    }
  },
  updateAdmin: async ({
    id,
    credentials,
  }: {
    id: string;
    credentials: ICreateAdminCredentials;
  }) => {
    try {
      return (await api.put(API_ENDPOINTS.USER.ADMIN_DETAILS(id), credentials))
        .data.message;
    } catch (error) {
      console.error("ERROR caught in User Service Update Admin", error);
      throw error;
    }
  },

  adminDetails: async (id: string) => {
    try {
      return (await api.get(API_ENDPOINTS.USER.ADMIN_DETAILS(id))).data;
    } catch (error) {
      console.error("ERROR caught in User Service Admin Details", error);
      throw error;
    }
  },
  deleteAdmin: async (
    id: string,
  ): Promise<ApiResponse<{ message: string }>> => {
    try {
      return await api.delete(`${API_ENDPOINTS.USER.ADMINS}/${id}`);
    } catch (error) {
      console.error("ERROR caught in User Service Delete Admin", error);
      throw error;
    }
  },
  resetAdminPassword: async (
    id: string,
  ): Promise<ApiResponse<TResetPasswordResponse>> => {
    try {
      return (await api.post(API_ENDPOINTS.USER.RESET_ADMIN_PASSWORD(id))).data;
    } catch (error) {
      console.error("ERROR caught in User Service Reset Admin Password", error);
      throw error;
    }
  },
  changeAdminStatus: async ({
    id,
    credentials,
  }: {
    id: string;
    credentials: TChangeAdminStatusCredentials;
  }) => {
    try {
      return (
        await api.put(API_ENDPOINTS.USER.CHANGE_ADMIN_STATUS(id), credentials)
      ).data;
    } catch (error) {
      console.error("ERROR Caught in user service => change status", error);
      throw error;
    }
  },
  uploadProfileImage: async ({
    file,
    onProgress,
  }: {
    file: File;
    onProgress?: (percent: number) => void;
  }) => {
    try {
      // Persisted on the backend as the profile image, so it must be an
      // absolute, directly-loadable URL — not the frontend `/api/proxy` path.
      return fileService.uploadFile({
        file,
        category: "profile_images",
        tags: ["user", "profile"],
        description: "Admin profile image",
        onProgress,
      });
    } catch (error) {
      console.error("ERROR caught in User Service Upload Profile Image", error);
      throw error;
    }
  },
  /**
   * Fetch an auth-protected file download through the proxy (so the axios
   * interceptor attaches the bearer token) and return a local object URL that
   * can be used directly as an `<img>` source.
   */
  fetchFileObjectUrl: async (url: string): Promise<string> => {
    try {
      const fileId = extractFileId(url);
      // Route via the relative proxy endpoint when this is a backend file URL;
      // otherwise fetch the URL as-is.
      const path = fileId ? API_ENDPOINTS.FILES.DOWNLOAD(fileId) : url;
      const response = await api.get(path, { responseType: "blob" });
      return URL.createObjectURL(response.data as Blob);
    } catch (error) {
      console.error("ERROR caught in User Service Fetch File Object Url", error);
      throw error;
    }
  },
};
