import axios from "axios";
import { AuthDataSource } from "../../../domain/datasources/auth_datasource";
import { LoginInfoEntity } from "../../../domain/entities/login_info_entity";
import { RegisterInfoEntity } from "../../../domain/entities/register_info";
import { userRegisterEntityToUserRegisterModel } from "../utils/user_util";
import { API_URL } from "../../../../common/const/api";
import { LoginUserModel } from "../models/login_user_model";
import { RegisterResponseModel } from "../models/register_user_model";
import { ResetPasswordInfoEntity } from "../../../domain/entities/reset_password_entity";
import { ApiResponseError } from "../../../errors/api_response_error";

export class AuthDatasourceProd implements AuthDataSource {
  async verifyAccount(code: string): Promise<void> {
    try {
      const { status } = await axios.post(`${API_URL}/user/confirm-email`, {
        code,
      });

      if (status !== 201) {
        throw new Error("Error verifying account");
      }
    } catch (error: any) {
      if (axios.isAxiosError(error)) {
        throw new ApiResponseError(
          error.response!.status,
          error.response?.data.message
        );
      }
      throw new ApiResponseError(500, "Internal Server Error");
    }
  }
  async resendConfirmationCode(): Promise<void> {
    try {
      const { status } = await axios.post(
        `${API_URL}/user/resend-confirmation-code`
      );

      if (status !== 201) {
        throw new Error("Error resending confirmation code");
      }
    } catch (error: any) {
      if (axios.isAxiosError(error)) {
        throw new ApiResponseError(
          error.response!.status,
          error.response?.data.message
        );
      }
      throw new ApiResponseError(500, "Internal Server Error");
    }
  }
  async getResetCode(email: string): Promise<void> {
    const { status } = await axios.post(`${API_URL}/user/get-reset-code`, {
      email,
    });

    if (status !== 201) {
      throw new Error("Error fetching new reset code");
    }
  }
  async resetPassword(resetInfo: ResetPasswordInfoEntity): Promise<void> {
    const resetInfoModel = {
      email: resetInfo.email,
      resetCode: resetInfo.code,
      newPassword: resetInfo.newPassword,
    };

    const { status } = await axios.post(
      `${API_URL}/user/reset-password`,
      resetInfoModel
    );

    if (status !== 201) {
      throw new Error("Error reset Password");
    }
  }
  login: (email: string, password: string) => Promise<LoginInfoEntity> = async (
    email,
    password
  ) => {
    try {
      const loginInfo: LoginUserModel = {
        email,
        password,
      };
      //TODO: Hacer el login info model y el user info model cuando se termine la documentación
      const { data, status } = await axios.post<RegisterResponseModel>(
        `${API_URL}/user/signin`,
        loginInfo
      );
      const loginResponse: LoginInfoEntity = {
        token: data.user.token,
        user: {
          id: data.user.userId,
          email: data.user.email,
          name: data.user.name,
          lastName: data.user.lastName,
        },
      };
      return loginResponse;
    } catch (error: any) {
      if (axios.isAxiosError(error)) {
        throw new ApiResponseError(
          error.response!.status,
          error.response?.data.message
        );
      }
      throw new ApiResponseError(500, "Internal Server Error");
    }
  };

  register: (user: RegisterInfoEntity) => Promise<LoginInfoEntity> = async (
    user
  ) => {
    try {
      const newUser = userRegisterEntityToUserRegisterModel(user);
      const { data, status } = await axios.post<RegisterResponseModel>(
        `${API_URL}/user/signup`,
        newUser
      );

      const registeredUser: LoginInfoEntity = {
        token: data.user.token,
        user: {
          id: data.user.userId,
          email: data.user.email,
          name: data.user.name,
          lastName: data.user.lastName,
        },
      };
      return registeredUser;
    } catch (error: any) {
      if (axios.isAxiosError(error)) {
        throw new ApiResponseError(
          error.response!.status,
          error.response?.data.message
        );
      }
      throw new ApiResponseError(500, "Internal Server Error");
    }
  };
}
