import { Request, Response } from 'express';
import { PaginationHelper } from '../helpers/paginate';
import db from '../models'; // Adjust the path to your models folder if necessary
const TaskModel = db.Task;
const RoleMasterModel = db.RoleMaster;
const UserModel = db.User;

import { Parser } from 'json2csv';
import { Op } from 'sequelize';
import { UserData } from '../helpers/userToken';
import { generateApiKey } from '../utils/apiKeyUtils';


//Create and Edit and is_ative false the client
export const createUser = async (req: Request, res: Response): Promise<void> => {
    try {
        const { id, first_name, last_name, email, mobile, role_id, isActive, staff_augmentation, staff_augmentation_percentage } = req.body;
        const userId = (req.user as UserData).user_data.id;

        let result;

        // Backend validation & normalization
        let normalizedPercentage = staff_augmentation_percentage;

        if (staff_augmentation === false) {
          // If toggle is OFF, percentage must be NULL
          normalizedPercentage = null;
        }

        if (
          staff_augmentation === true &&
          (staff_augmentation_percentage === null ||
            staff_augmentation_percentage === undefined)
        ) {
          res.status(400).json({
            success: false,
            message: 'Staff augmentation percentage is required when enabled',
          });
          return;
        }
        // Create or update the client
        const userData = {
            first_name,
            last_name,
            email,
            mobile,
            role_id,
            isActive,
            staff_augmentation,
            staff_augmentation_percentage: normalizedPercentage
        };

        if(id){
            result = await UserModel.update(userData, { where: { id } });
        }
        else{
            result = await UserModel.create(userData);
        }
        let msg
        if (!id) {
            msg = 'User Created';
        } else if (typeof isActive !== 'undefined') {
            msg = isActive === 'false' || isActive === false ? 'User Deactivated' : 'User Updated';
        } else {
            msg = 'User Updated';
        }
        
        res.status(200).json({
            success: true,
            message:msg
        });
    } catch (error) {
        console.error('Error creating/updating client:', error);
        res.status(500).json({
            success: false,
            message: 'Internal server error',
            error: error instanceof Error ? error.message : 'An unknown error occurred',
        });
    }
};

//Get all user list
export const getUsers = async (req: Request, res: Response): Promise<void> => {
    try {
        const { id, page, per_page, search, type } = req.query;
        const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        // Build the where clause
        let whereClause: any = {};

        if(type !== 'all') {
            whereClause.isActive = true
        }

        // Add search condition if search parameter exists
        if (search && typeof search === 'string') {
            whereClause = {
                ...whereClause,
                [Op.or]: [
                    {
                        first_name: {
                            [Op.iLike]: `%${search}%`
                        }
                    },
                    {
                        last_name: {
                            [Op.iLike]: `%${search}%`
                        }
                    }
                ]
            };
        }

        //Add id condition if id parameter exists
        if (req.query.id && typeof req.query.id === 'string') {
            whereClause = {
                ...whereClause,
                id: {
                    [Op.eq]: req.query.id
                }
            };
        }

        const result = await UserModel.findAndCountAll({
            where: whereClause,
            include: [
                {   
                    model: RoleMasterModel,
                    as: 'RoleMaster',
                    attributes: ['id', 'role']
                }
            ],
            order: [['id', 'ASC']],
            limit,
            offset,
            attributes: { 
                exclude: ['password', 'token', 'api_key'] 
            }
        });

        if (result.count === 0) {
            res.status(200).json({ 
                success: true, 
                data: [],
                pagination: {
                    total_records: 0,
                    total_pages: 0,
                    current_page: parseInt(page as string) || 1,
                    per_page: limit
                }
            });
            return;
        }

        const paginatedResult = PaginationHelper.paginate({
            data: result.rows,
            count: result.count,
            per_page: limit,
            page: page as string
        });

        res.status(200).json({
            success: true,
            data: paginatedResult.data,
            pagination: paginatedResult.pagination
        });

    } catch (error) {
        console.error('Error fetching users:', error);
        res.status(500).json({
            success: false,
            message: "We hit a snag! Our team is looking into it.",
            error: error instanceof Error ? error.message : 'Unknown error'
        });
    }
};

//Get Role Masters List
export const getRoleMasters = async (req: Request, res: Response): Promise<void> => {
    try {
        const { id, page, per_page, search } = req.query;
        let whereClause: any = {
            is_active: true,
        };
        //if search in parameter condition
        if (search && typeof search === 'string') {
            whereClause = {
                ...whereClause,
                role: {
                    [Op.iLike]: `%${search}%` // Case-insensitive search
                }
            };
        }
        const result = await db.RoleMaster.findAll({
            where: whereClause,
            order: [['id', 'ASC']],
            attributes: { 
                exclude: ['createdAt', 'updatedAt'] 
            }
        });

        res.status(200).json({
            success: true,
            data: result
        });
    } catch (error) {
        console.error('Error fetching role masters:', error);
        res.status(500).json({
            success: false,
            message: "We hit a snag! Our team is looking into it.",
            error: error instanceof Error ? error.message : 'Unknown error'
        });
    }
};

/**
 * Generates a new API key for the authenticated user
 * POST /api/user/generate-api-key
 */
export const generateUserApiKey = async (req: Request, res: Response): Promise<void> => {
    try {
        const userData = req.user as UserData;
        const userId = userData.user_data.id;

        // Generate new API key
        const newApiKey = generateApiKey();
        const now = new Date();

        // Update user with new API key
        await UserModel.update(
            {
                api_key: newApiKey,
                api_key_created_at: now,
                api_key_last_used: null // Reset last used when new key is generated
            },
            { where: { id: userId } }
        );

        res.status(200).json({
            success: true,
            message: 'API key generated successfully',
            data: {
                api_key: newApiKey,
                created_at: now,
                warning: 'Store this API key securely. You will not be able to see it again.'
            }
        });

    } catch (error) {
        console.error('Error generating API key:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to generate API key',
            error: error instanceof Error ? error.message : 'Unknown error'
        });
    }
};

/**
 * Gets user's API key information (without the actual key)
 * GET /api/user/api-key-info
 */
export const getApiKeyInfo = async (req: Request, res: Response): Promise<void> => {
    try {
        const userData = req.user as UserData;
        const userId = userData.user_data.id;

        const user = await UserModel.findOne({
            where: { id: userId },
            attributes: ['api_key_created_at', 'api_key_last_used']
        });

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

        res.status(200).json({
            success: true,
            data: {
                has_api_key: !!user.api_key_created_at,
                created_at: user.api_key_created_at,
                last_used: user.api_key_last_used
            }
        });

    } catch (error) {
        console.error('Error fetching API key info:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to fetch API key information',
            error: error instanceof Error ? error.message : 'Unknown error'
        });
    }
};

/**
 * Revokes (deletes) the user's API key
 * DELETE /api/user/revoke-api-key
 */
export const revokeApiKey = async (req: Request, res: Response): Promise<void> => {
    try {
        const userData = req.user as UserData;
        const userId = userData.user_data.id;

        // Remove API key fields
        await UserModel.update(
            {
                api_key: null,
                api_key_created_at: null,
                api_key_last_used: null
            },
            { where: { id: userId } }
        );

        res.status(200).json({
            success: true,
            message: 'API key revoked successfully'
        });

    } catch (error) {
        console.error('Error revoking API key:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to revoke API key',
            error: error instanceof Error ? error.message : 'Unknown error'
        });
    }
};