// app/services/auth/authService.ts
import { createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

export const loginUser = createAsyncThunk(
  "auth/login",
  async (
    credentials: { email: string; password: string; language?: string },
    { rejectWithValue }
  ) => {
    try {
      const response = await axios.post(
        "/api/auth",
        {
          action: "login",
          email: credentials.email,
          password: credentials.password,
          language: credentials.language || "en",
        },
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );
      if (response.status == 200) {
        return {
          token: response.data.data.jwt,
          data: response.data.data,
        };
      } else {
        return rejectWithValue(response.data.error || "Login failed");
      }
    } catch (error: any) {
      return rejectWithValue(
        error.response?.data?.error ||
          error.response?.data?.message ||
          "Login failed"
      );
    }
  }
);

export const registerUser = createAsyncThunk(
  "auth/register",
  async (
    userData: {
      lang: string;
      name: string;
      username: string;
      email: string;
      password: string;
      phone: string;
      address: string;
      postal_code: string;
      country_id: number;
      state_id: number;
      city_id: number;
      role: number;
      community: string;
      organization: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(`${baseURL}/users`, userData, {
        headers: {
          "Content-Type": "application/json",
        },
      });

      if (response.data) {
        return {
          data: response.data,
          user: response.data,
          message: "Registration successful",
        };
      } else {
        return rejectWithValue("Registration failed");
      }
    } catch (error: any) {
      return rejectWithValue(
        error.response?.data?.message ||
          error.response?.data?.error ||
          "Registration failed"
      );
    }
  }
);
export const forgotPassword = createAsyncThunk(
  "auth/forgotPassword",
  async (emailData: { email: string }, { rejectWithValue }) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/forgot-password`,
        emailData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Password reset email sent successfully",
        };
      } else {
        return rejectWithValue("Password reset request failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Password reset request failed";
      return rejectWithValue(errorMessage);
    }
  }
);

export const verifyResetCode = createAsyncThunk(
  "auth/verifyResetCode",
  async (
    verificationData: {
      email: string;
      code: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/verify-reset-code`,
        verificationData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Verification code verified successfully",
        };
      } else {
        return rejectWithValue("Verification failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Verification failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const resetPasswordCode = createAsyncThunk(
  "auth/resetPasswordCode",
  async (
    resetData: {
      email: string;
      code: string;
      newPassword: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/reset-password-code`,
        resetData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Password reset successfully",
        };
      } else {
        return rejectWithValue("Password reset failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Password reset failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const verifyResetToken = createAsyncThunk(
  "auth/verifyResetToken",
  async (
    tokenData: {
      token: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/verify-reset-token`,
        tokenData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Token verified successfully",
        };
      } else {
        return rejectWithValue("Token verification failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Token verification failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const resetPasswordToken = createAsyncThunk(
  "auth/resetPasswordToken",
  async (
    resetData: {
      token: string;
      newPassword: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/reset-password-token`,
        resetData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Password reset successfully",
        };
      } else {
        return rejectWithValue("Password reset failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Password reset failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const checkPhone = createAsyncThunk(
  "auth/checkPhone",
  async (
    phoneData: {
      phone: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/check-phone`,
        phoneData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Phone check completed successfully",
        };
      } else {
        return rejectWithValue("Phone check failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Phone check failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const checkEmail = createAsyncThunk(
  "auth/checkEmail",
  async (
    emailData: {
      email: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/check-email`,
        emailData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Email check completed successfully",
        };
      } else {
        return rejectWithValue("Email check failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Email check failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const verifyEmailCode = createAsyncThunk(
  "auth/verifyEmailCode",
  async (
    verificationData: {
      code: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/verify-email-code`,
        verificationData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Email verification code validated successfully",
        };
      } else {
        return rejectWithValue("Email verification failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Email verification failed";
      return rejectWithValue(errorMessage);
    }
  }
);
export const verifyEmailToken = createAsyncThunk(
  "auth/verifyEmailToken",
  async (
    verificationData: {
      token: string;
    },
    { rejectWithValue }
  ) => {
    try {
      const baseURL = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await axios.post(
        `${baseURL}/users/verify-email-token`,
        verificationData,
        {
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (response.data) {
        return {
          data: response.data,
          message: "Email token verified successfully",
        };
      } else {
        return rejectWithValue("Email token verification failed");
      }
    } catch (error: any) {
      const errorMessage =
        error.response?.data?.message ||
        error.response?.data?.error ||
        "Email token verification failed";
      return rejectWithValue(errorMessage);
    }
  }
);

// Google/Microsoft OAuth callback handler
export const handleGoogleOAuthCallback = createAsyncThunk(
  "auth/googleOAuthCallback",
  async (
    authData: {
      jwt: string;
      user_id: number;
      name: string;
      date_of_birth?: string;
      christian_name?: string;
      sur_name?: string;
      person_to_contact?: string;
      phone?: string;
      organization?: string;
      email: string;
      username: string;
      community?: string;
      avtar_text?: string;
      photo?: string;
      accountStatus?: string;
      role?: number;
      promo_code?: string;
      stripe_coupon_id?: string;
      stripe_customer_id?: string;
      promo_code_assigned?: boolean;
      wallets?: Array<{
        id: number;
        balance: number;
        notes: string;
        expiry_date: Date;
        created_at: Date;
        updated_at: Date;
      }>;
    },
    { rejectWithValue }
  ) => {
    try {
      // Format the response to match the login response structure exactly
      return {
        token: authData.jwt,
        data: {
          jwt: authData.jwt,
          user_id: authData.user_id,
          name: authData.name,
          date_of_birth: authData.date_of_birth,
          christian_name: authData.christian_name,
          sur_name: authData.sur_name,
          person_to_contact: authData.person_to_contact,
          phone: authData.phone,
          organization: authData.organization,
          email: authData.email,
          username: authData.username,
          community: authData.community,
          avtar_text: authData.avtar_text,
          photo: authData.photo,
          accountStatus: authData.accountStatus,
          role: authData.role,
          promo_code: authData.promo_code,
          stripe_coupon_id: authData.stripe_coupon_id,
          stripe_customer_id: authData.stripe_customer_id,
          promo_code_assigned: authData.promo_code_assigned,
          wallets: authData.wallets,
        },
      };
    } catch (error: any) {
      return rejectWithValue(
        error.message || "Failed to process OAuth callback"
      );
    }
  }
);
