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 TaskHistoryModel = db.TaskHistory;
const ProjectMasterModel = db.ProjectMaster;
const ClientMasterModel = db.ClientMaster;
const UserModel = db.User;
const PlanModel = db.Plan;
import { Op, where } from 'sequelize';
import { UserData } from '../helpers/userToken';
const TrackexNotificationModel = db.TrackexNotification;
const NotificationHistoryModel = db.NotificationHistory;
import { WebSocketService } from '../services/WebSocketService';
import { model } from 'mongoose';
const TaskWatchModel = db.TaskWatcher;

//Get the Plans based in is_highlight true on top from plans table
export const getMyPlans = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page, plan_date } = req.query;

         // Get today's date at start and end
         const today = new Date();
         today.setHours(0, 0, 0, 0);
         const tomorrow = new Date(today);
         tomorrow.setDate(tomorrow.getDate() + 1);
 
         // Set date range based on query param or default to today
         const targetDate = plan_date ? new Date(plan_date as string) : today;
         const nextDate = new Date(targetDate);
         nextDate.setDate(targetDate.getDate() + 1);
 
          // Get paginated plans list (existing functionality)
          const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const userId = (req.user as UserData).user_data.id;
        //check the role of the user
        const userRole = (req.user as UserData).user_data.role_id;
        //get the roles from the role table
        const role = await db.RoleMaster.findOne({
            where: { id: userRole },
            attributes: ['role'],
        });
        let result,stats;
        const dateWhereClause = {
            plan_date: {
                [Op.gte]: targetDate,
                [Op.lt]: nextDate
            }
        };
        // If the role is management then start new if block
        // Get task counts
        const taskCounts = await PlanModel.findAll({
            attributes: [
                [db.sequelize.fn('COUNT', db.sequelize.col('*')), 'total_tasks'],
                [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status = 'completed' THEN 1 ELSE 0 END`)), 'completed_tasks'],
                [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status NOT IN ('completed','pending') THEN 1 ELSE 0 END`)), 'remaining_tasks'],
                [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN plan_released = true THEN 1 ELSE 0 END`)), 'released_tasks']
            ],
            where: { user_id: userId, ...dateWhereClause },
            raw: true
        });

        result = await PlanModel.findAndCountAll({
            where: {
                user_id: userId,
                is_active: true,
                ...dateWhereClause
            },
            include: [
                {
                    model: TaskModel,
                    as: 'task',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                    include: [
                        {
                            model: ProjectMasterModel,
                            as: 'project',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                        {
                            model: ClientMasterModel,
                            as: 'client',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                    ]

                },
                {
                    model: UserModel,
                    as: 'user',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt','token']},
                },
                {
                    model: UserModel,
                    as: 'assigner',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                },
               
            ],
            order: [['is_highlight', 'DESC'], ['plan_date', 'ASC']],
            limit,
            offset,
        });

         // Format task statistics
         stats = {
            total_tasks: parseInt(taskCounts[0]?.total_tasks as string) || 0,
            completed_tasks: parseInt(taskCounts[0]?.completed_tasks as string) || 0,
            remaining_tasks: parseInt(taskCounts[0]?.remaining_tasks as string) || 0,
            released_tasks:parseInt(taskCounts[0]?.released_tasks as string) || 0,
            // completion_percentage: taskCounts[0]?.total_tasks ? 
            //     Math.round((parseInt(taskCounts[0].completed_tasks as string) / parseInt(taskCounts[0].total_tasks as string)) * 100) : 
            //     0
        };

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

       

        res.status(200).json({
            success: true,
            message: 'All Today Tasks',
            task_statistics: stats,
            data: paginatedResult.data,
            pagination: paginatedResult.pagination
        });

    } catch (error) {
        console.error('Error fetching plans:', 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'
        });
    }
};

//Update the plan status as started
export const updatePlanStatus = async (req: Request, res: Response): Promise<void> => {
    try {
        // const { id } = req.params;
        const { plan_id, status,close_notes,ai_use,difficulty,stuck_comments } = req.body;
        const userId = (req.user as UserData).user_data.id;
        let taskId = await PlanModel.findOne({
            where: { id: plan_id },     
        });
        const task = await TaskModel.findOne({ where: { id: taskId.task_id } });
        //updte the tasks like task_status, plan_status
        if(status ==='started'){
            //update Task Model
            await TaskModel.update(
                { status: 'started' },
                { where: { id: taskId.task_id } }
            );
            //create taskhistories
            await TaskHistoryModel.create({
                task_id: taskId.task_id,
                user_id: userId,
                status: 'started',
                task_date: new Date(),
            });
            //update the planModel
            await PlanModel.update(
                { is_started: true },
                { where: { id:plan_id } }
            );
        }else if(status === 'escalated'){
            //update Task Model     
            await TaskModel.update(
                { status: 'escalated',escalated_date: new Date() },
                { where: { id: taskId.task_id } }
            );
            //create taskhistories
            await TaskHistoryModel.create({
                task_id: taskId.task_id,
                user_id: userId,
                status: 'escalated',
                task_date: new Date(),
            });
            //update the planModel
            await PlanModel.update(
                { task_status: 'escalated',is_started: false,stuck_comments:stuck_comments,is_escalated:true },
                { where: { id:plan_id } }
            );

            //create notifications
            const notification = await TrackexNotificationModel.create(
                {
                    task_id: task.id,
                    type: 'escalate_task',
                    title: 'Task Escalated',
                    text: task.title,
                    user_id: userId
                }
            );

            console.log("1")

            const managers = await UserModel.findAll({ where: { role_id: 1 } });

            console.log(managers)

            //create Notification Histories table
            for (const manager of managers) {
                await NotificationHistoryModel.create({
                    notification_id: notification.id,
                    target_to: manager.id,
                    user_id: userId
                });

                WebSocketService.getInstance().sendNotification(manager.id, {
                    type: 'escalate_task',
                    message: taskId.title,
                    data: {
                        task: {
                            task_id: task.id,
                            type: 'Escalated Task',
                            title: 'Task Escalated',
                            text: task.title,
                            user_id: userId
                            
                        }
                    }
                });
            }
        }else{
            //update Task Model
            await TaskModel.update(
                { status: 'completed',close_notes,ai_use,difficulty },
                { where: { id: taskId.task_id } }
            );
            //create taskhistories
            await TaskHistoryModel.create({
                task_id: taskId.task_id,
                user_id: userId,
                status: 'completed',
                task_date: new Date(),
            });
            //update the planModel
            await PlanModel.update(
                { task_status: 'completed',is_started:false },
                { where: { id:plan_id } }
            );
        }
        if(status === 'escalated'){
        res.status(200).json({
            status: 200,
            success: true,
            message: 'Houston, we have a problem! Help has been summoned.',
        });
        }else if(status === 'completed'){
            res.status(200).json({
                status: 200,
                success: true,
                message: 'Task conquered! Your productivity streak continues.',
            });
        }else{
            res.status(201).json({
                status: 201,
                success: true,
                message: 'Task Started! Your productivity streak continues.',
            });
        }
    } catch (error) {
        console.error('Error updating plan status:', 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'
        });
    }
};

//Release task Api
export const releaseTask = async (req: Request, res: Response): Promise<void> => {
    try {
        const { plan_id } = req.body;
        const userId = (req.user as UserData).user_data.id;

        //update the planModel
        await PlanModel.update(
            { task_status: 'pending',is_active: false,plan_released: true },
            { where: { id:plan_id } }
        );
        //get the task_id from the plan table
        let taskId = await PlanModel.findOne({
            where: { id: plan_id },     
        });
        const task_id = taskId.task_id;
        //update Task Model
        await TaskModel.update(
            { 
                task_type: 'planned',
                status: 'pending', 
                is_released: true, 
                assigned_to: null,
                task_released:true,
                is_adhoc: false },
            { 
                where: { id: task_id } 
            }
        );
        //create taskhistories
        await TaskHistoryModel.create({
            task_id: task_id,
            user_id: userId,
            status: 'released',
            task_date: new Date(),
        });
        
        res.status(200).json({
            success: true,
            message: 'Task returned to the pool! Ready for another day.',
        });
    } catch (error) {
        console.error('Error releasing task:', 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 the Plan and include task and user details
//Get the Plans based in is_highlight true on top from plans table
export const getAssignPlans = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page, plan_date } = req.query;

         // Get today's date at start and end
         const today = new Date();
         today.setHours(0, 0, 0, 0);
         const tomorrow = new Date(today);
         tomorrow.setDate(tomorrow.getDate() + 1);
 
         // Set date range based on query param or default to today
         const targetDate = plan_date ? new Date(plan_date as string) : today;
         const nextDate = new Date(targetDate);
         nextDate.setDate(targetDate.getDate() + 1);
 
          // Get paginated plans list (existing functionality)
          const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const userId = (req.user as UserData).user_data.id;
        //check the role of the user
        const userRole = (req.user as UserData).user_data.role_id;
        //get the roles from the role table
        const role = await db.RoleMaster.findOne({
            where: { id: userRole },
            attributes: ['role'],
        });
        let result,stats;
        const dateWhereClause = {
            plan_date: {
                [Op.gte]: targetDate,
                [Op.lt]: nextDate
            }
        };
        // If the role is management then start new if block
            result = await PlanModel.findAll({
                where: {
                    is_active: true,
                    plan_status: 'draft',
                    task_status: 'assigned',         
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                    },
                    {
                        model: UserModel,
                        as: 'user',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt','token']},
                    },
                    {
                        model: UserModel,
                        as: 'assigner',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt','token']},
                    },
                ],
                order: [['id', 'DESC'],],
            });
        

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

    } catch (error) {
        console.error('Error fetching plans:', 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'
        });
    }
};

//My Reviews

//Get the Plans based in is_highlight true on top from plans table
export const getMyReviews = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page, plan_date, user_id, status, my_focus, released_tasks_only } = req.query;

         // Get today's date at start and end
         const today = new Date();
         today.setHours(0, 0, 0, 0);
         const tomorrow = new Date(today);
         tomorrow.setDate(tomorrow.getDate() + 1);
 
         // Set date range based on query param or default to today
         const targetDate = plan_date ? new Date(plan_date as string) : today;
         const nextDate = new Date(targetDate);
         nextDate.setDate(targetDate.getDate() + 1);
 
          // Get paginated plans list (existing functionality)
          const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const userId = (req.user as UserData).user_data.id;
        //check the role of the user
        const userRole = (req.user as UserData).user_data.role_id;
        //get the roles from the role table
        const role = await db.RoleMaster.findOne({
            where: { id: userRole },
            attributes: ['role'],
        });
        let result,stats;
        const dateWhereClause = {
            plan_date: {
                [Op.gte]: targetDate,
                [Op.lt]: nextDate
            }
        };
        const whereClause: any = {
            ...dateWhereClause
        }

        if(user_id) {
            whereClause.user_id = user_id
        }

        if(status === 'pending') {
            whereClause.task_status = {
                [ Op.notIn ]: [ 'completed', 'released' ]
            },
            whereClause.is_active = true,
            whereClause.plan_released = false
        }

        if (my_focus === 'true') {
            const watchedTasks = await TaskWatchModel.findAll({
                where: { user_id: userId },
                attributes: ['task_id'],
                raw: true,
            });
        
            const watchedTaskIds = watchedTasks.map((t: any) => t.task_id);
        
            whereClause[Op.or] = [
                { user_id: userId },
                { task_id: { [Op.in]: watchedTaskIds } },
            ];
        }

        if (released_tasks_only === 'true') {
            whereClause.is_active = false;
            whereClause.plan_released = true;
            whereClause.task_status = 'pending';
        }

        // If the role is management then start new if block
            //stats for the management
            const taskCounts = await PlanModel.findAll({
                attributes: [
                    [db.sequelize.fn('COUNT', db.sequelize.col('*')), 'total_tasks'],
                    [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status = 'completed' THEN 1 ELSE 0 END`)), 'completed_tasks'],
                    [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status = 'escalated' THEN 1 ELSE 0 END`)), 'escalated_tasks'],
                    [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status NOT IN ('completed', 'escalated', 'pending') THEN 1 ELSE 0 END`)), 'remaining_tasks'],
                    [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN plan_released = true THEN 1 ELSE 0 END`)), 'released_tasks']
                ],
                where: whereClause,
                raw: true
            });

            stats = {
                total_tasks: parseInt(taskCounts[0]?.total_tasks as string) || 0,
                completed_tasks: parseInt(taskCounts[0]?.completed_tasks as string) || 0,
                escalated_tasks: parseInt(taskCounts[0]?.escalated_tasks as string) || 0,
                remaining_tasks: parseInt(taskCounts[0]?.remaining_tasks as string) || 0,
                released_tasks:parseInt(taskCounts[0]?.released_tasks as string) || 0
            };

            //get hours for individual user
            const hoursByUserArr = await PlanModel.findAll({
                attributes: [
                    'user_id',
                    [db.sequelize.fn('SUM', db.sequelize.col('task.hours')), 'total_hours']
                ],
                where: {
                    ...whereClause
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        attributes: [],
                    },
                    {
                        model: UserModel,
                        as: 'user',
                        attributes: [],
                    }
                ],
                group: ['Plan.user_id'],
                raw: true
            });
                        
            const hoursByUserMap: Record<number, number> = {};
            hoursByUserArr.forEach((row: any) => {
                hoursByUserMap[row.user_id] = Number(row.total_hours ?? 0);
            });

            result = await PlanModel.findAll({
                where: {
                    is_active: true,
                    ...whereClause
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                        include: [
                            {
                                model: ProjectMasterModel,
                                as: 'project',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                            {
                                model: ClientMasterModel,
                                as: 'client',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                            {
                                model: TaskWatchModel,
                                as: 'task_watchers',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                                include: [
                                    {
                                        model: UserModel,
                                        as: 'user',
                                        required: false,
                                        attributes: ['id', 'first_name','last_name', "email"],
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        model: UserModel,
                        as: 'user',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt','token']},
                    },
                    {
                        model: UserModel,
                        as: 'assigner',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt', 'token']},
                    },
                ],
                order: [['plan_date', 'ASC']],
            });

            result.forEach((plan: any) => {
                // add directly to the Sequelize instance
                plan.setDataValue(
                    'user_total_hours',
                    hoursByUserMap[plan.user_id] ?? 0
                );
            });
            
     
        const paginatedResult = PaginationHelper.paginate({
            data: result.rows,
            count: result.count,
            per_page: limit,
            page: page as string
        });

       

        res.status(200).json({
            success: true,
            message: 'All Today Tasks',
            task_statistics: stats,
            data: result,
        });

    } catch (error) {
        console.error('Error fetching plans:', 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'
        });
    }
};


//view plans
export const viewPlans = async (req: Request, res: Response): Promise<void> => {
    try {
        const { plan_date } = req.query;

        if (!plan_date) {
            res.status(200).json({
                success: true,
                message: "No plan_date provided",
                data: [],
            });
            return;
        }

        // Get today's date at start and end
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const tomorrow = new Date(today);
        tomorrow.setDate(tomorrow.getDate() + 1);

        // Set date range based on query param or default to today
        const targetDate = plan_date ? new Date(plan_date as string) : today;
        const nextDate = new Date(targetDate);
        nextDate.setDate(targetDate.getDate() + 1);

        const dateWhereClause = {
            plan_date: {
                [Op.gte]: targetDate,
                [Op.lt]: nextDate
            }
        };

        const result = await PlanModel.findAll({
            where: {
                is_active: true,
                ...dateWhereClause
            },
            include: [
                {
                    model: TaskModel,
                    as: 'task',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                    include: [
                        {
                            model: ProjectMasterModel,
                            as: 'project',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                        {
                            model: ClientMasterModel,
                            as: 'client',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                    ]

                },
                {
                    model: UserModel,
                    as: 'user',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt','token']},
                },
                {
                    model: UserModel,
                    as: 'assigner',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt', 'token']},
                },
            ],
            order: [['plan_date', 'ASC']],  
        });

        res.status(200).json({
            success: true,
            message: 'All Today Plans',
            data: result
        });

    } catch (error) {
        console.error('Error fetching plans:', 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'
        });
    }
}

//view plan analytics
export const getPlanAnalytics = async (req: Request, res: Response): Promise<void> => {
    try {
        const { plan_date } = req.query;

        if (!plan_date) {
            res.status(200).json({
                success: true,
                message: "No plan_date provided",
                data: [],
            });
            return;
        }

        // Get today's date at start and end
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const tomorrow = new Date(today);
        tomorrow.setDate(tomorrow.getDate() + 1);

        // Set date range based on query param or default to today
        const targetDate = plan_date ? new Date(plan_date as string) : today;
        targetDate.setHours(0, 0, 0, 0);

        const nextDate = new Date(targetDate);
        nextDate.setDate(targetDate.getDate() + 1);

        let whereClause;

        if(targetDate > today) {
            whereClause = {
                is_active: true,
                is_draft: true
            }
        } else {
            whereClause = {
                is_active: true,
                plan_date: {
                    [Op.gte]: targetDate,
                    [Op.lt]: nextDate
                }
            }
        };

        //Get plans
        const plans = await PlanModel.findAll({
            where: whereClause,
            attributes: ['task_id'],
        });

        const taskIds = plans.map((plan: any) => plan.task_id);

        //get cilent ids from tasks
        const clientsAssigned = await TaskModel.findAll({
            where: {
                id: { [Op.in]: taskIds },
                client_id: { [Op.ne]: null },
                is_active: true
            },
            attributes: ['client_id'],
        });
        const clientAssignedIds = clientsAssigned.map((clients:any) => clients.client_id);

        //get unassigned clients
        const clientsUnassigned = await ClientMasterModel.findAll({
            where: {
                is_active: true,
                id: {
                    [Op.notIn]: clientAssignedIds
                },
                // Ensure client has at least one valid task
                [Op.and]: [
                    db.Sequelize.literal(`EXISTS (
                        SELECT 1 FROM tasks 
                        WHERE tasks.client_id = "ClientMaster".id 
                        AND tasks.is_active = true 
                        AND tasks.status != 'completed'
                    )`)
                ]
            },
            order: [['id', 'ASC']]
        });

        //get user ids from tasks
        const usersAssigned = await PlanModel.findAll({
            where: whereClause,
            attributes: ['user_id'],
        });
        const userAssignedIds = usersAssigned.map((users:any) => users.user_id);

        //get unassigned users
        const usersUnassigned = await UserModel.findAll({
            where: { 
                id: { [Op.notIn]: userAssignedIds},
                isActive: true,
                [Op.or]: [
                    { staff_augmentation_percentage: { [Op.lt]: 100 } },
                    { staff_augmentation_percentage: null }
                ]
            },
            attributes: { exclude: ['token', 'createdAt', 'updatedAt']},
            order: [['id', 'ASC']]
        });

        // Get total unassigned tasks count
        const unassignedTasksCount = await TaskModel.count({
            where: {
                never_assigned: true,
                status: 'pending',
                is_active: true
            }
        });

        //get unassigned tasks
        const unassignedTasks = await TaskModel.findAll({
            where: {
                never_assigned: true,
                status: 'pending',
                is_active: true
            },
            include: [
                {
                    model: ProjectMasterModel,
                    as: 'project',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                },
                {
                    model: ClientMasterModel,
                    as: 'client',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                },
            ],
            order: [['createdAt', 'ASC']],
            limit: 5
        });

        //get released tasks
        const releasedTasks = await TaskHistoryModel.findAll({
            where: {
                status: 'released',
                is_active: true
            },
            attributes: [
                'task_id',
                [db.Sequelize.fn('COUNT', db.Sequelize.col('task_id')), 'release_count']
            ],
            group: 'task_id',
            order: [[db.Sequelize.literal('release_count'), 'DESC']]
        });

        console.log(releasedTasks);

        const releasedTaskIds = releasedTasks.map((entry: any) => entry.task_id);

        // Get total released tasks count
        const releasedTasksCount = await TaskModel.count({
            where: {
                id: { [Op.in]: releasedTaskIds },
                status: { [Op.ne]: 'completed' },
                is_active: true
            }
        });

        const releasedtotalTasks = await TaskModel.findAll({
            where: {
                id: { [Op.in]: releasedTaskIds },
                status: { [Op.ne]: 'completed' },
                is_active: true
            },
            attributes: {
                include: [
                    [
                        db.Sequelize.literal(`(
                            SELECT COUNT(*)
                            FROM task_histories
                            WHERE task_histories.task_id = "Task".id
                            AND task_histories.status = 'released'
                            AND task_histories.is_active = true
                        )`),
                        'release_count'
                    ],
                ]
            },
            include: [
                {
                    model: ProjectMasterModel,
                    as: 'project',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                },
                {
                    model: ClientMasterModel,
                    as: 'client',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                },
            ],    
            order: [
                [db.Sequelize.literal('release_count'), 'DESC']
            ],
            limit: 5
        });

        res.status(200).json({
            success: true,
            message: 'Plan Analytics Data',
            unassigned_clients_count: clientsUnassigned.length,
            unassigned_users_count: usersUnassigned.length,
            unassigned_tasks_count: unassignedTasksCount,
            released_tasks_count: releasedTasksCount,
            unassigned_clients: clientsUnassigned,
            unassigned_users: usersUnassigned,
            unassigned_tasks: unassignedTasks,
            released_tasks: releasedtotalTasks
        });
    } catch (error) {
        console.error('Error fetching plans:', 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'
        });
    }
}

export const getPlanSummary = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page, plan_date } = req.query;

        // Get today's date at start and end
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const tomorrow = new Date(today);
        tomorrow.setDate(tomorrow.getDate() + 1);

        // Set date range based on query param or default to today
        const targetDate = plan_date ? new Date(plan_date as string) : today;
        const nextDate = new Date(targetDate);
        nextDate.setDate(targetDate.getDate() + 1);

        // Get paginated plans list (existing functionality)
        const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const dateWhereClause = plan_date ? {
            plan_date: {
                [Op.gte]: targetDate,
                [Op.lt]: nextDate
            }
        } : {};

        //get count
        const totalCount = await PlanModel.findAll({
            attributes: [
                [db.sequelize.fn('DATE', db.sequelize.col('plan_date')), 'date'],
                'plan_status'
            ],
            where: { ...dateWhereClause },
            group: [db.sequelize.fn('DATE', db.sequelize.col('plan_date')), 'plan_status'],
            raw: true
        });
        const totalRecords = totalCount.length;

        // Get task counts
        const taskCounts = await PlanModel.findAll({
            attributes: [
                [db.sequelize.fn('DATE', db.sequelize.col('plan_date')), 'date'],
                [db.sequelize.fn('COUNT', db.sequelize.col('*')), 'total_tasks'],
                [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status = 'completed' THEN 1 ELSE 0 END`)), 'completed_tasks'],
                [db.sequelize.literal(`CEIL((SUM(CASE WHEN task_status = 'completed' THEN 1 ELSE 0 END) * 100.0) / COUNT(*))`), 'completion_percentage'],
                [db.sequelize.col('plan_status'), 'status'],
            ],
            where: { ...dateWhereClause },
            group: [db.sequelize.fn('DATE', db.sequelize.col('plan_date')), 'plan_status'],
            order: [[db.sequelize.fn('DATE', db.sequelize.col('plan_date')), 'DESC']],
            limit, 
            offset,
            raw: true
        });

        let taskSummary;

        if (plan_date) {
            if (taskCounts.length > 0) {
                taskSummary = taskCounts[0];
            } else {
                taskSummary = {
                    plan_date: '',
                    total_tasks: 0,
                    completed_tasks: 0,
                    completion_percentage: 0,
                    status: ''
                };
            }
        } else {
            taskSummary = PaginationHelper.paginate({
                data: taskCounts,
                count: totalRecords,
                per_page: limit,
                page: page as string
            });
        }

        res.status(200).json({
            success: true,
            message: plan_date ? 'Plan Summary' : 'All Plans Summary',
            task_summary: plan_date ? taskSummary : taskSummary.data,
            pagination: taskSummary.pagination
        });

    } catch (error) {
        console.error('Error Fetching Plan Summary:', 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 pending tasks
export const getAllPendingTasks = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page } = req.query;
        const today = new Date();
        today.setHours(0, 0, 0, 0);

        // Get paginated plans list (existing functionality)
          const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const { rows, count: total_records} = await PlanModel.findAndCountAll({
            where: {
                is_active: true,
                plan_released: false,
                is_escalated: false,
                task_status: 'assigned',
                plan_date: {
                    [Op.lt]: today
                }
            },
            include: [
                {
                    model: TaskModel,
                    as: 'task',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt']},
                    include: [
                        {
                            model: ProjectMasterModel,
                            as: 'project',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                        {
                            model: ClientMasterModel,
                            as: 'client',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt']},
                        },
                    ]

                },
                {
                    model: UserModel,
                    as: 'user',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt','token']},
                },
                {
                    model: UserModel,
                    as: 'assigner',
                    required: false,
                    attributes: {exclude: ['createdAt', 'updatedAt', 'token']},
                },
            ],
            order: [['plan_date', 'ASC']],  
            limit,
            offset
        });

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

        res.status(200).json({
            success: true,
            message: 'All Assign Plans',
            data: paginatedResult
        });
    } catch (error) {
        console.error('Error Fetching Plan Data:', 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'
        });
    }
}

//task watchers
export const watchTask = async (req: Request, res:Response): Promise<void> => {
    try {
        const { task_id, is_watching } = req.body;
        const userData = (req as any).user as UserData;
        let user_id = req.user.user_data.id;

        if (!task_id) {
            res.status(404).json({ success: false, message: "Task Id is required." });
            return;
        }

        if(is_watching === true) {
            await TaskWatchModel.create({
                task_id,
                user_id
            });
        } else {
            await TaskWatchModel.destroy({
                where: { task_id, user_id }
            })
        }

        res.status(200).json({
            success: true,
            message: is_watching ? 'Good! Thanks for keeping an eye on this task': 'Okay! You are no longer watching this task.',
        });
    } catch (error) {
        console.error('Error Creating Data:', 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 My Pending Tasks
export const getMyPendingTasks = async (req: Request, res: Response): Promise<void> => {
    try {
        const { page, per_page, plan_date, type } = req.query;

         // Get today's date at start and end
         const today = new Date();
         today.setHours(0, 0, 0, 0);
         const tomorrow = new Date(today);
         tomorrow.setDate(tomorrow.getDate() + 1);
 
         // Set date range based on query param or default to today
         const targetDate = plan_date ? new Date(plan_date as string) : today;
         const nextDate = new Date(targetDate);
         nextDate.setDate(targetDate.getDate() + 1);
 
          // Get paginated plans list (existing functionality)
          const { limit, offset } = PaginationHelper.getPaginationParams(
            page as string | number | undefined, 
            per_page as string | number | undefined
        );

        const userId = (req.user as UserData).user_data.id;

        // Check if type is ad_hoc - query plans for ad_hoc tasks with date filter
        if (type === 'ad_hoc') {
            const dateWhereClause = {
                plan_date: {
                    [Op.gte]: targetDate,
                    [Op.lt]: nextDate
                }
            };

            // Get today's ad hoc task plans for this user
            const { rows: planRows, count: planCount } = await PlanModel.findAndCountAll({
                where: {
                    user_id: userId,
                    is_active: true,
                    ...dateWhereClause
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        required: true,
                        where: {
                            task_type: 'ad_hoc',
                            is_active: true
                        },
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                        include: [
                            {
                                model: ProjectMasterModel,
                                as: 'project',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                            {
                                model: ClientMasterModel,
                                as: 'client',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                        ]
                    },
                    {
                        model: UserModel,
                        as: 'user',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt','token']},
                    },
                    {
                        model: UserModel,
                        as: 'assigner',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                    },
                ],
                order: [['is_highlight', 'DESC'], ['plan_date', 'ASC']],
                limit,
                offset
            });

            // Get statistics for today's ad hoc tasks
            const allAdHocPlansToday = await PlanModel.findAll({
                where: {
                    user_id: userId,
                    is_active: true,
                    ...dateWhereClause
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        required: true,
                        where: {
                            task_type: 'ad_hoc',
                            is_active: true
                        },
                        attributes: []
                    }
                ],
                attributes: ['task_status']
            });

            const totalTasks = allAdHocPlansToday.length;
            const completedTasks = allAdHocPlansToday.filter((plan: any) => plan.task_status === 'completed').length;
            const pendingTasks = allAdHocPlansToday.filter((plan: any) => ['assigned', 'started'].includes(plan.task_status)).length;

            const adHocStats = {
                total_tasks: totalTasks,
                completed_tasks: completedTasks,
                pending_tasks: pendingTasks,
            };

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

            res.status(200).json({
                success: true,
                message: 'Today\'s Ad Hoc Tasks',
                task_statistics: adHocStats,
                data: paginatedResult.data,
                pagination: paginatedResult.pagination
            });

        } else {
            // Default behavior - current code logic
            //check the role of the user
            const userRole = (req.user as UserData).user_data.role_id;
            //get the roles from the role table
            const role = await db.RoleMaster.findOne({
                where: { id: userRole },
                attributes: ['role'],
            });
            let result,stats;
            const dateWhereClause = {
                plan_date: {
                    [Op.gte]: targetDate,
                    [Op.lt]: nextDate
                }
            };
            // If the role is management then start new if block
            // Get task counts
            const taskCounts = await PlanModel.findAll({
                attributes: [
                    // [db.sequelize.fn('COUNT', db.sequelize.col('*')), 'total_tasks'],
                    // [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status = 'completed' THEN 1 ELSE 0 END`)), 'completed_tasks'],
                   [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN task_status NOT IN ('completed','pending') THEN 1 ELSE 0 END`)), 'remaining_tasks'],
                    // [db.sequelize.fn('SUM', db.sequelize.literal(`CASE WHEN plan_released = true THEN 1 ELSE 0 END`)), 'released_tasks']
                ],
                where: { user_id: userId, ...dateWhereClause },
                raw: true
            });

            result = await PlanModel.findAndCountAll({
                where: {
                    user_id: userId,
                    is_active: true,
                    task_status: 'assigned',
                    ...dateWhereClause
                },
                include: [
                    {
                        model: TaskModel,
                        as: 'task',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                        include: [
                            {
                                model: ProjectMasterModel,
                                as: 'project',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                            {
                                model: ClientMasterModel,
                                as: 'client',
                                required: false,
                                attributes: {exclude: ['createdAt', 'updatedAt']},
                            },
                        ]

                    },
                    {
                        model: UserModel,
                        as: 'user',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt','token']},
                    },
                    {
                        model: UserModel,
                        as: 'assigner',
                        required: false,
                        attributes: {exclude: ['createdAt', 'updatedAt']},
                    },
                   
                ],
                order: [['is_highlight', 'DESC'], ['plan_date', 'ASC']],
                limit,
                offset,
            });

             // Format task statistics
             stats = {
                total_tasks: parseInt(taskCounts[0]?.total_tasks as string) || 0,
                completed_tasks: parseInt(taskCounts[0]?.completed_tasks as string) || 0,
                remaining_tasks: parseInt(taskCounts[0]?.remaining_tasks as string) || 0,
                released_tasks:parseInt(taskCounts[0]?.released_tasks as string) || 0,
                // completion_percentage: taskCounts[0]?.total_tasks ? 
                //     Math.round((parseInt(taskCounts[0].completed_tasks as string) / parseInt(taskCounts[0].total_tasks as string)) * 100) : 
                //     0
            };

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

           

            res.status(200).json({
                success: true,
                message: 'All Today PendingTasks',
                task_statistics: stats,
                data: paginatedResult.data,
                pagination: paginatedResult.pagination
            });
        }

    } catch (error) {
        console.error('Error fetching plans:', 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 Task Watchers List
export const getTaskWatchers = async (req: Request, res:Response): Promise<void> => {
    try {
        const { task_id } = req.query;

        if (!task_id) {
            res.status(404).json({ success: false, message: "Task Id is required." });
            return;
        }

        const today = new Date();
        today.setHours(0, 0, 0, 0);

        const task = await TaskModel.findOne({
            where: {
                id: task_id,
                is_active: true
            },
            include: [
                {
                    model: TaskWatchModel,
                    as: 'task_watchers',
                    required: false,
                    // where: {
                    //     is_active: true,
                    //     createdAt: {
                    //         [Op.gte]: today
                    //     }
                    // },
                    include: [
                        {
                            model: UserModel,
                            as: 'user',
                            required: false,
                            attributes: {exclude: ['createdAt', 'updatedAt','token']},
                        }
                    ]
                }
            ]
        });

        if (!task) {
            res.status(404).json({ success: false, message: "Task not found." });
            return;
        }

        res.status(200).json({
            success: true,
            data: task
        });
    } catch (error) {
        console.error('Error Fetching Task Watchers:', 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'
        });
    }
}