'use server'

import { revalidatePath } from 'next/cache'
import bcrypt from 'bcrypt'
import { signIn, signOut } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import {
  loginSchema,
  registerSchema,
  updatePasswordSchema,
  updateProfileSchema
} from '@/lib/validations/auth'
import type { ActionResult } from '@/types'
import { auth } from '@/lib/auth'

/**
 * Register a new user
 */
export async function register(
  email: string,
  password: string,
  name: string
): Promise<ActionResult<{ userId: string }>> {
  try {
    // Validate input
    const validatedData = registerSchema.parse({ email, password, name })

    // Check if user already exists
    const existingUser = await prisma.user.findUnique({
      where: { email: validatedData.email },
    })

    if (existingUser) {
      return {
        success: false,
        message: 'A user with this email already exists',
      }
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(validatedData.password, 10)

    // Get default language (English)
    const defaultLanguage = await prisma.language.findUnique({
      where: { code: 'en' },
    })

    if (!defaultLanguage) {
      return {
        success: false,
        message: 'System configuration error: default language not found',
      }
    }

    // Create user with preferences
    const user = await prisma.user.create({
      data: {
        email: validatedData.email,
        password: hashedPassword,
        name: validatedData.name,
        role: 'USER',
        isActive: true,
        preference: {
          create: {
            preferredLanguageId: defaultLanguage.id,
            characterDisplay: 'SIMPLIFIED',
            transcriptionType: 'pinyin',
            cardsPerSession: 20,
            dailyGoal: 50,
            removalThreshold: 10,
            allowManualDifficulty: true,
          },
        },
      },
    })

    revalidatePath('/')

    return {
      success: true,
      data: { userId: user.id },
      message: 'Account created successfully',
    }
  } catch (error: any) {
    if (error.name === 'ZodError') {
      return {
        success: false,
        message: 'Validation failed',
        errors: error.flatten().fieldErrors,
      }
    }

    console.error('Registration error:', error)
    return {
      success: false,
      message: 'An error occurred during registration',
    }
  }
}

/**
 * Login with email and password
 */
export async function login(
  email: string,
  password: string
): Promise<ActionResult> {
  try {
    // Validate input
    const validatedData = loginSchema.parse({ email, password })

    // Attempt sign in with NextAuth
    const result = await signIn('credentials', {
      email: validatedData.email,
      password: validatedData.password,
      redirect: false,
    })

    if (result?.error) {
      return {
        success: false,
        message: 'Invalid email or password',
      }
    }

    revalidatePath('/')

    return {
      success: true,
      message: 'Logged in successfully',
    }
  } catch (error: any) {
    if (error.name === 'ZodError') {
      return {
        success: false,
        message: 'Validation failed',
        errors: error.flatten().fieldErrors,
      }
    }

    console.error('Login error:', error)
    return {
      success: false,
      message: 'An error occurred during login',
    }
  }
}

/**
 * Logout current user
 */
export async function logout(): Promise<ActionResult> {
  try {
    await signOut({ redirect: false })
    revalidatePath('/')

    return {
      success: true,
      message: 'Logged out successfully',
    }
  } catch (error) {
    console.error('Logout error:', error)
    return {
      success: false,
      message: 'An error occurred during logout',
    }
  }
}

/**
 * Update user password
 */
export async function updatePassword(
  currentPassword: string,
  newPassword: string
): Promise<ActionResult> {
  try {
    // Get current user session
    const session = await auth()
    if (!session?.user) {
      return {
        success: false,
        message: 'You must be logged in to change your password',
      }
    }

    // Validate input
    const validatedData = updatePasswordSchema.parse({
      currentPassword,
      newPassword,
    })

    // Get user from database
    const user = await prisma.user.findUnique({
      where: { id: (session.user as any).id },
    })

    if (!user) {
      return {
        success: false,
        message: 'User not found',
      }
    }

    // Verify current password
    const isPasswordValid = await bcrypt.compare(
      validatedData.currentPassword,
      user.password
    )

    if (!isPasswordValid) {
      return {
        success: false,
        message: 'Current password is incorrect',
      }
    }

    // Hash new password
    const hashedPassword = await bcrypt.hash(validatedData.newPassword, 10)

    // Update password
    await prisma.user.update({
      where: { id: user.id },
      data: { password: hashedPassword },
    })

    revalidatePath('/settings')

    return {
      success: true,
      message: 'Password updated successfully',
    }
  } catch (error: any) {
    if (error.name === 'ZodError') {
      return {
        success: false,
        message: 'Validation failed',
        errors: error.flatten().fieldErrors,
      }
    }

    console.error('Update password error:', error)
    return {
      success: false,
      message: 'An error occurred while updating your password',
    }
  }
}

/**
 * Update user profile
 */
export async function updateProfile(
  name?: string,
  email?: string
): Promise<ActionResult> {
  try {
    // Get current user session
    const session = await auth()
    if (!session?.user) {
      return {
        success: false,
        message: 'You must be logged in to update your profile',
      }
    }

    // Validate input
    const validatedData = updateProfileSchema.parse({ name, email })

    // Check if email is already taken by another user
    if (validatedData.email) {
      const existingUser = await prisma.user.findFirst({
        where: {
          email: validatedData.email,
          NOT: { id: (session.user as any).id },
        },
      })

      if (existingUser) {
        return {
          success: false,
          message: 'This email is already in use',
        }
      }
    }

    // Update user
    await prisma.user.update({
      where: { id: (session.user as any).id },
      data: {
        ...(validatedData.name && { name: validatedData.name }),
        ...(validatedData.email && { email: validatedData.email }),
      },
    })

    revalidatePath('/settings')

    return {
      success: true,
      message: 'Profile updated successfully',
    }
  } catch (error: any) {
    if (error.name === 'ZodError') {
      return {
        success: false,
        message: 'Validation failed',
        errors: error.flatten().fieldErrors,
      }
    }

    console.error('Update profile error:', error)
    return {
      success: false,
      message: 'An error occurred while updating your profile',
    }
  }
}
