import bcrypt from 'bcryptjs';
import { z } from 'zod';
import * as usersRepo from '../repositories/users.repository.js';

export const updateUserSchema = z.object({
  name: z.string().min(2).optional(),
  email: z.email().optional(),
  password: z.string().min(6).optional(),
});

export const updateProfileSchema = z.object({
  name: z.string().min(2).optional(),
  profilePhoto: z.string().optional(),
  bio: z.string().max(500).optional(),
});

export async function getUser(id: string) {
  const user = await usersRepo.findUserById(id);
  if (!user) throw new Error('User not found');
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    profilePhoto: user.profilePhoto,
    bio: user.bio,
    createdAt: user.createdAt,
  };
}

export async function getProfile(id: string) {
  const user = await usersRepo.findUserById(id);
  if (!user) throw new Error('User not found');
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    profilePhoto: user.profilePhoto,
    bio: user.bio,
  };
}

export async function updateUser(id: string, input: z.infer<typeof updateUserSchema>) {
  const user = await usersRepo.findUserById(id);
  if (!user) throw new Error('User not found');

  const data: Parameters<typeof usersRepo.updateUser>[1] = { updatedAt: new Date() };

  if (input.name) data.name = input.name;
  if (input.email) data.email = input.email;
  if (input.password) data.password = await bcrypt.hash(input.password, 10);

  const updated = await usersRepo.updateUser(id, data);
  return { id: updated.id, name: updated.name, email: updated.email };
}

export async function updateProfile(id: string, input: z.infer<typeof updateProfileSchema>) {
  const user = await usersRepo.findUserById(id);
  if (!user) throw new Error('User not found');

  const data: Parameters<typeof usersRepo.updateUser>[1] = { updatedAt: new Date() };

  if (input.name) data.name = input.name;
  if (input.profilePhoto !== undefined) data.profilePhoto = input.profilePhoto;
  if (input.bio !== undefined) data.bio = input.bio;

  const updated = await usersRepo.updateUser(id, data);
  return {
    id: updated.id,
    name: updated.name,
    email: updated.email,
    profilePhoto: updated.profilePhoto,
    bio: updated.bio,
  };
}

export async function deleteUser(id: string) {
  const user = await usersRepo.findUserById(id);
  if (!user) throw new Error('User not found');
  await usersRepo.deleteUser(id);
}