import { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import db from '../../database/models/index.js';
const { User, AuditLog } = db;
import { generateToken } from '../../common/config/auth.js';
import { AUDIT_ACTIONS } from '../../common/config/constants.js';
import { AuthRequest } from '../../types/express.types.js';

// Register new user
export const register = async (req: Request, res: Response) => {
    try {
        const { email, password, fullName, role, phone, locationId } = req.body;

        // Validate input
        if (!email || !password || !fullName || !role) {
            return res.status(400).json({
                success: false,
                message: 'Email, password, full name, and role are required'
            });
        }

        // Check if user already exists
        const existingUser = await User.findOne({ where: { email } });
        if (existingUser) {
            return res.status(400).json({
                success: false,
                message: 'User with this email already exists'
            });
        }

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

        // Insert user
        const user = await User.create({
            email,
            password: hashedPassword,
            fullName,
            roleCode: role,
            mobileNumber: phone,
            districtId: locationId,
            status: 'active'
        });

        // Log audit
        await AuditLog.create({
            userId: user.id,
            action: AUDIT_ACTIONS.CREATED,
            entityType: 'user',
            entityId: user.id
        });

        res.status(201).json({
            success: true,
            message: 'User registered successfully',
            userId: user.id
        });
    } catch (error) {
        console.error('Register error:', error);
        res.status(500).json({
            success: false,
            message: 'Error registering user'
        });
    }
};

// Login
export const login = async (req: Request, res: Response) => {
    try {
        const { email, password } = req.body;

        // Validate input
        if (!email || !password) {
            return res.status(400).json({
                success: false,
                message: 'Email and password are required'
            });
        }

        // Get user
        const user = await User.findOne({ where: { email } });

        if (!user) {
            return res.status(401).json({
                success: false,
                message: 'Invalid email or password'
            });
        }

        // Check if account is active
        if (user.status !== 'active') {
            return res.status(403).json({
                success: false,
                message: 'Account is inactive'
            });
        }

        // Verify password
        const isValidPassword = await bcrypt.compare(password, user.password!);
        if (!isValidPassword) {
            return res.status(401).json({
                success: false,
                message: 'Invalid email or password'
            });
        }

        // Update last login
        await user.update({ lastLogin: new Date() });

        // Generate token
        const token = generateToken(user);

        // Log audit
        await AuditLog.create({
            userId: user.id,
            action: AUDIT_ACTIONS.LOGIN as any,
            entityType: 'user',
            entityId: user.id
        });

        res.json({
            success: true,
            token,
            user: {
                id: user.id,
                email: user.email,
                fullName: user.fullName,
                role: user.roleCode,
                districtId: user.districtId
            }
        });
    } catch (error) {
        console.error('Login error:', error);
        res.status(500).json({
            success: false,
            message: 'Error during login'
        });
    }
};

// Get profile
export const getProfile = async (req: AuthRequest, res: Response) => {
    try {
        if (!req.user) {
            return res.status(401).json({ success: false, message: 'Unauthorized' });
        }

        // Mock Prospective User handling
        if (req.user.roleCode === 'Prospective Dealer') {
            return res.json({
                success: true,
                user: {
                    id: req.user.id,
                    email: req.user.email,
                    fullName: req.user.fullName,
                    role: 'Prospective Dealer',
                    phone: (req.user as any).mobileNumber || (req.user as any).phone,
                    createdAt: (req.user as any).createdAt || new Date().toISOString()
                }
            });
        }

        const user = await User.findByPk(req.user.id, {
            attributes: ['id', 'email', 'fullName', 'roleCode', 'districtId', 'mobileNumber', 'createdAt']
        });

        if (!user) {
            return res.status(404).json({
                success: false,
                message: 'User not found'
            });
        }

        res.json({
            success: true,
            user: {
                id: user.id,
                email: user.email,
                fullName: user.fullName,
                role: user.roleCode,
                districtId: user.districtId,
                phone: user.mobileNumber,
                createdAt: (user as any).createdAt
            }
        });
    } catch (error) {
        console.error('Get profile error:', error);
        res.status(500).json({
            success: false,
            message: 'Error fetching profile'
        });
    }
};

// Update profile
export const updateProfile = async (req: AuthRequest, res: Response) => {
    try {
        if (!req.user) {
            return res.status(401).json({ success: false, message: 'Unauthorized' });
        }

        const { fullName, phone } = req.body;

        const user = await User.findByPk(req.user.id);
        if (!user) {
            return res.status(404).json({
                success: false,
                message: 'User not found'
            });
        }

        await user.update({
            fullName: fullName || user.fullName,
            mobileNumber: phone || user.mobileNumber
        });

        // Log audit
        await AuditLog.create({
            userId: req.user.id,
            action: AUDIT_ACTIONS.UPDATED,
            entityType: 'user',
            entityId: req.user.id
        });

        res.json({
            success: true,
            message: 'Profile updated successfully'
        });
    } catch (error) {
        console.error('Update profile error:', error);
        res.status(500).json({
            success: false,
            message: 'Error updating profile'
        });
    }
};

// Change password
export const changePassword = async (req: AuthRequest, res: Response) => {
    try {
        if (!req.user) {
            return res.status(401).json({ success: false, message: 'Unauthorized' });
        }

        const { currentPassword, newPassword } = req.body;

        if (!currentPassword || !newPassword) {
            return res.status(400).json({
                success: false,
                message: 'Current password and new password are required'
            });
        }

        // Get current user
        const user = await User.findByPk(req.user.id);
        if (!user) {
            return res.status(404).json({
                success: false,
                message: 'User not found'
            });
        }

        // Verify current password
        const isValid = await bcrypt.compare(currentPassword, user.password!);
        if (!isValid) {
            return res.status(401).json({
                success: false,
                message: 'Current password is incorrect'
            });
        }

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

        // Update password
        await user.update({ password: hashedPassword });

        // Log audit
        await AuditLog.create({
            userId: req.user.id,
            action: 'password_changed' as any,
            entityType: 'user',
            entityId: req.user.id
        });

        res.json({
            success: true,
            message: 'Password changed successfully'
        });
    } catch (error) {
        console.error('Change password error:', error);
        res.status(500).json({
            success: false,
            message: 'Error changing password'
        });
    }
};
