"use server"

import { cookies } from "next/headers"
import { api } from "@/lib/api"
import { ENDPOINTS } from "@/constants/endpoints"
import { API_CONFIG } from "@/lib/config"
import { resolveAdminRedirectPath } from "@/lib/auth/redirect"
import { ApiError } from "@/lib/errors"
import type { UserDTO, ApiResponse } from "@/types"
import i18n from "@/lib/i18n";

export interface LoginActionResult {
  success: boolean
  message: string
  requires_otp: boolean
  mustChangePassword?: boolean
  preAuthToken?: string
  user?: UserDTO
  redirectPath?: string
  accessToken?: string
}

export interface PersistAuthPayload {
  accessToken: string
  refreshToken: string
  tokenType: string
  sessionId: string
  user: UserDTO
}

function setAuthCookies(
  cookieStore: Awaited<ReturnType<typeof cookies>>,
  accessToken: string,
  refreshToken: string,
  tokenType: string,
  sessionId: string,
  user: UserDTO,
) {
  const sessionPayload = JSON.stringify({
    accessToken,
    refreshToken,
    tokenType,
    sessionId,
    user,
    issuedAt: new Date().toISOString(),
  })

  const encryptedPayload = Buffer.from(sessionPayload).toString("base64")

  const isProduction = process.env.NODE_ENV === "production"

  cookieStore.set("fastapi-session", encryptedPayload, {
    httpOnly: true,
    secure: isProduction,
    sameSite: "lax",
    path: "/",
  })

  cookieStore.set("auth_token", accessToken, {
    httpOnly: false,
    secure: isProduction,
    sameSite: "lax",
    path: "/",
    maxAge: 60 * 60 * 24 * 7,
  })

  const primaryRole = user.roles?.[0]
  const userData = JSON.stringify({
    id: user.id,
    name: user.email?.split("@")[0] || i18n.t('app.login.actions.text_1'),
    email: user.email || "",
    role: primaryRole?.code || user.user_type || "operations_admin",
    roles: user.roles || [],
    permissions: user.permissions || [],
    user_type: user.user_type,
    status: user.status,
  })
  cookieStore.set("auth_user", encodeURIComponent(userData), {
    httpOnly: false,
    secure: isProduction,
    sameSite: "lax",
    path: "/",
    maxAge: 60 * 60 * 24 * 7,
  })
}

export async function persistAuthAction(payload: PersistAuthPayload): Promise<LoginActionResult> {
  if (!payload.accessToken || !payload.refreshToken || !payload.sessionId || !payload.user?.id) {
    return {
      success: false,
      message: i18n.t('app.login.actions.text_12'),
      requires_otp: false,
    }
  }

  try {
    const cookieStore = await cookies()
    setAuthCookies(
      cookieStore,
      payload.accessToken,
      payload.refreshToken,
      payload.tokenType || "bearer",
      payload.sessionId,
      payload.user,
    )
    return {
      success: true,
      message: i18n.t('app.login.actions.text_10'),
      requires_otp: false,
      user: payload.user,
      accessToken: payload.accessToken,
      redirectPath: resolveAdminRedirectPath(payload.user),
    }
  } catch {
    return {
      success: false,
      message: i18n.t('app.login.actions.text_12'),
      requires_otp: false,
    }
  }
}

export async function loginStep1Action(username: string, password: string): Promise<LoginActionResult> {
  const provider = API_CONFIG.DATA_PROVIDER

  try {
    if (provider === "fastapi") {
      const response: ApiResponse<{ pre_auth_token: string; message: string; must_change_password?: boolean }> = await api.post(ENDPOINTS.AUTH.LOGIN_STEP1, {
        username,
        password,
      });

      if (!response.success || !response.data?.pre_auth_token) {
        return {
          success: false,
          message: response.message || i18n.t('app.login.actions.text_2'),
          requires_otp: false,
        }
      }

      return {
        success: true,
        message: response.data.message || i18n.t('app.login.actions.text_3'),
        requires_otp: !response.data.must_change_password,
        mustChangePassword: response.data.must_change_password || false,
        preAuthToken: response.data.pre_auth_token,
      }
    } else {
      const cookieStore = await cookies()
      cookieStore.set("mock-session", "true", {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        sameSite: "lax",
        path: "/",
      })

      return {
        success: true,
        message: i18n.t('app.login.actions.text_4'),
        requires_otp: false,
        redirectPath: "/",
      }
    }
  } catch (err: unknown) {
    console.error("[loginStep1Action] Error:", err)
    let message = i18n.t('app.login.actions.text_5')
    if (err instanceof ApiError) {
      if (err.status === 401) {
        message = i18n.t('app.login.actions.text_6')
      } else if (err.status === 429) {
        message = i18n.t('app.login.actions.text_7')
      } else {
        message = err.message || message
      }
    } else if (err instanceof Error) {
      message = err.message
    }
    return { success: false, message, requires_otp: false }
  }
}

export async function verifyOtpAction(preAuthToken: string, otpCode: string): Promise<LoginActionResult> {
  const provider = API_CONFIG.DATA_PROVIDER

  try {
    if (provider === "fastapi") {
      if (!preAuthToken || !otpCode) {
        return {
          success: false,
          message: i18n.t('app.login.actions.text_8'),
          requires_otp: true,
        }
      }

      const response: ApiResponse<{ access_token: string; refresh_token: string; token_type: string; session_id: string; user: UserDTO }> = await api.post(ENDPOINTS.AUTH.LOGIN_VERIFY_OTP, {
        pre_auth_token: preAuthToken,
        otp_code: otpCode,
      });

      if (!response.success || !response.data?.access_token) {
        return {
          success: false,
          message: response.message || i18n.t('app.login.actions.text_9'),
          requires_otp: true,
        }
      }

      const cookieStore = await cookies()
      setAuthCookies(cookieStore, response.data.access_token, response.data.refresh_token, response.data.token_type, response.data.session_id, response.data.user)

      const redirectPath = response.data.user?.email === "admin@goldwallet.com"
        ? "/"
        : resolveAdminRedirectPath(response.data.user)

      return {
        success: true,
        message: i18n.t('app.login.actions.text_10'),
        requires_otp: false,
        user: response.data.user,
        redirectPath: redirectPath,
        accessToken: response.data.access_token,
      }
    } else {
      const cookieStore = await cookies()
      cookieStore.set("mock-session", "true", {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        sameSite: "lax",
        path: "/",
      })

      return {
        success: true,
        message: i18n.t('app.login.actions.text_11'),
        requires_otp: false,
        redirectPath: "/",
      }
    }
  } catch (err: unknown) {
    console.error("[verifyOtpAction] Error:", err)
    let message = i18n.t('app.login.actions.text_12')
    if (err instanceof ApiError) {
      if (err.status === 401) {
        message = i18n.t('app.login.actions.text_13')
      } else if (err.status === 410) {
        message = i18n.t('app.login.actions.text_14')
      } else if (err.status === 429) {
        message = i18n.t('app.login.actions.text_15')
      } else {
        message = err.message || message
      }
    } else if (err instanceof Error) {
      message = err.message
    }
    return { success: false, message, requires_otp: true }
  }
}

export async function changeTempPasswordAction(preAuthToken: string, newPassword: string): Promise<LoginActionResult> {
  const provider = API_CONFIG.DATA_PROVIDER

  try {
    if (provider === "fastapi") {
      if (!preAuthToken || !newPassword) {
        return {
          success: false,
          message: i18n.t('app.login.actions.text_16'),
          requires_otp: false,
          mustChangePassword: true,
        }
      }

      const response: ApiResponse<{ access_token: string; refresh_token: string; token_type: string; session_id: string; user: UserDTO }> = await api.post(ENDPOINTS.AUTH.CHANGE_TEMP_PASSWORD || 'auth/change-temp-password', {
        pre_auth_token: preAuthToken,
        new_password: newPassword,
      });

      if (!response.success || !response.data?.access_token) {
        return {
          success: false,
          message: response.message || i18n.t('app.login.actions.text_17'),
          requires_otp: false,
          mustChangePassword: true,
        }
      }

      const cookieStore = await cookies()
      setAuthCookies(cookieStore, response.data.access_token, response.data.refresh_token, response.data.token_type || "bearer", response.data.session_id, response.data.user)

      const redirectPath = response.data.user?.email === "admin@goldwallet.com"
        ? "/"
        : resolveAdminRedirectPath(response.data.user)

      return {
        success: true,
        message: i18n.t('app.login.actions.text_18'),
        requires_otp: false,
        mustChangePassword: false,
        user: response.data.user,
        redirectPath: redirectPath,
        accessToken: response.data.access_token,
      }
    } else {
      const cookieStore = await cookies()
      cookieStore.set("mock-session", "true", {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        sameSite: "lax",
        path: "/",
      })

      return {
        success: true,
        message: i18n.t('app.login.actions.text_19'),
        requires_otp: false,
        redirectPath: "/",
      }
    }
  } catch (err: unknown) {
    console.error("[changeTempPasswordAction] Error:", err)
    let message = i18n.t('app.login.actions.text_20')
    if (err instanceof ApiError) {
      if (err.status === 401) {
        message = i18n.t('app.login.actions.text_21')
      } else if (err.status === 400) {
        message = err.message || i18n.t('app.login.actions.text_22')
      } else {
        message = err.message || message
      }
    } else if (err instanceof Error) {
      message = err.message
    }
    return { success: false, message, requires_otp: false, mustChangePassword: true }
  }
}
