import bcrypt from "bcryptjs";
import { generateAccessToken } from "../../config/jwt.js";
import { UserRepository } from "../../repositories/UserRepository.js";
import type { Prisma } from "../../generated/prisma/client.js";

export class MobileAuthService {
    constructor(private readonly userRepository = new UserRepository()) { }

    async login(identifier: string, password: string) {
        // Accept email or mobile number
        const isEmail = identifier.includes("@");
        const user = isEmail
            ? await this.userRepository.findByEmail(identifier)
            : await this.userRepository.findByMobileNo(identifier);

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

        if (Number(user.roleId) !== 2) {
            throw new Error("Access denied. Only staff can login on the mobile app.");
        }

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

        const token = generateAccessToken({
            id: Number(user.id),
            name: user.name,
            email: user.email,
            roleId: Number(user.roleId),
            role: user.role?.name,
        });

        return {
            message: "Login successful",
            token,
            user: {
                id: Number(user.id),
                name: user.name,
                email: user.email,
                mobileNo: user.mobileNo ?? null,
                role: user.role?.name,
                roleId: Number(user.roleId),
                status: Boolean(user.status),
                profile: user.profile ?? null,
            },
        };
    }

    async logout() {
        return { message: "Logout successful" };
    }

    async getProfile(userId: bigint) {
        const user = await this.userRepository.findById(userId);
        if (!user) {
            throw new Error("User not found.");
        }
        return user;
    }

    async updateProfile(userId: bigint, updateData: Prisma.UserUncheckedUpdateInput) {
        const user = await this.userRepository.findById(userId);
        if (!user) {
            throw new Error("User not found.");
        }

        if (typeof updateData.password === "string") {
            updateData.password = await bcrypt.hash(updateData.password, 10);
        }

        return this.userRepository.update(userId, updateData);
    }
}