import prisma from '../lib/prisma';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';

const JWT_SECRET = process.env.JWT_SECRET || 'secret';

export class AuthService {
    static async getUser(userId: string) {
        const user = await prisma.user.findUnique({
            where: { id: userId },
            include: { profile: true }
        });

        if (!user) return null;

        const { password: _, ...userSafe } = user;
        return userSafe;
    }

    static async login(email: string, password: string) {
        const user = await prisma.user.findUnique({
            where: { email },
            include: { profile: true }
        });

        if (!user) {
            throw new Error('Invalid credentials');
        }

        if (user.isBlocked) {
            throw new Error('Account is blocked');
        }

        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) {
            throw new Error('Invalid credentials');
        }

        const token = jwt.sign({ userId: user.id, role: user.role }, JWT_SECRET);
        const { password: _, ...userSafe } = user;

        return { user: userSafe, token };
    }

    static async register(email: string, password: string) {
        const existingUser = await prisma.user.findUnique({ where: { email } });
        if (existingUser) {
            throw new Error('User already exists');
        }

        const hashedPassword = await bcrypt.hash(password, 10);

        const user = await prisma.user.create({
            data: {
                email,
                password: hashedPassword,
                role: 'USER',
                profile: {
                    create: {
                        weight: 70
                    }
                }
            },
            include: { profile: true }
        });

        const token = jwt.sign({ userId: user.id, role: user.role }, JWT_SECRET);
        const { password: _, ...userSafe } = user;

        return { user: userSafe, token };
    }

    static async changePassword(userId: string, newPassword: string) {
        const hashed = await bcrypt.hash(newPassword, 10);

        await prisma.user.update({
            where: { id: userId },
            data: {
                password: hashed,
                isFirstLogin: false
            }
        });
    }

    static async updateProfile(userId: string, data: any) {
        // Convert birthDate if needed
        if (data.birthDate) {
            data.birthDate = new Date(data.birthDate);
        }

        await prisma.userProfile.upsert({
            where: { userId: userId },
            update: { ...data },
            create: { userId: userId, ...data }
        });
    }

    static async getAllUsers() {
        const users = await prisma.user.findMany({
            select: {
                id: true,
                email: true,
                role: true,
                isBlocked: true,
                isFirstLogin: true,
                profile: true
            },
            orderBy: {
                email: 'asc'
            }
        });
        return users;
    }

    static async deleteUser(adminId: string, targetId: string) {
        if (targetId === adminId) {
            throw new Error('Cannot delete yourself');
        }
        await prisma.user.delete({ where: { id: targetId } });
    }

    static async blockUser(adminId: string, targetId: string, block: boolean) {
        if (targetId === adminId) {
            throw new Error('Cannot block yourself');
        }
        await prisma.user.update({
            where: { id: targetId },
            data: { isBlocked: block }
        });
    }

    static async resetUserPassword(targetId: string, newPassword: string) {
        if (!newPassword || newPassword.length < 4) {
            throw new Error('Password too short');
        }

        const hashed = await bcrypt.hash(newPassword, 10);

        await prisma.user.update({
            where: { id: targetId },
            data: {
                password: hashed,
                isFirstLogin: true
            }
        });
    }
}
