import {queryAll, queryOne, run} from '../../shared/database';
import bcrypt from 'bcrypt';

const USER_DB_NAME = 'userdata';
const SALT_ROUNDS = 10;

interface User {
    id: number;
    username: string;
    profile_picture_url: string | null;
    has_password: boolean;
}

export async function userExists(id: number): Promise<boolean> {
    const sql = 'SELECT 1 FROM User WHERE id = ?';
    const row = await queryOne(sql, [id], USER_DB_NAME);
    return !!row;
}

export async function createUser(username: string, profilePictureUrl?: string, password?: string): Promise<{ lastID: number }> {
    let passwordHash = null;

    if (password && password.trim()) {
        passwordHash = await bcrypt.hash(password.trim(), SALT_ROUNDS);
    }

    const sql = `
        INSERT INTO User (username, profile_picture_url, password_hash)
        VALUES (?, ?, ?)
    `;
    const params = [username, profilePictureUrl || null, passwordHash];

    const result = await run(sql, params, USER_DB_NAME);

    return { lastID: result.lastID };
}

export async function updateUser(userId: number, updates: any): Promise<any> {
    const fields: string[] = [];
    const values: (string | number | null)[] = [];

    if (updates.username !== undefined) {
        fields.push('username = ?');
        values.push(updates.username);
    }

    if (updates.profilePictureUrl !== undefined) {
        fields.push('profile_picture_url = ?');
        values.push(updates.profilePictureUrl);
    }

    if (updates.password !== undefined) {
        if (updates.password === null || updates.password === '') {
            // Eliminar contraseña
            fields.push('password_hash = ?');
            values.push(null);
        } else {
            // Actualizar contraseña
            const hash = await bcrypt.hash(updates.password.trim(), SALT_ROUNDS);
            fields.push('password_hash = ?');
            values.push(hash);
        }
    }

    if (fields.length === 0) {
        return { changes: 0, lastID: userId };
    }

    const setClause = fields.join(', ');
    const sql = `UPDATE User SET ${setClause} WHERE id = ?`;
    values.push(userId);

    return await run(sql, values, USER_DB_NAME);
}

export async function deleteUser(userId: number): Promise<any> {
    await run(
        `DELETE FROM ListEntry WHERE user_id = ?`,
        [userId],
        USER_DB_NAME
    );

    await run(
        `DELETE FROM UserIntegration WHERE user_id = ?`,
        [userId],
        USER_DB_NAME
    );

    await run(
        `DELETE FROM favorites WHERE user_id = ?`,
        [userId],
        'favorites'
    );

    const result = await run(
        `DELETE FROM User WHERE id = ?`,
        [userId],
        USER_DB_NAME
    );

    return result;
}

export async function getAllUsers(): Promise<User[]> {
    const sql = `
        SELECT 
            id, 
            username, 
            profile_picture_url,
            CASE WHEN password_hash IS NOT NULL THEN 1 ELSE 0 END as has_password
        FROM User 
        ORDER BY id
    `;

    const users = await queryAll(sql, [], USER_DB_NAME);

    return users.map((user: any) => ({
        id: user.id,
        username: user.username,
        profile_picture_url: user.profile_picture_url || null,
        has_password: !!user.has_password
    })) as User[];
}

export async function getUserById(id: number): Promise<User | null> {
    const sql = `
        SELECT
            id,
            username,
            profile_picture_url,
            CASE WHEN password_hash IS NOT NULL THEN 1 ELSE 0 END as has_password
        FROM User
        WHERE id = ?
    `;

    const user = await queryOne(sql, [id], USER_DB_NAME);

    if (!user) return null;

    return {
        id: user.id,
        username: user.username,
        profile_picture_url: user.profile_picture_url || null,
        has_password: !!user.has_password
    };
}

export async function verifyPassword(userId: number, password: string): Promise<boolean> {
    const sql = 'SELECT password_hash FROM User WHERE id = ?';
    const user = await queryOne(sql, [userId], USER_DB_NAME);

    if (!user || !user.password_hash) {
        return false;
    }

    return await bcrypt.compare(password, user.password_hash);
}

export async function getAniListIntegration(userId: number) {
    const sql = `
        SELECT anilist_user_id, expires_at
        FROM UserIntegration
        WHERE user_id = ? AND platform = ?
    `;

    const row = await queryOne(sql, [userId, "AniList"], USER_DB_NAME);

    if (!row) {
        return { connected: false };
    }

    return {
        connected: true,
        anilistUserId: row.anilist_user_id,
        expiresAt: row.expires_at
    };
}

export async function removeAniListIntegration(userId: number) {
    const sql = `
        DELETE FROM UserIntegration
        WHERE user_id = ? AND platform = ?
    `;

    return run(sql, [userId, "AniList"], USER_DB_NAME);
}