<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Activities extends CI_Controller
{

    public function __construct()
    {
        parent::__construct();
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method');
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE');
        // // avoiding preflight requests
        $method = $_SERVER['REQUEST_METHOD'];
        if ($method == "OPTIONS") {
            die();
        }

        $this->load->helper('form');
        $this->load->library('upload');
        $this->db->query("SET time_zone = '+03:00'");
    }
    

public function add_activity()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $outcome_id = $json_data['outcome_id'];
    $code = $json_data['code'] ?? 0.0;
    $name = $json_data['name'];
    $status = $json_data['status'] ?? 'Not Started';
    $created_at = $json_data['created_at'] ?? date('Y-m-d H:i:s');
    $location = $json_data['location'];
    $has_sub_activities = $json_data['has_sub_activities'] ?? 0;
    $has_follow_up_activities = $json_data['has_follow_up_activities'] ?? 0;
    $inCharges = $json_data['inCharges'] ?? null; // List of user IDs (array or string)
    $user_id = $json_data['user_id'];
    $months = $json_data['months'] ?? []; // Array of month names

    // Validate required fields
    if (empty($user_id) || empty($outcome_id) || empty($name)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_INPUT'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate outcome exists and is active
    $this->db->where('id', $outcome_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $outcome = $this->db->get('outcomes')->row_array();

    if (empty($outcome)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_OUTCOME'
            )));
    }

    // Validate status
    if (!in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_STATUS'
            )));
    }

    // Validate code (numeric, defaults to 0.0 if not provided)
    $code = floatval($code);

    // Validate progress (numeric string, defaults to '0')
    $progress = '0'; // Default to '0' as per your sample (not included in JSON but assumed)

    // Parse and validate inCharges (list of user IDs, similar to in_charge_ids for products)
    $inCharges_array = [];
    if ($inCharges !== null) {
        // Try to decode as JSON (e.g., "[9,10]" -> [9, 10])
        $parsed_ids = json_decode($inCharges, true);
        if (is_array($parsed_ids)) {
            $inCharges_array = array_filter(array_map('intval', $parsed_ids)); // Convert to integers, remove empty
        } else {
            // If not JSON, split by comma (e.g., "9,10" -> [9, 10])
            $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
            $inCharges_array = array_filter(array_map('trim', $ids), 'strlen'); // Clean and filter empty values
            $inCharges_array = array_map('intval', $inCharges_array); // Convert to integers
        }

        // Validate inCharges exist and are active
        if (!empty($inCharges_array)) {
            $this->db->where_in('id', $inCharges_array);
            $this->db->where('is_active', 1); // Assuming soft delete with is_active
            $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);

            if (!$users_exist) {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400) // Bad Request
                    ->set_output(json_encode(array(
                        'success' => false,
                        'message' => 'INVALID_INCHARGE_IDS'
                    )));
            }
        }
    } else {
        $inCharges_array = []; // Default to empty if not provided (no team members)
    }

    // Validate months (array of valid month names)
    $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    if (!empty($months) && !is_array($months)) {
        $months = explode(',', $months); // Handle comma-separated string if passed
    }
    $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
        return in_array($month, $valid_months);
    });
    if (empty($months)) {
        $months = []; // Default to empty if no valid months
    }

    // Validate created_at (optional, defaults to current timestamp if invalid)
    $created_at = date('Y-m-d H:i:s', strtotime($created_at)) ?: date('Y-m-d H:i:s');

    // Prepare data for insertion
    $data = [
        'outcome_id' => $outcome_id,
        'name' => $name,
        'code' => $code,
        'progress' => $progress,
        'status' => $status,
        'location' => $location,
        'has_sub_activities' => (int)$has_sub_activities,
        'has_follow_up_activities' => (int)$has_follow_up_activities,
        'inCharges' => !empty($inCharges_array) ? json_encode($inCharges_array) : json_encode([]), // Store as JSON array in inCharges column
        'created_by' => $user_id,
        'updated_by' => $user_id,
        'created_at' => $created_at,
        'is_active' => 1 // Default to active
    ];

    // Start a transaction to ensure data consistency
    $this->db->trans_start();

    // Insert the activity
    $insert = $this->db->insert('activities', $data);
    if (!$insert) {
        $this->db->trans_rollback();
        log_message('error', "Failed to insert activity: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACTIVITY_NOT_CREATED - ' . $this->db->error()['message']
            )));
    }

    $activity_id = $this->db->insert_id();

    // Insert activity months if provided
    if (!empty($months)) {
        $month_data = array_map(function($month) use ($activity_id, $user_id) {
            return [
                'activity_id' => $activity_id,
                'month' => $month,
                'created_by' => $user_id,
                'updated_by' => $user_id
            ];
        }, $months);

        $this->db->insert_batch('activity_months', $month_data);
        if ($this->db->affected_rows() === FALSE) {
            $this->db->trans_rollback();
            log_message('error', "Failed to insert activity months: " . $this->db->error()['message']);
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400) // Bad Request
                ->set_output(json_encode(array(
                    'success' => false,
                    'message' => 'ACTIVITY_MONTHS_NOT_CREATED - ' . $this->db->error()['message']
                )));
        }
    }

    // Commit the transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    // Prepare response data (format team as {"name": "Activity Team", "members": {}})
    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar'); // Assuming users table has these fields
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1); // Ensure users are active
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'], // Convert to string to match your response
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }

    // Structure the response with "team" as {"name": "Activity Team", "members": []}
    $team_response = [
        'name' => 'Activity Team',
        'members' => $inCharges_details
    ];

    $response_data = [
        'id' => (string)$activity_id, // Convert to string to match your response
        'progress' => $progress,
        'name' => $name,
        'code' => $code,
        'months' => $months,
        'team' => $team_response, // Updated to match {"name": "Activity Team", "members": {}}
        'status' => $status,
        'outcome' => $outcome['title'], // Use outcome title
        'created_at' => $created_at,
        'location' => $location,
        'followUpActivities' => [], // Placeholder
        'hasFollowUpActivities' => (bool)$has_follow_up_activities,
        'hasSubActivities' => (bool)$has_sub_activities,
        'subActivities' => [], // Placeholder
        'outputs' => [
            'status' => 'Not Started', // Placeholder, update as needed
            'comments' => [], // Placeholder
            'planned' => 0, // Placeholder
            'achieved' => 0, // Placeholder
            'list' => [] // Placeholder
        ],
        'comments' => [], // Placeholder
        'comments_count' => '0', // Default to 0 as string
        'products' => [], // Initially empty, products can be added separately
        'outputProducts' => [], // Initially empty, output products can be added separately
        'attachments' => [] // Placeholder
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201) // Created
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'ACTIVITY_CREATED_SUCCESSFULLY',
            'data' => $response_data
        )));
}

// public function edit_activity($id)
// {
//     // Get form data from JSON input
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $name = $json_data['name'];
//     $code = $json_data['code'];
//     $progress = $json_data['progress'] ?? 0;
//     $status = $json_data['status'];
//     $location = $json_data['location'];
//     $has_sub_activities = $json_data['has_sub_activities'];
//     $has_follow_up_activities = $json_data['has_follow_up_activities'];
//     $inCharges = $json_data['inCharges'] ?? null;
//     $user_id = $json_data['user_id'];
//     $months = $json_data['months'] ?? [];

//     // Validate required fields
//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate user exists
//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     // Validate activity exists and is active
//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $activity = $this->db->get('activities')->row_array();
//     if (empty($activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED']));
//     }

//     // Validate status if provided
//     if ($status && !in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//     }

//     // Validate code and progress
//     $code = $code !== null ? floatval($code) : $activity['code'];
//     $progress = $progress !== null && is_numeric($progress) ? (string)$progress : $activity['progress'];

//     // Validate has_sub_activities and has_follow_up_activities
//     $has_sub_activities = $has_sub_activities !== null ? (int)$has_sub_activities : $activity['has_sub_activities'];
//     $has_follow_up_activities = $has_follow_up_activities !== null ? (int)$has_follow_up_activities : $activity['has_follow_up_activities'];
//     if ($has_sub_activities === 1) {
//         $has_follow_up_activities = 0;
//     } elseif ($has_follow_up_activities === 1) {
//         $has_sub_activities = 0;
//     }

//     // Parse and validate inCharges
//     $inCharges_array = [];
//     if ($inCharges !== null) {
//         $parsed_ids = json_decode($inCharges, true);
//         if (is_array($parsed_ids)) {
//             $inCharges_array = array_filter(array_map('intval', $parsed_ids));
//         } else {
//             $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
//             $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
//             $inCharges_array = array_map('intval', $inCharges_array);
//         }
//         if (!empty($inCharges_array)) {
//             $this->db->where_in('id', $inCharges_array);
//             $this->db->where('is_active', 1);
//             $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
//             if (!$users_exist) {
//                 return $this->output
//                     ->set_content_type('application/json')
//                     ->set_status_header(400)
//                     ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
//             }
//         }
//     } else {
//         $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
//     }

//     // Validate months
//     $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
//     if (!empty($months) && !is_array($months)) {
//         $months = explode(',', $months);
//     }
//     $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
//         return in_array($month, $valid_months);
//     });
//     if (empty($months)) {
//         $this->db->select('month');
//         $this->db->where('activity_id', $id);
//         $this->db->where('is_active', 1);
//         $existing_months = $this->db->get('activity_months')->result_array();
//         $months = array_column($existing_months, 'month');
//     }

//     // Prepare data for update
//     $data = [];
//     if ($name) $data['name'] = $name;
//     if ($code !== null) $data['code'] = $code;
//     if ($progress !== null) $data['progress'] = $progress;
//     if ($status) $data['status'] = $status;
//     if ($location) $data['location'] = $location;
//     if ($has_sub_activities !== null) $data['has_sub_activities'] = $has_sub_activities;
//     if ($has_follow_up_activities !== null) $data['has_follow_up_activities'] = $has_follow_up_activities;
//     if (!empty($inCharges_array)) $data['inCharges'] = json_encode($inCharges_array);
//     $data['updated_by'] = $user_id;
//     $data['updated_at'] = date('Y-m-d H:i:s');

//     // Start transaction
//     $this->db->trans_start();

//     // Update the activity
//     $this->db->where('id', $id);
//     $update = $this->db->update('activities', $data);
//     if (!$update) {
//         $this->db->trans_rollback();
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']]));
//     }

//     // Handle activity months
//     if (!empty($months)) {
//         // Get all existing months (active and inactive) for this activity
//         $this->db->select('month, is_active');
//         $this->db->where('activity_id', $id);
//         $existing_months = $this->db->get('activity_months')->result_array();
//         $existing_months_map = array_column($existing_months, 'is_active', 'month');

//         // Categorize months
//         $new_months = [];
//         $months_to_reactivate = [];
//         $existing_active_months = [];

//         foreach ($months as $month) {
//             if (!isset($existing_months_map[$month])) {
//                 $new_months[] = $month; // Truly new month
//             } elseif ($existing_months_map[$month] == 0) {
//                 $months_to_reactivate[] = $month; // Inactive, reactivate
//             } else {
//                 $existing_active_months[] = $month; // Already active
//             }
//         }

//         // Insert new months
//         if (!empty($new_months)) {
//             $month_data = array_map(function($month) use ($id, $user_id) {
//                 return [
//                     'activity_id' => $id,
//                     'month' => $month,
//                     'created_by' => $user_id,
//                     'updated_by' => $user_id,
//                     'is_active' => 1
//                 ];
//             }, $new_months);
//             $this->db->insert_batch('activity_months', $month_data);
//         }

//         // Reactivate inactive months
//         if (!empty($months_to_reactivate)) {
//             $this->db->where('activity_id', $id);
//             $this->db->where_in('month', $months_to_reactivate);
//             $this->db->update('activity_months', [
//                 'is_active' => 1,
//                 'deleted_at' => null,
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }

//         // Deactivate months that are no longer selected
//         $months_to_delete = array_diff(array_keys($existing_months_map), $months);
//         if (!empty($months_to_delete)) {
//             $this->db->where('activity_id', $id);
//             $this->db->where_in('month', $months_to_delete);
//             $this->db->update('activity_months', [
//                 'is_active' => 0,
//                 'deleted_at' => date('Y-m-d H:i:s'),
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }
//     } else {
//         // If no months provided, deactivate all existing active months
//         $this->db->where('activity_id', $id);
//         $this->db->where('is_active', 1);
//         $this->db->update('activity_months', [
//             'is_active' => 0,
//             'deleted_at' => date('Y-m-d H:i:s'),
//             'updated_by' => $user_id,
//             'updated_at' => date('Y-m-d H:i:s')
//         ]);
//     }

//     // Check if this activity should be deactivated (e.g., no months left)
//     $this->db->where('activity_id', $id);
//     $this->db->where('is_active', 1);
//     $remaining_months = $this->db->get('activity_months')->num_rows();
//     if ($remaining_months == 0) {
//         $this->db->where('id', $id);
//         $this->db->update('activities', [
//             'is_active' => 0,
//             'deleted_at' => date('Y-m-d H:i:s'),
//             'updated_by' => $user_id,
//             'updated_at' => date('Y-m-d H:i:s')
//         ]);
//     }

//     // Commit transaction
//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//     }

//     // Fetch updated activity for response
//     $this->db->where('id', $id);
//     $updated_activity = $this->db->get('activities')->row_array();

//     if (empty($updated_activity) || $updated_activity['is_active'] == 0) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'ACTIVITY_DEACTIVATED_DUE_TO_NO_MONTHS']));
//     }

//     // Fetch related data
//     $this->db->select('o.title');
//     $this->db->where('o.id', $updated_activity['outcome_id']);
//     $outcome = $this->db->get('outcomes o')->row_array();

//     $this->db->select('month');
//     $this->db->where('activity_id', $id);
//     $this->db->where('is_active', 1);
//     $current_months = $this->db->get('activity_months')->result_array();
//     $months = array_column($current_months, 'month');

//     $inCharges_details = [];
//     if (!empty($inCharges_array)) {
//         $this->db->select('id, first_name, image as avatar');
//         $this->db->where_in('id', $inCharges_array);
//         $this->db->where('is_active', 1);
//         $users = $this->db->get('users')->result_array();
//         foreach ($users as $user) {
//             $inCharges_details[] = [
//                 'id' => (string)$user['id'],
//                 'first_name' => $user['first_name'],
//                 'avatar' => $user['avatar'] ?? ''
//             ];
//         }
//     }

//     $team_response = [
//         'name' => 'Activity Team',
//         'members' => $inCharges_details
//     ];

//     $response_data = [
//         'id' => (string)$updated_activity['id'],
//         'progress' => (string)$updated_activity['progress'],
//         'name' => $updated_activity['name'],
//         'code' => floatval($updated_activity['code']),
//         'months' => $months,
//         'team' => $team_response,
//         'status' => $updated_activity['status'],
//         'outcome' => $outcome['title'],
//         'created_at' => $updated_activity['created_at'],
//         'location' => $updated_activity['location'],
//         'followUpActivities' => [],
//         'hasFollowUpActivities' => (bool)$updated_activity['has_follow_up_activities'],
//         'hasSubActivities' => (bool)$updated_activity['has_sub_activities'],
//         'subActivities' => [],
//         'outputs' => $this->get_outputs_for_activity($id),
//         'comments' => [],
//         'comments_count' => (string)$updated_activity['comments_count'],
//         'products' => $this->get_products_for_activity($id),
//         'outputProducts' => $this->get_output_products_for_activity($id),
//         'attachments' => []
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'ACTIVITY_UPDATED_SUCCESSFULLY', 'data' => $response_data]));
// }

public function edit_activity($id)
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $name = $json_data['name'];
    $code = $json_data['code'];
    $progress = $json_data['progress'] ?? 0;
    $status = $json_data['status'];
    $location = $json_data['location'];
    $has_sub_activities = $json_data['has_sub_activities'];
    $has_follow_up_activities = $json_data['has_follow_up_activities'];
    $inCharges = $json_data['inCharges'] ?? null;
    $user_id = $json_data['user_id'];
    $months = $json_data['months'] ?? [];
    // NEW: Add isImplemented from JSON input, default to existing value if not provided
    $isImplemented = $json_data['isImplemented'] ?? null;

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Validate activity exists and is active
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $activity = $this->db->get('activities')->row_array();
    if (empty($activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED']));
    }

    // Validate status if provided
    if ($status && !in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
    }

    // Validate code and progress
    $code = $code !== null ? floatval($code) : $activity['code'];
    $progress = $progress !== null && is_numeric($progress) ? (string)$progress : $activity['progress'];

    // NEW: Validate isImplemented
    $isImplemented = $isImplemented !== null ? (int)(bool)$isImplemented : $activity['isImplemented'];

    // Validate has_sub_activities and has_follow_up_activities
    $has_sub_activities = $has_sub_activities !== null ? (int)$has_sub_activities : $activity['has_sub_activities'];
    $has_follow_up_activities = $has_follow_up_activities !== null ? (int)$has_follow_up_activities : $activity['has_follow_up_activities'];
    if ($has_sub_activities === 1) {
        $has_follow_up_activities = 0;
    } elseif ($has_follow_up_activities === 1) {
        $has_sub_activities = 0;
    }

    // Parse and validate inCharges
    $inCharges_array = [];
    if ($inCharges !== null) {
        $parsed_ids = json_decode($inCharges, true);
        if (is_array($parsed_ids)) {
            $inCharges_array = array_filter(array_map('intval', $parsed_ids));
        } else {
            $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
            $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
            $inCharges_array = array_map('intval', $inCharges_array);
        }
        if (!empty($inCharges_array)) {
            $this->db->where_in('id', $inCharges_array);
            $this->db->where('is_active', 1);
            $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
            if (!$users_exist) {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
            }
        }
    } else {
        $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
    }

    // Validate months
    $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    if (!empty($months) && !is_array($months)) {
        $months = explode(',', $months);
    }
    $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
        return in_array($month, $valid_months);
    });
    if (empty($months)) {
        $this->db->select('month');
        $this->db->where('activity_id', $id);
        $this->db->where('is_active', 1);
        $existing_months = $this->db->get('activity_months')->result_array();
        $months = array_column($existing_months, 'month');
    }

    // Prepare data for update
    $data = [];
    if ($name) $data['name'] = $name;
    if ($code !== null) $data['code'] = $code;
    if ($progress !== null) $data['progress'] = $progress;
    if ($status) $data['status'] = $status;
    if ($location) $data['location'] = $location;
    if ($has_sub_activities !== null) $data['has_sub_activities'] = $has_sub_activities;
    if ($has_follow_up_activities !== null) $data['has_follow_up_activities'] = $has_follow_up_activities;
    if (!empty($inCharges_array)) $data['inCharges'] = json_encode($inCharges_array);
    // NEW: Add isImplemented to update data
    $data['isImplemented'] = $isImplemented;
    $data['updated_by'] = $user_id;
    $data['updated_at'] = date('Y-m-d H:i:s');

    // Start transaction
    $this->db->trans_start();

    // Update the activity
    $this->db->where('id', $id);
    $update = $this->db->update('activities', $data);
    if (!$update) {
        $this->db->trans_rollback();
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']]));
    }

    // Handle activity months
    if (!empty($months)) {
        // Get all existing months (active and inactive) for this activity
        $this->db->select('month, is_active');
        $this->db->where('activity_id', $id);
        $existing_months = $this->db->get('activity_months')->result_array();
        $existing_months_map = array_column($existing_months, 'is_active', 'month');

        // Categorize months
        $new_months = [];
        $months_to_reactivate = [];
        $existing_active_months = [];

        foreach ($months as $month) {
            if (!isset($existing_months_map[$month])) {
                $new_months[] = $month; // Truly new month
            } elseif ($existing_months_map[$month] == 0) {
                $months_to_reactivate[] = $month; // Inactive, reactivate
            } else {
                $existing_active_months[] = $month; // Already active
            }
        }

        // Insert new months
        if (!empty($new_months)) {
            $month_data = array_map(function($month) use ($id, $user_id) {
                return [
                    'activity_id' => $id,
                    'month' => $month,
                    'created_by' => $user_id,
                    'updated_by' => $user_id,
                    'is_active' => 1
                ];
            }, $new_months);
            $this->db->insert_batch('activity_months', $month_data);
        }

        // Reactivate inactive months
        if (!empty($months_to_reactivate)) {
            $this->db->where('activity_id', $id);
            $this->db->where_in('month', $months_to_reactivate);
            $this->db->update('activity_months', [
                'is_active' => 1,
                'deleted_at' => null,
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        // Deactivate months that are no longer selected
        $months_to_delete = array_diff(array_keys($existing_months_map), $months);
        if (!empty($months_to_delete)) {
            $this->db->where('activity_id', $id);
            $this->db->where_in('month', $months_to_delete);
            $this->db->update('activity_months', [
                'is_active' => 0,
                'deleted_at' => date('Y-m-d H:i:s'),
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }
    } else {
        // If no months provided, deactivate all existing active months
        $this->db->where('activity_id', $id);
        $this->db->where('is_active', 1);
        $this->db->update('activity_months', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
    }

    // Check if this activity should be deactivated (e.g., no months left)
    $this->db->where('activity_id', $id);
    $this->db->where('is_active', 1);
    $remaining_months = $this->db->get('activity_months')->num_rows();
    if ($remaining_months == 0) {
        $this->db->where('id', $id);
        $this->db->update('activities', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
    }

    // Commit transaction
    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
    }

    // Fetch updated activity for response
    $this->db->where('id', $id);
    $updated_activity = $this->db->get('activities')->row_array();

    if (empty($updated_activity) || $updated_activity['is_active'] == 0) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'ACTIVITY_DEACTIVATED_DUE_TO_NO_MONTHS']));
    }

    // Fetch related data
    $this->db->select('o.title');
    $this->db->where('o.id', $updated_activity['outcome_id']);
    $outcome = $this->db->get('outcomes o')->row_array();

    $this->db->select('month');
    $this->db->where('activity_id', $id);
    $this->db->where('is_active', 1);
    $current_months = $this->db->get('activity_months')->result_array();
    $months = array_column($current_months, 'month');

    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1);
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'],
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }

    $team_response = [
        'name' => 'Activity Team',
        'members' => $inCharges_details
    ];

    $response_data = [
        'id' => (string)$updated_activity['id'],
        'progress' => (string)$updated_activity['progress'],
        'name' => $updated_activity['name'],
        'code' => floatval($updated_activity['code']),
        'months' => $months,
        'team' => $team_response,
        'status' => $updated_activity['status'],
        'outcome' => $outcome['title'],
        'created_at' => $updated_activity['created_at'],
        'location' => $updated_activity['location'],
        'followUpActivities' => [],
        'hasFollowUpActivities' => (bool)$updated_activity['has_follow_up_activities'],
        'hasSubActivities' => (bool)$updated_activity['has_sub_activities'],
        'subActivities' => [],
        'outputs' => $this->get_outputs_for_activity($id),
        'comments' => [],
        'comments_count' => (string)$updated_activity['comments_count'],
        'products' => $this->get_products_for_activity($id),
        'outputProducts' => $this->get_output_products_for_activity($id),
        'attachments' => [],
        // NEW: Include isImplemented in response
        'isImplemented' => (bool)$updated_activity['isImplemented']
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'ACTIVITY_UPDATED_SUCCESSFULLY', 'data' => $response_data]));
}



public function get_all_activities()
{
    // Validate user_id (assuming it's passed via GET or form for authentication)
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }
    
       $this->db->where('id',$user_id);
   $this->db->set('last_login_ip', $_SERVER['REMOTE_ADDR']);
   $this->db->set('last_login_at', date('Y-m-d\TH:i:s.u\Z'));
   $this->db->update('users');

    // Get country from input (required)
    $country_code = $this->input->get('country');
    if (empty($country_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_COUNTRY'
            )));
    }

    // Get programme from input (required)
    $programme_code = $this->input->get('programme');
    if (empty($programme_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PROGRAMME'
            )));
    }

    // Get year from input (required)
    $year = $this->input->get('year');
    if (empty($year) || !is_numeric($year) || strlen($year) !== 4) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR'
            )));
    }

    // Get country ID from countries table
    $this->db->select('id');
    $this->db->where('code', $country_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $country_record = $this->db->get('countries')->row_array();

    if (empty($country_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'COUNTRY_NOT_FOUND'
            )));
    }

    $country_id = $country_record['id'];

    // Get programme ID from programmes table
    $this->db->select('id');
    $this->db->where('country_id', $country_id);
    $this->db->where('code', $programme_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $programme_record = $this->db->get('programmes')->row_array();

    if (empty($programme_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRAMME_NOT_FOUND'
            )));
    }

    $programme_id = $programme_record['id'];

    // Get year ID from years table
    $this->db->select('id');
    $this->db->where('programme_id', $programme_id);
    $this->db->where('year', $year);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $year_record = $this->db->get('years')->row_array();

    if (empty($year_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'YEAR_NOT_FOUND'
            )));
    }

    $year_id = $year_record['id'];

    // Get all quarters for the year
    $this->db->select('id, quarter');
    $this->db->where('year_id', $year_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $quarters = $this->db->get('quarters')->result_array();

    // Prepare the response structure
    $response_data = [
        'country' => $country_code,
        'programme' => $programme_code,
        'year' => $year,
        'quarters' => []
    ];

    foreach ($quarters as $quarter) {
        // Get outcomes for the quarter
        $this->db->select('id, title, progress');
        $this->db->where('quarter_id', $quarter['id']);
        $this->db->where('is_active', 1); // Assuming soft delete with is_active
        $outcomes = $this->db->get('outcomes')->result_array();

        $quarter_data = [
            'quarter' => $quarter['quarter'],
            'outcomes' => []
        ];

        foreach ($outcomes as $outcome) {
            // Get activities for the outcome
            $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location, a.has_sub_activities, a.isImplemented, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
            $this->db->where('a.outcome_id', $outcome['id']);
            $this->db->where('a.is_active', 1); // Assuming soft delete with is_active
            $activities = $this->db->get('activities a')->result_array();

            $outcome_data = [
                'id' => (string)$outcome['id'], // Convert to string to match your response
                'title' => $outcome['title'],
                'progress' => (string)$outcome['progress'],
                'activities' => []
            ];

            foreach ($activities as $activity) {
                // Parse inCharges from JSON
                $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
                $inCharges_array = array_filter(array_map('intval', $inCharges_array));

                // Get inCharges details for the response
                $inCharges_details = [];
                if (!empty($inCharges_array)) {
                    $this->db->select('id, first_name, image as avatar');
                    $this->db->where_in('id', $inCharges_array);
                    $this->db->where('is_active', 1); // Ensure users are active
                    $users = $this->db->get('users')->result_array();
                    foreach ($users as $user) {
                        $inCharges_details[] = [
                            'id' => (string)$user['id'], // Convert to string to match your response
                            'first_name' => $user['first_name'],
                            'avatar' => $user['avatar'] ?? ''
                        ];
                    }
                }

                // Structure the response with "team" as {"name": "Activity Team", "members": []}
                $team_response = [
                    'name' => 'Activity Team',
                    'members' => $inCharges_details
                ];

                $activity_data = [
                    'id' => (string)$activity['id'], // Convert to string to match your response
                    'progress' => (string)$activity['progress'],
                    'name' => $activity['name'],
                    'code' => floatval($activity['code']), // Convert decimal to float
                    'months' => $this->get_activity_months($activity['id']), // Fetch months from activity_months, ordered
                    'team' => $team_response, // Updated to match {"name": "Activity Team", "members": {}}
                    'status' => $activity['status'],
                    'outcome' => $outcome['title'], // Use outcome title directly
                    'created_at' => $activity['created_at'],
                    'location' => $activity['location'],
                    'followUpActivities' => [], // Placeholder for future implementation
                    'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
                    'hasSubActivities' => (bool)$activity['has_sub_activities'],
                    'isImplemented' =>(bool)$activity['isImplemented'],
                    'subActivities' => [], // Placeholder for future implementation
                    'outputs' => $this->get_outputs_for_activity($activity['id']),
                    'comments' => [], // Placeholder
                    'comments_count' => (string)$activity['comments_count'], // Convert to string to match your response
                    'products' => $this->get_products_for_activity($activity['id']), // Populate products
                    'outputProducts' => $this->get_output_products_for_activity($activity['id']), // Placeholder for future implementation
                    'attachments' => [] // Placeholder for future implementation
                ];
                $outcome_data['activities'][] = $activity_data;
            }

            $quarter_data['outcomes'][] = $outcome_data;
        }

        $response_data['quarters'][] = $quarter_data;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'ACTIVITIES_RETRIEVED_SUCCESSFULLY',
            'data' => $response_data
        )));
}

public function get_all_activities_with_subactivities()
{
    // Validate user_id (assuming it's passed via GET or form for authentication)
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }
    
       $this->db->where('id',$user_id);
   $this->db->set('last_login_ip', $_SERVER['REMOTE_ADDR']);
   $this->db->set('last_login_at', date('Y-m-d\TH:i:s.u\Z'));
   $this->db->update('users');

    // Get country from input (required)
    $country_code = $this->input->get('country');
    if (empty($country_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_COUNTRY'
            )));
    }

    // Get programme from input (required)
    $programme_code = $this->input->get('programme');
    if (empty($programme_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PROGRAMME'
            )));
    }

    // Get year from input (required)
    $year = $this->input->get('year');
    if (empty($year) || !is_numeric($year) || strlen($year) !== 4) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR'
            )));
    }

    // Get country ID from countries table
    $this->db->select('id');
    $this->db->where('code', $country_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $country_record = $this->db->get('countries')->row_array();

    if (empty($country_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'COUNTRY_NOT_FOUND'
            )));
    }

    $country_id = $country_record['id'];

    // Get programme ID from programmes table
    $this->db->select('id');
    $this->db->where('country_id', $country_id);
    $this->db->where('code', $programme_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $programme_record = $this->db->get('programmes')->row_array();

    if (empty($programme_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRAMME_NOT_FOUND'
            )));
    }

    $programme_id = $programme_record['id'];

    // Get year ID from years table
    $this->db->select('id');
    $this->db->where('programme_id', $programme_id);
    $this->db->where('year', $year);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $year_record = $this->db->get('years')->row_array();

    if (empty($year_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'YEAR_NOT_FOUND'
            )));
    }

    $year_id = $year_record['id'];

    // Get all quarters for the year
    $this->db->select('id, quarter');
    $this->db->where('year_id', $year_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $quarters = $this->db->get('quarters')->result_array();

    // Prepare the response structure
    $response_data = [
        'country' => $country_code,
        'programme' => $programme_code,
        'year' => $year,
        'quarters' => []
    ];

    foreach ($quarters as $quarter) {
        // Get outcomes for the quarter
        $this->db->select('id, title, progress');
        $this->db->where('quarter_id', $quarter['id']);
        $this->db->where('is_active', 1); // Assuming soft delete with is_active
        $outcomes = $this->db->get('outcomes')->result_array();

        $quarter_data = [
            'quarter' => $quarter['quarter'],
            'outcomes' => []
        ];

        foreach ($outcomes as $outcome) {
            // Get activities for the outcome
            $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location, a.has_sub_activities, a.isImplemented, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
            $this->db->where('a.outcome_id', $outcome['id']);
            $this->db->where('a.is_active', 1); // Assuming soft delete with is_active
            $activities = $this->db->get('activities a')->result_array();

            $outcome_data = [
                'id' => (string)$outcome['id'], // Convert to string to match your response
                'title' => $outcome['title'],
                'progress' => (string)$outcome['progress'],
                'activities' => []
            ];

            foreach ($activities as $activity) {
                // Parse inCharges from JSON
                $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
                $inCharges_array = array_filter(array_map('intval', $inCharges_array));

                // Get inCharges details for the response
                $inCharges_details = [];
                if (!empty($inCharges_array)) {
                    $this->db->select('id, first_name, image as avatar');
                    $this->db->where_in('id', $inCharges_array);
                    $this->db->where('is_active', 1); // Ensure users are active
                    $users = $this->db->get('users')->result_array();
                    foreach ($users as $user) {
                        $inCharges_details[] = [
                            'id' => (string)$user['id'], // Convert to string to match your response
                            'first_name' => $user['first_name'],
                            'avatar' => $user['avatar'] ?? ''
                        ];
                    }
                }

                // Structure the response with "team" as {"name": "Activity Team", "members": []}
                $team_response = [
                    'name' => 'Activity Team',
                    'members' => $inCharges_details
                ];

                $activity_data = [
                    'id' => (string)$activity['id'], // Convert to string to match your response
                    'progress' => (string)$activity['progress'],
                    'name' => $activity['name'],
                    'code' => floatval($activity['code']), // Convert decimal to float
                    'months' => $this->get_activity_months($activity['id']), // Fetch months from activity_months, ordered
                    'team' => $team_response, // Updated to match {"name": "Activity Team", "members": {}}
                    'status' => $activity['status'],
                    'outcome' => $outcome['title'], // Use outcome title directly
                    'created_at' => $activity['created_at'],
                    'location' => $activity['location'],
                    'followUpActivities' => [], // Placeholder for future implementation
                    'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
                    'hasSubActivities' => (bool)$activity['has_sub_activities'],
                    'isImplemented' =>(bool)$activity['isImplemented'],
                    'subActivities' => $this->get_sub_activities($activity['id']), // Placeholder for future implementation
                    'outputs' => $this->get_outputs_for_activity($activity['id']),
                    'comments' => [], // Placeholder
                    'comments_count' => (string)$activity['comments_count'], // Convert to string to match your response
                    'products' => $this->get_products_for_activity($activity['id']), // Populate products
                    'outputProducts' => $this->get_output_products_for_activity($activity['id']), // Placeholder for future implementation
                    'attachments' => [] // Placeholder for future implementation
                ];
                $outcome_data['activities'][] = $activity_data;
            }

            $quarter_data['outcomes'][] = $outcome_data;
        }

        $response_data['quarters'][] = $quarter_data;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'ACTIVITIES_RETRIEVED_SUCCESSFULLY',
            'data' => $response_data
        )));
}



// based on current month
public function get_quarter_activities()
{
    // Validate user_id (assuming it's passed via GET or form for authentication)
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Get country from input (required)
    $country_code = $this->input->get('country');
    if (empty($country_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_COUNTRY'
            )));
    }

    // Get programme from input (required)
    $programme_code = $this->input->get('programme');
    if (empty($programme_code)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PROGRAMME'
            )));
    }

    // Get year from input (required)
    $year = $this->input->get('year');
    if (empty($year) || !is_numeric($year) || strlen($year) !== 4) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR'
            )));
    }

    // Get quarter from input (required)
    $quarter = $this->input->get('quarter');
    if (empty($quarter) || !preg_match('/^Q[1-4]$/', $quarter)) { // Ensure quarter is Q1, Q2, Q3, or Q4
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_QUARTER'
            )));
    }

    // Get country ID from countries table
    $this->db->select('id');
    $this->db->where('code', $country_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $country_record = $this->db->get('countries')->row_array();

    if (empty($country_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'COUNTRY_NOT_FOUND'
            )));
    }

    $country_id = $country_record['id'];

    // Get programme ID from programmes table
    $this->db->select('id');
    $this->db->where('country_id', $country_id);
    $this->db->where('code', $programme_code);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $programme_record = $this->db->get('programmes')->row_array();

    if (empty($programme_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRAMME_NOT_FOUND'
            )));
    }

    $programme_id = $programme_record['id'];

    // Get year ID from years table
    $this->db->select('id');
    $this->db->where('programme_id', $programme_id);
    $this->db->where('year', $year);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $year_record = $this->db->get('years')->row_array();

    if (empty($year_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'YEAR_NOT_FOUND'
            )));
    }

    $year_id = $year_record['id'];

    // Get quarter ID from quarters table
    $this->db->select('id');
    $this->db->where('year_id', $year_id);
    $this->db->where('quarter', $quarter);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $quarter_record = $this->db->get('quarters')->row_array();

    if (empty($quarter_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'QUARTER_NOT_FOUND'
            )));
    }

    $quarter_id = $quarter_record['id'];

    // Get outcomes for the quarter
    $this->db->select('id, title, progress');
    $this->db->where('quarter_id', $quarter_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $outcomes = $this->db->get('outcomes')->result_array();

    // Define quarter months
    $quarter_months = [
        'Q1' => ['January', 'February', 'March'],
        'Q2' => ['April', 'May', 'June'],
        'Q3' => ['July', 'August', 'September'],
        'Q4' => ['October', 'November', 'December']
    ];

    $current_quarter_months = $quarter_months[$quarter]; // e.g., Q2 -> ["April", "May", "June"]

    // Prepare the response structure
    $response_data = [
        'country' => $country_code,
        'programme' => $programme_code,
        'year' => $year,
        'quarter' => $quarter,
        'outcomes' => []
    ];

    foreach ($outcomes as $outcome) {
        // Get activities for the outcome
        $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location,a.isImplemented, a.has_sub_activities, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
        $this->db->where('a.outcome_id', $outcome['id']);
        $this->db->where('a.is_active', 1); // Assuming soft delete with is_active
         $this->db->order_by('a.code', 'ASC');
        $activities = $this->db->get('activities a')->result_array();

        $outcome_data = [
            'id' => (string)$outcome['id'],
            'title' => $outcome['title'],
            'progress' => (string)$outcome['progress'],
            'activities' => []
        ];

        foreach ($activities as $activity) {
            // Parse inCharges from JSON
            $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
            $inCharges_array = array_filter(array_map('intval', $inCharges_array));

            // Get inCharges details for the response
            $inCharges_details = [];
            if (!empty($inCharges_array)) {
                $this->db->select('id, first_name, image as avatar');
                $this->db->where_in('id', $inCharges_array);
                $this->db->where('is_active', 1); // Ensure users are active
                $users = $this->db->get('users')->result_array();
                foreach ($users as $user) {
                    $inCharges_details[] = [
                        'id' => (string)$user['id'],
                        'first_name' => $user['first_name'],
                        'avatar' => $user['avatar'] ?? ''
                    ];
                }
            }

            // Structure the response with "team"
            $team_response = [
                'name' => 'Activity Team',
                'members' => $inCharges_details
            ];

            // Get activity months
            $activity_months = $this->get_activity_months($activity['id']); // e.g., ["May", "June"]

            // Check flags
            $has_sub_activities = (bool)$activity['has_sub_activities'];
            $has_follow_up_activities = (bool)$activity['has_follow_up_activities'];

            // Determine has_planned_activities
            $has_planned_activities = "N/A"; // Default for no sub/follow-up activities
            if ($has_sub_activities || $has_follow_up_activities) {
                // Check if any activity months intersect with the quarter months
                $months_in_quarter = !empty(array_intersect($activity_months, $current_quarter_months));

                if ($months_in_quarter) {
                    // Check for actual sub-activities and follow-up activities
                    $has_planned_activities = false; // Default to false unless proven otherwise

                    if ($has_sub_activities) {
                        $this->db->where('parent_activity_id', $activity['id']);
                        $this->db->where('is_active', 1);
                        $sub_activities_count = $this->db->count_all_results('sub_activities');
                        if ($sub_activities_count > 0) {
                            $has_planned_activities = true;
                        }
                    }

                    if ($has_follow_up_activities && !$has_planned_activities) { // Only check if not already true
                        $this->db->where('parent_activity_id', $activity['id']);
                        $this->db->where('is_active', 1);
                        $follow_up_activities_count = $this->db->count_all_results('follow_up_activities');
                        if ($follow_up_activities_count > 0) {
                            $has_planned_activities = true;
                        }
                    }
                }
            }

            $activity_data = [
                'id' => (string)$activity['id'],
                'progress' => (string)$activity['progress'],
                'name' => $activity['name'],
                'code' => floatval($activity['code']),
                'months' => $activity_months,
                'team' => $team_response,
                'status' => $activity['status'],
                'outcome' => $outcome['title'],
                'created_at' => $activity['created_at'],
                'isImplemented' => (bool)$activity['isImplemented'],
                'location' => $activity['location'],
                'followUpActivities' => [], // Empty as requested
                'hasFollowUpActivities' => $has_follow_up_activities,
                'hasSubActivities' => $has_sub_activities,
                'subActivities' => [], // Empty as requested
                'outputs' => $this->get_outputs_for_activity($activity['id']),
                'comments' => $this->get_comments('activity', $activity['id']),
                'comments_count' => (string)$activity['comments_count'],
                'products' => $this->get_products_for_activity($activity['id']),
                'outputProducts' => $this->get_output_products_for_activity($activity['id']),
                'attachments' => [],
                'has_planned_activities' => $has_planned_activities // New property, "N/A" or true/false
            ];
            $outcome_data['activities'][] = $activity_data;
        }

        $response_data['outcomes'][] = $outcome_data;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'QUARTER_ACTIVITIES_RETRIEVED_SUCCESSFULLY',
            'data' => $response_data
        )));
}


public function get_activity_($id)
{
    // Validate user_id (assuming it's passed via form or session for authentication)
    $user_id = $this->input->get('user_id') ?? $this->session->userdata('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Get the activity by ID
    $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location, a.has_sub_activities, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
    $this->db->where('a.id', $id);
    $this->db->where('a.is_active', 1); // Assuming soft delete with is_active
    $activity = $this->db->get('activities a')->row_array();

    if (empty($activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACTIVITY_NOT_FOUND'
            )));
    }

    // Get outcomes for mapping outcome titles
    $this->db->select('id, title');
    $outcomes = $this->db->get('outcomes')->result_array();
    $outcome_map = array_column($outcomes, 'title', 'id');

    // Parse inCharges from JSON
    $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
    $inCharges_array = array_filter(array_map('intval', $inCharges_array));

    // Get inCharges details for the response
    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1); // Ensure users are active
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'], // Convert to string to match your response
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }

    // Structure the response with "team" as {"name": "Activity Team", "members": []}
    $team_response = [
        'name' => 'Activity Team',
        'members' => $inCharges_details
    ];

    // Prepare activity data
    $activity_data = [
        'id' => $activity['id'],
        'progress' => $activity['progress'],
        'name' => $activity['name'],
        'code' => floatval($activity['code']), // Convert decimal to float
        'months' => $this->get_activity_months($activity['id']), // Fetch months from activity_months
        'team' => $team_response, // Updated to match {"name": "Activity Team", "members": {}}
        'status' => $activity['status'],
        'outcome' => $outcome_map[$activity['outcome_id']] ?? 'Unknown Outcome', // Map outcome ID to title
        'created_at' => $activity['created_at'],
        'location' => $activity['location'],
        'followUpActivities' => [], // Placeholder for future implementation
        'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
        'hasSubActivities' => (bool)$activity['has_sub_activities'],
        'subActivities' => [], // Placeholder for future implementation
        'outputs' => $this->get_outputs_for_activity($activity['id']),
        'comments' => [], // Placeholder
        'comments_count' => $activity['comments_count'],
        'products' => $this->get_products_for_activity($activity['id']), // Populate products
        'outputProducts' => $this->get_output_products_for_activity($activity['id']), // Placeholder for future implementation
        'attachments' => [] // Placeholder for future implementation
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'ACTIVITY_RETRIEVED_SUCCESSFULLY',
            'data' => $activity_data
        )));
}

// Helper function to get months for an activity
private function get_activity_months($activity_id)
{
    $this->db->select('month');
    $this->db->where('activity_id', $activity_id);
    $this->db->where('is_active', 1);
    
    $months = $this->db->get('activity_months')->result_array();

    // Define the order of months (1-based index for sorting)
    $month_order = [
        'January' => 1,
        'February' => 2,
        'March' => 3,
        'April' => 4,
        'May' => 5,
        'June' => 6,
        'July' => 7,
        'August' => 8,
        'September' => 9,
        'October' => 10,
        'November' => 11,
        'December' => 12
    ];

    // Extract month names from the result
    $month_names = array_column($months, 'month');

    // Sort months based on their numerical order
    usort($month_names, function($a, $b) use ($month_order) {
        return $month_order[$a] - $month_order[$b];
    });

    return $month_names;
}

// Helper function to get team details (name and members)
private function get_team_details($team_id)
{
    if (!$team_id) return ['name' => '', 'members' => []];

    $this->db->select('t.name');
    $this->db->where('t.id', $team_id);
    $team = $this->db->get('teams t')->row_array();

    $this->db->select('u.id, u.first_name, u.image as avatar');
    $this->db->join('team_members tm', 'tm.user_id = u.id');
    $this->db->where('tm.team_id', $team_id);
    $members = $this->db->get('users u')->result_array();

    $member_data = [];
    foreach ($members as $member) {
        $member_data[] = [
            'id' => $member['id'],
            'first_name' => $member['first_name'],
            'avatar' => $member['avatar'] ?? ''
        ];
    }

    return [
        'name' => $team['name'] ?? 'No Team',
        'members' => $member_data
    ];
}

private function get_products_for_activity($activity_id,$isActiveOnAnnual=0)
{
    $this->db->select('p.id, p.name, p.type, p.url, p.status,p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type,p.activity_id');
     $this->db->where('p.group', 'general');
    $this->db->where('p.activity_id', $activity_id);
    $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
    if($isActiveOnAnnual) // only calls if $isActiveOnAnnual=0
    $this->db->where('p.isActiveOnAnnual',$isActiveOnAnnual);
    $products = $this->db->get('products p')->result_array();

    $products_data = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = [];
        if (!empty($in_charge_ids)) {
            $this->db->select('id, first_name, image as avatar');
            $this->db->where_in('id', $in_charge_ids);
            $users = $this->db->get('users')->result_array();
            foreach ($users as $user) {
                $in_charge[] = [
                    'id' => (string)$user['id'], // Convert to string to match your response
                    'first_name' => $user['first_name'],
                    'avatar' => $user['avatar'] ?? ''
                ];
            }
        }

        $product_data = [
            'id' => (string)$product['id'], // Convert to string to match your response
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'parent_activity_id'=>$product['activity_id'],
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'isUrgent' =>(bool)$product['isUrgent'] ?? false,
            'isRequiredToProceed' =>(bool)$product['isRequiredToProceed'] ?? false,
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'comments'=>$this->get_comments('activity_product', $product['id']),
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null // Add prod_type ID to the response
        ];

        // If it's a folder product, include files
        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1); // Assuming soft delete with is_active
            $files_data = $this->db->get('product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'], // Convert to string to match your response
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $products_data[] = $product_data;
    }

    return $products_data;
}

private function get_output_products_for_activity($activity_id, $isActiveOnAnnual=0)
{
    $this->db->select('p.id, p.name, p.type, p.url, p.status, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
    $this->db->where('p.activity_id', $activity_id);
    $this->db->where('p.group', 'output');
    $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
    if($isActiveOnAnnual) // only calls if $isActiveOnAnnual=1
    $this->db->where('p.isActiveOnAnnual',$isActiveOnAnnual);
    $products = $this->db->get('products p')->result_array();

    $output_products = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = [];
        if (!empty($in_charge_ids)) {
            $this->db->select('id, first_name, image as avatar');
            $this->db->where_in('id', $in_charge_ids);
            $users = $this->db->get('users')->result_array();
            foreach ($users as $user) {
                $in_charge[] = [
                    'id' => (string)$user['id'], // Convert to string to match your response
                    'first_name' => $user['first_name'],
                    'avatar' => $user['avatar'] ?? ''
                ];
            }
        }

        $product_data = [
            'id' => (string)$product['id'], // Convert to string to match your response
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null, // Add prod_type ID to the response
             'comments'=>$this->get_comments('activity_output_product', $product['id'])
        ];

        // If it's a folder product, include files
        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1); // Assuming soft delete with is_active
            $files_data = $this->db->get('product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'], // Convert to string to match your response
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $output_products[] = $product_data;
    }

    return $output_products;
}

//URGENT PRODUCTS

public function get_all_products (){
     // prepare urgent products [main,sub] -- include activity data (id,code,name,quarter[this is got from the outcome relationship])
     // prepare not urgent products [main,sub -- include activity data (id,code,name,quarter[this is got from the outcome relationship]) for sub --include sub-data
     // prepare urgent attachments [main,sub] -- include activity data (id,code,name,quarter[this is got from the outcome relationship] for sub --include sub-data
     // ensure all these are obtained from active Activity or Sub activity
     
     
      $urgent_products = [
            'main' => $this->get_activity_products(1),
            'sub' => $this->get_sub_activity_products_(1),
            // 'follow_up' => $this->get_follow_up_activity_products_(1)
        ];

        $not_urgent_products = [
            'main' => $this->get_activity_products(0),
            'sub' => $this->get_sub_activity_products_(0),
            // 'follow_up' => $this->get_follow_up_activity_products_(0)
        ];

        // Fetch urgent and non-urgent attachments
        $urgent_attachments = [
            'main' => $this->get_attachments_for_activity_(1),
            'sub' => $this->get_attachments_for_sub_activity_(1),
            'follow_up' => $this->get_attachments_for_follow_up_activity_(1)
        ];

        $non_urgent_attachments = [
            'main' => $this->get_attachments_for_activity_(0),
            'sub' => $this->get_attachments_for_sub_activity_(0),
            'follow_up' => $this->get_attachments_for_follow_up_activity_(0)
        ];

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'PRODUCTS_FETCHED_SUCCESSFULLY',
                'data' => [
                    'urgent_products' => $urgent_products,
                    'not_urgent_products' => $not_urgent_products,
                    'urgent_attachments' => $urgent_attachments,
                    'non_urgent_attachments' => $non_urgent_attachments
                ]
            ]));
    }

     
     
    
     
 
// private function get_activity_products($urgency=0)
// {
//     $this->db->select('p.id, p.activity_id, p.name, p.type, p.url, p.status,p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
//      $this->db->where('p.group', 'general');
//     $this->db->where('p.isUrgent', $urgency);
//     $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
//     $products = $this->db->get('products p')->result_array();

//     $products_data = [];
//     foreach ($products as $product) {
//         $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
//         $in_charge = [];
//         if (!empty($in_charge_ids)) {
//             $this->db->select('id, first_name, image as avatar');
//             $this->db->where_in('id', $in_charge_ids);
//             $users = $this->db->get('users')->result_array();
//             foreach ($users as $user) {
//                 $in_charge[] = [
//                     'id' => (string)$user['id'], // Convert to string to match your response
//                     'first_name' => $user['first_name'],
//                     'avatar' => $user['avatar'] ?? ''
//                 ];
//             }
//         }

//         $product_data = [
//             'id' => (string)$product['id'], // Convert to string to match your response
//             'name' => $product['name'],
//             'type' => $product['type'] ?? '',
//             'url' => $product['url'] ?? '',
//             'inCharge' => $in_charge,
//             'status' => $product['status'] ?? 'Pending',
//             'isUrgent' =>(bool)$product['isUrgent'] ?? false,
//             'dateSubmitted' => $product['date_submitted'] ?? '',
//             'comments'=>$this->get_comments('activity_product', $product['id']),
//             'lastUpdated' => $product['last_updated'] ?? '',
//             'prod_type' => $product['prod_type'] ?? null // Add prod_type ID to the response
//         ];

//         // If it's a folder product, include files
//         if ($product['type'] === 'folder') {
//             $this->db->where('product_id', $product['id']);
//             $this->db->where('is_active', 1); // Assuming soft delete with is_active
//             $files_data = $this->db->get('product_files')->result_array();
//             $files = [];
//             foreach ($files_data as $file) {
//                 $files[] = [
//                     'id' => (string)$file['id'], // Convert to string to match your response
//                     'name' => $file['name'],
//                     'type' => $file['type'],
//                     'url' => $file['url'],
//                     'date' => $file['date'],
//                     'size' => $file['size']
//                 ];
//             }
//             $product_data['files'] = $files;
//         }

//         $products_data[] = $product_data;
//     }
    
//     return $products_data;
// }

private function get_activity_products($urgency = 0) {
        $this->db->select('p.id, p.activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
                           a.code, a.name AS activity_name, q.quarter, y.year');
        $this->db->from('products p');
        $this->db->join('activities a', 'p.activity_id = a.id', 'inner');
        $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
         $this->db->join('years y', 'q.year_id = y.id', 'inner');
        $this->db->where('p.group', 'general');
        $this->db->where('p.isUrgent', $urgency);
        $this->db->where('p.is_active', 1);
       $this->db->where_in('p.status', ['Review', 'Submitted']);
       $this->db->where('p.type !=', 'folder');
        $this->db->where('a.is_active', 1);
        $products = $this->db->get()->result_array();

        $products_data = [];
        foreach ($products as $product) {
            $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
            $in_charge = [];
            if (!empty($in_charge_ids)) {
                $this->db->select('id, first_name, image AS avatar');
                $this->db->where_in('id', $in_charge_ids);
                $users = $this->db->get('users')->result_array();
                foreach ($users as $user) {
                    $in_charge[] = [
                        'id' => (string)$user['id'],
                        'first_name' => $user['first_name'],
                        'avatar' => $user['avatar'] ?? ''
                    ];
                }
            }

            $product_data = [
                'id' => (string)$product['id'],
                'name' => $product['name'],
                'type' => $product['type'] ?? '',
                'url' => $product['url'] ?? '',
                'inCharge' => $in_charge,
                'status' => $product['status'] ?? 'Pending',
                'isUrgent' => (bool)$product['isUrgent'] ?? false,
                'dateSubmitted' => $product['date_submitted'] ?? '',
                'comments' => $this->get_comments('activity_product', $product['id']),
                'lastUpdated' => $product['last_updated'] ?? '',
                'prod_type' => $product['prod_type'] ?? null,
                'activity' => [
                    'id' => (string)$product['activity_id'],
                    'code' => $product['code'],
                    'name' => $product['activity_name'],
                    'quarter' => $product['quarter'],
                    'year' => $product['year'],
                ]
            ];

            if ($product['type'] === 'folder') {
                $this->db->where('product_id', $product['id']);
                $this->db->where('is_active', 1);
                $files_data = $this->db->get('product_files')->result_array();
                $files = [];
                foreach ($files_data as $file) {
                    $files[] = [
                        'id' => (string)$file['id'],
                        'name' => $file['name'],
                        'type' => $file['type'],
                        'url' => $file['url'],
                        'date' => $file['date'],
                        'size' => $file['size']
                    ];
                }
                $product_data['files'] = $files;
            }

            $products_data[] = $product_data;
        }

        return $products_data;
    }
// private function get_sub_activity_products_($urgency=0)
// {
//     $this->db->select('p.id, p.sub_activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
//     $this->db->where('p.group', 'general');
//     $this->db->where('p.isUrgent', $urgency);
//     $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
//     $products = $this->db->get('sub_activity_products p')->result_array();

//     $products_data = [];
//     foreach ($products as $product) {
//         $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
//         $in_charge = [];
//         if (!empty($in_charge_ids)) {
//             $this->db->select('id, first_name, image as avatar');
//             $this->db->where_in('id', $in_charge_ids);
//             $users = $this->db->get('users')->result_array();
//             foreach ($users as $user) {
//                 $in_charge[] = [
//                     'id' => (string)$user['id'], // Convert to string to match your response
//                     'first_name' => $user['first_name'],
//                     'avatar' => $user['avatar'] ?? ''
//                 ];
//             }
//         }

//         $product_data = [
//             'id' => (string)$product['id'], // Convert to string to match your response
//             'name' => $product['name'],
//             'type' => $product['type'] ?? '',
//             'url' => $product['url'] ?? '',
//             'inCharge' => $in_charge,
//             'status' => $product['status'] ?? 'Pending',
//             'isUrgent' =>(bool)$product['isUrgent'] ?? false,
//             'dateSubmitted' => $product['date_submitted'] ?? '',
//             'lastUpdated' => $product['last_updated'] ?? '',
//             'prod_type' => $product['prod_type'] ?? null, // Add prod_type ID to the response
//             'comments'=>$this->get_comments('sub_activity_product', $product['id'])
//         ];

//         // If it's a folder product, include files
//         if ($product['type'] === 'folder') {
//             $this->db->where('product_id', $product['id']);
//             $this->db->where('is_active', 1); // Assuming soft delete with is_active
//             $files_data = $this->db->get('sub_activity_product_files')->result_array();
//             $files = [];
//             foreach ($files_data as $file) {
//                 $files[] = [
//                     'id' => (string)$file['id'], // Convert to string to match your response
//                     'name' => $file['name'],
//                     'type' => $file['type'],
//                     'url' => $file['url'],
//                     'date' => $file['date'],
//                     'size' => $file['size']
//                 ];
//             }
//             $product_data['files'] = $files;
//         }

//         $products_data[] = $product_data;
//     }

//     return $products_data;
// }

private function get_sub_activity_products_($urgency = 0) {
        $this->db->select('p.id, p.sub_activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
                           sa.code AS sub_activity_code, sa.name AS sub_activity_name, 
                           a.id AS activity_id, a.code AS activity_code, a.name AS activity_name, q.quarter, y.year');
        $this->db->from('sub_activity_products p');
        $this->db->join('sub_activities sa', 'p.sub_activity_id = sa.id', 'inner');
        $this->db->join('activities a', 'sa.parent_activity_id = a.id', 'inner');
        $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
         $this->db->join('years y', 'q.year_id = y.id', 'inner');
        $this->db->where('p.group', 'general');
        $this->db->where('p.isUrgent', $urgency);
        $this->db->where('p.type !=', 'folder');
        $this->db->where('p.is_active', 1);
        $this->db->where_in('p.status', ['Review', 'Submitted']);
        $this->db->where('sa.is_active', 1);
        $this->db->where('a.is_active', 1);
        $products = $this->db->get()->result_array();

        $products_data = [];
        foreach ($products as $product) {
            $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
            $in_charge = [];
            if (!empty($in_charge_ids)) {
                $this->db->select('id, first_name, image AS avatar');
                $this->db->where_in('id', $in_charge_ids);
                $users = $this->db->get('users')->result_array();
                foreach ($users as $user) {
                    $in_charge[] = [
                        'id' => (string)$user['id'],
                        'first_name' => $user['first_name'],
                        'avatar' => $user['avatar'] ?? ''
                    ];
                }
            }

            $product_data = [
                'id' => (string)$product['id'],
                'name' => $product['name'],
                'type' => $product['type'] ?? '',
                'url' => $product['url'] ?? '',
                'inCharge' => $in_charge,
                'status' => $product['status'] ?? 'Pending',
                'isUrgent' => (bool)$product['isUrgent'] ?? false,
                'dateSubmitted' => $product['date_submitted'] ?? '',
                'lastUpdated' => $product['last_updated'] ?? '',
                'prod_type' => $product['prod_type'] ?? null,
                'comments' => $this->get_comments('sub_activity_product', $product['id']),
                'sub_activity' => [
                    'id' => (string)$product['sub_activity_id'],
                    'code' => $product['sub_activity_code'],
                    'name' => $product['sub_activity_name']
                ],
                'activity' => [
                    'id' => (string)$product['activity_id'],
                    'code' => $product['activity_code'],
                    'name' => $product['activity_name'],
                    'quarter' => $product['quarter'],
                     'year' => $product['year']
                ]
            ];

            if ($product['type'] === 'folder') {
                $this->db->where('product_id', $product['id']);
                $this->db->where('is_active', 1);
                $files_data = $this->db->get('sub_activity_product_files')->result_array();
                $files = [];
                foreach ($files_data as $file) {
                    $files[] = [
                        'id' => (string)$file['id'],
                        'name' => $file['name'],
                        'type' => $file['type'],
                        'url' => $file['url'],
                        'date' => $file['date'],
                        'size' => $file['size']
                    ];
                }
                $product_data['files'] = $files;
            }

            $products_data[] = $product_data;
        }

        return $products_data;
    }


// attachments


 private function get_attachments_for_activity_($urgency = 0) {
        $this->db->select('a.id, a.activity_id, act.code AS activity_code, act.name AS activity_name, q.quarter, y.year');
        $this->db->from('attachments a');
        $this->db->join('activities act', 'a.activity_id = act.id', 'inner');
        $this->db->join('outcomes o', 'act.outcome_id = o.id', 'inner');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
        $this->db->join('years y', 'q.year_id = y.id', 'inner');
        $this->db->where('a.activity_id IS NOT NULL');
        $this->db->where('a.sub_activity_id IS NULL');
        $this->db->where('a.follow_up_activity_id IS NULL');
        $this->db->where('a.is_active', 1);
       
        $this->db->where('act.is_active', 1);
        $this->db->where('a.isUrgent', $urgency);
        $attachments = $this->db->get()->result_array();

        return array_map(function ($attachment) {
            $attachment_data = $this->get_attachment_data($attachment['id'], 'activity_attachment');
            if ($attachment_data) {
                $attachment_data['activity'] = [
                    'id' => (string)$attachment['activity_id'],
                    'code' => $attachment['activity_code'],
                    'name' => $attachment['activity_name'],
                    'quarter' => $attachment['quarter'],
                    'year' => $attachment['year']
                ];
            }
            return $attachment_data;
        }, $attachments);
    }
    
// private function get_attachments_for_sub_activity_($urgency=0)
// {
//     $this->db->where('sub_activity_id !=', null);
//     $this->db->where('activity_id', null);
//     $this->db->where('follow_up_activity_id', null);
//     $this->db->where('is_active', 1);
//     $this->db->where('isUrgent', $urgency);
//     $attachments = $this->db->get('attachments')->result_array();

//     return array_map(function ($attachment) {
//         return $this->get_attachment_data($attachment['id'],'sub_activity_attachment');
//     }, $attachments);
// }

private function get_attachments_for_sub_activity_($urgency = 0) {
        $this->db->select('a.id,a.sub_activity_id, sa.code AS sub_activity_code, sa.name AS sub_activity_name, 
                           a.activity_id, act.id AS activity_id, act.code AS activity_code, act.name AS activity_name, q.quarter, y.year');
        $this->db->from('attachments a');
        $this->db->join('sub_activities sa', 'a.sub_activity_id = sa.id', 'inner');
        $this->db->join('activities act', 'sa.parent_activity_id = act.id', 'inner');
        $this->db->join('outcomes o', 'act.outcome_id = o.id', 'inner');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
        $this->db->join('years y', 'q.year_id = y.id', 'inner');
        $this->db->where('a.sub_activity_id IS NOT NULL');
        $this->db->where('a.activity_id IS NULL');
        $this->db->where('a.follow_up_activity_id IS NULL');
        
        $this->db->where('a.is_active', 1);
        $this->db->where('sa.is_active', 1);
        $this->db->where('act.is_active', 1);
        $this->db->where('a.isUrgent', $urgency);
        $attachments = $this->db->get()->result_array();

        return array_map(function ($attachment) {
            $attachment_data = $this->get_attachment_data($attachment['id'], 'sub_activity_attachment');
            if ($attachment_data) {
                $attachment_data['sub_activity'] = [
                    'id' => (string)$attachment['sub_activity_id'],
                    'code' => $attachment['sub_activity_code'],
                    'name' => $attachment['sub_activity_name']
                ];
                $attachment_data['activity'] = [
                    'id' => (string)$attachment['activity_id'],
                    'code' => $attachment['activity_code'],
                    'name' => $attachment['activity_name'],
                    'quarter' => $attachment['quarter'],
                    'year' => $attachment['year']
                ];
            }
            return $attachment_data;
        }, $attachments);
    }

private function get_attachments_for_follow_up_activity_($urgency=0)
{
    $this->db->where('sub_activity_id', null);
    $this->db->where('activity_id', null);
    $this->db->where('follow_up_activity_id !=', null);
    $this->db->where('is_active', 1);
    $this->db->where('isUrgent', $urgency);
    $attachments = $this->db->get('attachments')->result_array();

    return array_map(function ($attachment) {
        return $this->get_attachment_data($attachment['id'],'followup_activity_attachment');
    }, $attachments);
}

private function get_activity_output_products($urgency=0)
{
    $this->db->select('p.id, p.activity_id, p.name, p.type, p.url, p.status, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
    $this->db->where('p.isUrgent', 1);
    $this->db->where('p.group', 'output');
    $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
    $products = $this->db->get('products p')->result_array();

    $output_products = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = [];
        if (!empty($in_charge_ids)) {
            $this->db->select('id, first_name, image as avatar');
            $this->db->where_in('id', $in_charge_ids);
            $users = $this->db->get('users')->result_array();
            foreach ($users as $user) {
                $in_charge[] = [
                    'id' => (string)$user['id'], // Convert to string to match your response
                    'first_name' => $user['first_name'],
                    'avatar' => $user['avatar'] ?? ''
                ];
            }
        }

        $product_data = [
            'id' => (string)$product['id'], // Convert to string to match your response
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null, // Add prod_type ID to the response
             'comments'=>$this->get_comments('activity_output_product', $product['id'])
        ];

        // If it's a folder product, include files
        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1); // Assuming soft delete with is_active
            $files_data = $this->db->get('product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'], // Convert to string to match your response
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $output_products[] = $product_data;
    }

    return $output_products;
}


//  public function get_all_products() {
//         // Fetch urgent and non-urgent products
//         $urgent_products = [
//             'main' => $this->get_activity_products(1),
//             'sub' => $this->get_sub_activity_products_(1),
//             'follow_up' => $this->get_follow_up_activity_products_(1)
//         ];

//         $not_urgent_products = [
//             'main' => $this->get_activity_products(0),
//             'sub' => $this->get_sub_activity_products_(0),
//             'follow_up' => $this->get_follow_up_activity_products_(0)
//         ];

//         // Fetch urgent and non-urgent attachments
//         $urgent_attachments = [
//             'main' => $this->get_attachments_for_activity_(1),
//             'sub' => $this->get_attachments_for_sub_activity_(1),
//             'follow_up' => $this->get_attachments_for_follow_up_activity_(1)
//         ];

//         $non_urgent_attachments = [
//             'main' => $this->get_attachments_for_activity_(0),
//             'sub' => $this->get_attachments_for_sub_activity_(0),
//             'follow_up' => $this->get_attachments_for_follow_up_activity_(0)
//         ];

//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode([
//                 'success' => true,
//                 'message' => 'PRODUCTS_FETCHED_SUCCESSFULLY',
//                 'data' => [
//                     'urgent_products' => $urgent_products,
//                     'not_urgent_products' => $not_urgent_products,
//                     'urgent_attachments' => $urgent_attachments,
//                     'non_urgent_attachments' => $non_urgent_attachments
//                 ]
//             ]));
//     }

//     private function get_activity_products($urgency = 0) {
//         $this->db->select('p.id, p.activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
//                           a.code, a.name AS activity_name, q.quarter');
//         $this->db->from('products p');
//         $this->db->join('activities a', 'p.activity_id = a.id', 'inner');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('p.group', 'general');
//         $this->db->where('p.isUrgent', $urgency);
//         $this->db->where('p.is_active', 1);
//         $this->db->where('a.is_active', 1);
//         $products = $this->db->get()->result_array();

//         return $this->format_product_data($products, 'activity_product');
//     }

//     private function get_sub_activity_products_($urgency = 0) {
//         $this->db->select('p.id, p.sub_activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
//                           a.code, a.name AS activity_name, q.quarter, sa.name AS sub_activity_name');
//         $this->db->from('sub_activity_products p');
//         $this->db->join('sub_activities sa', 'p.sub_activity_id = sa.id', 'inner');
//         $this->db->join('activities a', 'sa.parent_activity_id = a.id', 'inner');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('p.group', 'general');
//         $this->db->where('p.isUrgent', $urgency);
//         $this->db->where('p.is_active', 1);
//         $this->db->where('sa.is_active', 1);
//         $this->db->where('a.is_active', 1);
//         $products = $this->db->get()->result_array();

//         return $this->format_product_data($products, 'sub_activity_product', true);
//     }

//     private function get_follow_up_activity_products_($urgency = 0) {
//         $this->db->select('p.id, p.follow_up_activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
//                           a.code, a.name AS activity_name, q.quarter, fa.name AS follow_up_activity_name');
//         $this->db->from('follow_up_activity_products p');
//         $this->db->join('follow_up_activities fa', 'p.follow_up_activity_id = fa.id', 'inner');
//         $this->db->join('activities a', 'fa.parent_activity_id = a.id', 'inner');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('p.group', 'general');
//         $this->db->where('p.isUrgent', $urgency);
//         $this->db->where('p.is_active', 1);
//         $this->db->where('fa.is_active', 1);
//         $this->db->where('a.is_active', 1);
//         $products = $this->db->get()->result_array();

//         return $this->format_product_data($products, 'followup_activity_product', true, 'follow_up_activity');
//     }

//     private function format_product_data($products, $comment_type, $include_sub_data = false, $activity_type = 'activity') {
//         $products_data = [];
//         foreach ($products as $product) {
//             $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
//             $in_charge = [];
//             if (!empty($in_charge_ids)) {
//                 $this->db->select('id, first_name, image AS avatar');
//                 $this->db->where_in('id', $in_charge_ids);
//                 $users = $this->db->get('users')->result_array();
//                 foreach ($users as $user) {
//                     $in_charge[] = [
//                         'id' => (string)$user['id'],
//                         'first_name' => $user['first_name'],
//                         'avatar' => $user['avatar'] ?? ''
//                     ];
//                 }
//             }

//             $product_data = [
//                 'id' => (string)$product['id'],
//                 'name' => $product['name'],
//                 'type' => $product['type'] ?? '',
//                 'url' => $product['url'] ?? '',
//                 'inCharge' => $in_charge,
//                 'status' => $product['status'] ?? 'Pending',
//                 'isUrgent' => (bool)$product['isUrgent'],
//                 'dateSubmitted' => $product['date_submitted'] ?? '',
//                 'lastUpdated' => $product['last_updated'] ?? '',
//                 'prod_type' => $product['prod_type'] ?? null,
//                 'comments' => $this->get_comments($comment_type, $product['id']),
//                 'activity' => [
//                     'id' => (string)$product[$activity_type . '_id'],
//                     'code' => $product['code'],
//                     'name' => $product['activity_name'],
//                     'quarter' => $product['quarter']
//                 ]
//             ];

//             if ($include_sub_data) {
//                 $sub_key = $activity_type === 'sub_activity' ? 'sub_activity_name' : 'follow_up_activity_name';
//                 $product_data['sub_activity'] = [
//                     'id' => (string)$product[$activity_type . '_id'],
//                     'name' => $product[$sub_key]
//                 ];
//             }

//             if ($product['type'] === 'folder') {
//                 $table = $activity_type === 'activity' ? 'product_files' : ($activity_type === 'sub_activity' ? 'sub_activity_product_files' : 'follow_up_activity_product_files');
//                 $this->db->where('product_id', $product['id']);
//                 $this->db->where('is_active', 1);
//                 $files_data = $this->db->get($table)->result_array();
//                 $files = [];
//                 foreach ($files_data as $file) {
//                     $files[] = [
//                         'id' => (string)$file['id'],
//                         'name' => $file['name'],
//                         'type' => $file['type'],
//                         'url' => $file['url'],
//                         'date' => $file['date'],
//                         'size' => $file['size']
//                     ];
//                 }
//                 $product_data['files'] = $files;
//             }

//             $products_data[] = $product_data;
//         }
//         return $products_data;
//     }

//     private function get_attachments_for_activity_($urgency = 0) {
//         $this->db->select('a.id, a.activity_id, a.name, a.type, a.url, a.isUrgent, a.date_submitted, a.in_charge_ids, 
//                           act.code, act.name AS activity_name, q.quarter');
//         $this->db->from('attachments a');
//         $this->db->join('activities act', 'a.activity_id = act.id', 'inner');
//         $this->db->join('outcomes o', 'act.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('a.activity_id IS NOT NULL');
//         $this->db->where('a.sub_activity_id IS NULL');
//         $this->db->where('a.follow_up_activity_id IS NULL');
//         $this->db->where('a.is_active', 1);
//         $this->db->where('act.is_active', 1);
//         $this->db->where('a.isUrgent', $urgency);
//         $attachments = $this->db->get()->result_array();

//         return array_map(function ($attachment) {
//             return $this->get_attachment_data($attachment['id'], 'activity_attachment');
//         }, $attachments);
//     }

//     private function get_attachments_for_sub_activity_($urgency = 0) {
//         $this->db->select('a.id, a.sub_activity_id, a.name, a.type, a.url, a.isUrgent, a.date_submitted, a.in_charge_ids, 
//                           act.code, act.name AS activity_name, q.quarter, sa.name AS sub_activity_name');
//         $this->db->from('attachments a');
//         $this->db->join('sub_activities sa', 'a.sub_activity_id = sa.id', 'inner');
//         $this->db->join('activities act', 'sa.parent_activity_id = act.id', 'inner');
//         $this->db->join('outcomes o', 'act.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('a.sub_activity_id IS NOT NULL');
//         $this->db->where('a.activity_id IS NULL');
//         $this->db->where('a.follow_up_activity_id IS NULL');
//         $this->db->where('a.is_active', 1);
//         $this->db->where('sa.is_active', 1);
//         $this->db->where('act.is_active', 1);
//         $this->db->where('a.isUrgent', $urgency);
//         $attachments = $this->db->get()->result_array();

//         return array_map(function ($attachment) {
//             return $this->get_attachment_data($attachment['id'], 'sub_activity_attachment');
//         }, $attachments);
//     }

//     private function get_attachments_for_follow_up_activity_($urgency = 0) {
//         $this->db->select('a.id, a.follow_up_activity_id, a.name, a.type, a.url, a.isUrgent, a.date_submitted, a.in_charge_ids, 
//                           act.code, act.name AS activity_name, q.quarter, fa.name AS follow_up_activity_name');
//         $this->db->from('attachments a');
//         $this->db->join('follow_up_activities fa', 'a.follow_up_activity_id = fa.id', 'inner');
//         $this->db->join('activities act', 'fa.parent_activity_id = act.id', 'inner');
//         $this->db->join('outcomes o', 'act.outcome_id = o.id', 'inner');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
//         $this->db->where('a.follow_up_activity_id IS NOT NULL');
//         $this->db->where('a.activity_id IS NULL');
//         $this->db->where('a.sub_activity_id IS NULL');
//         $this->db->where('a.is_active', 1);
//         $this->db->where('fa.is_active', 1);
//         $this->db->where('act.is_active', 1);
//         $this->db->where('a.isUrgent', $urgency);
//         $attachments = $this->db->get()->result_array();

//         return array_map(function ($attachment) {
//             return $this->get_attachment_data($attachment['id'], 'followup_activity_attachment');
//         }, $attachments);
//     }




private function get_outputs_for_activity($activity_id)
{
    $this->db->select('id, title, status, planned, achieved, comments');
    $this->db->where('activity_id', $activity_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $outputs = $this->db->get('outputs')->result_array();

    $output_data = [
        'status' => 'Not Started', // Default or aggregate status
        'comments' => $this->get_comments('outputs',$activity_id),
        'planned' => 0,
        'achieved' => 0,
        'list' => []
    ];

    foreach ($outputs as $output) {
        $output_data['list'][] = [
            'id' => (string)$output['id'], // Convert to string to match your response
            'title' => $output['title'],
            'status' => $output['status'],
            'progress' => [
                'planned' => (int)$output['planned'],
                'achieved' => (int)$output['achieved']
            ]
        ];
    }

    // Aggregate status, planned, and achieved (you can refine this logic)
    if (!empty($outputs)) {
        $output_data['status'] = $this->aggregate_output_status($outputs);
        $output_data['planned'] = array_sum(array_column($outputs, 'planned'));
        $output_data['achieved'] = array_sum(array_column($outputs, 'achieved'));
        // $output_data['comments'] = array_unique(array_filter(array_column($outputs, 'comments')));
    }

    return $output_data;
}

// Helper function to aggregate output status
private function aggregate_output_status($outputs)
{
    $statuses = array_column($outputs, 'status');
    if (in_array('Finalised', $statuses)) return 'Finalised';
    if (in_array('In Progress', $statuses)) return 'In Progress';
    return 'Not Started';
}

public function delete_activity()
{
    // Validate user_id (assuming it's passed via GET or form for authentication)
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Get activity_id from input (required)
    $activity_id = $this->input->get('activity_id');
    if (empty($activity_id) || !is_numeric($activity_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_ACTIVITY_ID'
            )));
    }

    // Get delete_type from input (optional, defaults to soft delete)
    $delete_type = $this->input->get('delete_type') ?? 'soft';
    if (!in_array($delete_type, ['soft', 'hard'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_DELETE_TYPE'
            )));
    }

    // Check if activity exists and is active
    $this->db->where('id', $activity_id);
    if($delete_type === 'soft'){
      $this->db->where('is_active', 1); // Ensure the activity is active before deleting
    }else{
         $this->db->where('is_active', 0);
    }
    $activity = $this->db->get('activities')->row_array();

    if (empty($activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED'
            )));
    }

    // Start transaction for consistency
    $this->db->trans_start();

    if ($delete_type === 'soft') {
        // Perform soft delete: update is_active to 0 and set deleted_at
        $data = [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'), // Current timestamp
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s') // Current timestamp
        ];

        $this->db->where('id', $activity_id);
        $this->db->update('activities', $data);

        // Soft delete related records (e.g., products, activity_months) if needed
        $this->soft_delete_related_records($activity_id, $user_id);
    } else {
        // Perform hard delete: delete activity and related records
        $this->hard_delete_activity_and_related($activity_id);
    }

    // Complete transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500) // Internal Server Error
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'DELETE_FAILED'
            )));
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => ($delete_type === 'soft' ? 'ACTIVITY_SOFT_DELETED_SUCCESSFULLY' : 'ACTIVITY_HARD_DELETED_SUCCESSFULLY'),
            'data' => [
                'activity_id' => $activity_id,
                'delete_type' => $delete_type
            ]
        )));
}

// Helper function to soft delete related records
private function soft_delete_related_records($activity_id, $user_id)
{
    // Soft delete products
    $data = [
        'is_active' => 0,
        'deleted_at' => date('Y-m-d H:i:s'), // Current timestamp
        'updated_by' => $user_id,
        'updated_at' => date('Y-m-d H:i:s') // Current timestamp
    ];
    $this->db->where('activity_id', $activity_id);
    $this->db->update('products', $data);

    // Soft delete product_files (if any)
    $this->db->where('product_id IN (SELECT id FROM products WHERE activity_id = ' . $this->db->escape($activity_id) . ')');
    $this->db->update('product_files', $data);

    // Soft delete activity_months
    $this->db->where('activity_id', $activity_id);
    $this->db->update('activity_months', $data);
}

// Helper function to hard delete activity and related records
private function hard_delete_activity_and_related($activity_id)
{
    // Delete activity_months
    $this->db->where('activity_id', $activity_id);
    $this->db->delete('activity_months');

    // Get product IDs for this activity
    $this->db->select('id');
    $this->db->where('activity_id', $activity_id);
    $products = $this->db->get('products')->result_array();
    $product_ids = array_column($products, 'id');

    // Delete product_files (if any)
    if (!empty($product_ids)) {
        $this->db->where_in('product_id', $product_ids);
        $this->db->delete('product_files');
    }

    // Delete products
    $this->db->where('activity_id', $activity_id);
    $this->db->delete('products');

    // Delete the activity
    $this->db->where('id', $activity_id);
    $this->db->delete('activities');
}



public function get_activity($id)
{
    // Validate user_id
    $user_id = $this->input->get('user_id') ?? $this->session->userdata('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Get the activity by ID
    $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location, a.has_sub_activities, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
    $this->db->where('a.id', $id);
    $this->db->where('a.is_active', 1);
    $activity = $this->db->get('activities a')->row_array();

    if (empty($activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'ACTIVITY_NOT_FOUND']));
    }

    // Get outcomes for mapping
    $this->db->select('id, title');
    $outcomes = $this->db->get('outcomes')->result_array();
    $outcome_map = array_column($outcomes, 'title', 'id');

    // Get the current activity's quarter
    $this->db->select('q.quarter');
    $this->db->from('quarters q');
    $this->db->join('outcomes o', 'o.quarter_id = q.id');
    $this->db->where('o.id', $activity['outcome_id']);
    $current_quarter = $this->db->get()->row('quarter');

    // Define quarter order for comparison
    $quarter_order = ['Q1' => 1, 'Q2' => 2, 'Q3' => 3, 'Q4' => 4];
    $current_quarter_rank = $quarter_order[$current_quarter] ?? 0;

    // Fetch quarter data for all activities with the same code
    $this->db->select('a.id as activity_id, q.quarter');
    $this->db->from('activities a');
    $this->db->join('outcomes o', 'o.id = a.outcome_id');
    $this->db->join('quarters q', 'q.id = o.quarter_id');
    $this->db->where('a.code', $activity['code']);
    $this->db->where('a.is_active', 1);
    $quarter_activities = $this->db->get()->result_array();

    // Filter to only include quarters after the current one
    $quarter_data = array_filter($quarter_activities, function($item) use ($quarter_order, $current_quarter_rank) {
        $item_rank = $quarter_order[$item['quarter']] ?? 0;
        return $item_rank > $current_quarter_rank; // Only keep quarters after the current one
    });

    // Format the filtered quarter data
    $quarter_data = array_values(array_map(function($item) {
        return [
            'quarter' => $item['quarter'],
            'activity_id' => (string)$item['activity_id']
        ];
    }, $quarter_data));

    // Parse inCharges
    $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
    $inCharges_array = array_filter(array_map('intval', $inCharges_array));

    // Get inCharges details
    $inCharges_details = $this->get_in_charge_details($inCharges_array);
    $team_response = ['name' => 'Activity Team', 'members' => $inCharges_details];

    // Fetch sub-activities
    $sub_activities_data = [];
    if ($activity['has_sub_activities']) {
        $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, team_id, inCharges, comments_count');
        $this->db->where('parent_activity_id', $activity['id']);
        $this->db->where('is_active', 1);
        $sub_activities = $this->db->get('sub_activities')->result_array();

        foreach ($sub_activities as $sub_activity) {
            $sub_inCharges_array = json_decode($sub_activity['inCharges'], true) ?: [];
            $sub_inCharges_array = array_filter(array_map('intval', $sub_inCharges_array));
            $sub_inCharges_details = $this->get_in_charge_details($sub_inCharges_array);
            $sub_team_response = [
                'name' => $sub_activity['team_id'] ? $this->db->where('id', $sub_activity['team_id'])->get('teams')->row()->name ?? 'Sub-Activity Team' : 'Sub-Activity Team',
                'members' => $sub_inCharges_details
            ];

            // Fetch follow-up activities for this sub-activity
            $follow_up_activities_data = [];
            $this->db->select('id, parent_sub_activity_id, code, name, progress, status, created_at, location, due_date, team_id, inCharges, comments_count');
            $this->db->where('parent_sub_activity_id', $sub_activity['id']);
            $this->db->where('is_active', 1);
            $follow_up_activities = $this->db->get('sub_activity_follow_up_activities')->result_array();

            foreach ($follow_up_activities as $follow_up_activity) {
                $follow_up_inCharges_array = json_decode($follow_up_activity['inCharges'], true) ?: [];
                $follow_up_inCharges_array = array_filter(array_map('intval', $follow_up_inCharges_array));
                $follow_up_inCharges_details = $this->get_in_charge_details($follow_up_inCharges_array);
                $follow_up_team_response = [
                    'name' => $follow_up_activity['team_id'] ? $this->db->where('id', $follow_up_activity['team_id'])->get('teams')->row()->name ?? 'Follow-Up Activity Team' : 'Follow-Up Activity Team',
                    'members' => $follow_up_inCharges_details
                ];

                $follow_up_activity_data = [
                    'id' => (string)$follow_up_activity['id'],
                    'progress' => (string)$follow_up_activity['progress'],
                    'name' => $follow_up_activity['name'],
                    'code' => floatval($follow_up_activity['code']),
                    'due_date' => $follow_up_activity['due_date'],
                    'team' => $follow_up_team_response,
                    'status' => $follow_up_activity['status'],
                    'created_at' => $follow_up_activity['created_at'],
                    'location' => $follow_up_activity['location'],
                    'comments_count' => (string)$follow_up_activity['comments_count'],
                    'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []],
                    'comments' => $this->get_comments('sub_activity_followup_activity', $follow_up_activity['id']),
                    'products' => [],
                    'outputProducts' => [],
                    'attachments' => []
                ];
                $follow_up_activities_data[] = $follow_up_activity_data;
            }

            $sub_activity_data = [
                'id' => (string)$sub_activity['id'],
                'progress' => (string)$sub_activity['progress'],
                'name' => $sub_activity['name'],
                'code' => floatval($sub_activity['code']),
                'months' => $this->get_sub_activity_months($sub_activity['id']),
                'team' => $sub_team_response,
                'status' => $sub_activity['status'],
                'created_at' => $sub_activity['created_at'],
                'location' => $sub_activity['location'],
                'outputs' => $this->get_sub_activity_outputs($sub_activity['id']),
                'comments' => $this->get_comments('sub_activity', $sub_activity['id']),
                'comments_count' => (string)$sub_activity['comments_count'],
                'products' => $this->get_sub_activity_products($sub_activity['id']),
                'outputProducts' => [],
                'attachments' => $this->get_attachments_for_sub_activity($sub_activity['id']),
                'followUpActivities' => $follow_up_activities_data
            ];
            $sub_activities_data[] = $sub_activity_data;
        }
    }

    // Fetch follow-up activities directly tied to the main activity
    $follow_up_activities_data = [];
    if ($activity['has_follow_up_activities']) {
        $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, due_date, team_id, inCharges, comments_count');
        $this->db->where('parent_activity_id', $activity['id']);
        $this->db->where('is_active', 1);
        $follow_up_activities = $this->db->get('follow_up_activities')->result_array();

        foreach ($follow_up_activities as $follow_up_activity) {
            $follow_up_inCharges_array = json_decode($follow_up_activity['inCharges'], true) ?: [];
            $follow_up_inCharges_array = array_filter(array_map('intval', $follow_up_inCharges_array));
            $follow_up_inCharges_details = $this->get_in_charge_details($follow_up_inCharges_array);
            $follow_up_team_response = [
                'name' => $follow_up_activity['team_id'] ? $this->db->where('id', $follow_up_activity['team_id'])->get('teams')->row()->name ?? 'Follow-Up Activity Team' : 'Follow-Up Activity Team',
                'members' => $follow_up_inCharges_details
            ];

            $follow_up_activity_data = [
                'id' => (string)$follow_up_activity['id'],
                'progress' => (string)$follow_up_activity['progress'],
                'name' => $follow_up_activity['name'],
                'code' => floatval($follow_up_activity['code']),
                'months' => $this->get_follow_up_activity_months($follow_up_activity['id']),
                'due_date' => $follow_up_activity['due_date'],
                'team' => $follow_up_team_response,
                'status' => $follow_up_activity['status'],
                'created_at' => $follow_up_activity['created_at'],
                'location' => $follow_up_activity['location'],
                'comments_count' => (string)$follow_up_activity['comments_count'],
                'outputs' => $this->get_follow_up_activity_outputs($follow_up_activity['id']),
                'comments' => [],
                'products' => $this->get_follow_up_activity_products($follow_up_activity['id']),
                'outputProducts' => $this->get_follow_up_activity_output_products($follow_up_activity['id']),
                'attachments' => $this->get_attachments_for_follow_up_activity($follow_up_activity['id'])
            ];
            $follow_up_activities_data[] = $follow_up_activity_data;
        }
    }

    // Prepare activity data
    $activity_data = [
        'id' => $activity['id'],
        'progress' => $activity['progress'],
        'name' => $activity['name'],
        'code' => floatval($activity['code']),
        'months' => $this->get_activity_months($activity['id']),
        'team' => $team_response,
        'status' => $activity['status'],
        'outcome' => $outcome_map[$activity['outcome_id']] ?? 'Unknown Outcome',
        'created_at' => $activity['created_at'],
        'location' => $activity['location'],
        'followUpActivities' => $follow_up_activities_data,
        'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
        'hasSubActivities' => (bool)$activity['has_sub_activities'],
        'subActivities' => $sub_activities_data,
        'outputs' => $this->get_outputs_for_activity($activity['id']),
        'comments' => $this->get_comments('activity', $activity['id']),
        'comments_count' => $activity['comments_count'],
        'products' => $this->get_products_for_activity($activity['id']),
        'outputProducts' => $this->get_output_products_for_activity($activity['id']),
        'attachments' => $this->get_attachments_for_activity($activity['id']),
        'quarter_data' => $quarter_data // Only forward quarters
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode([
            'success' => true,
            'message' => 'ACTIVITY_RETRIEVED_SUCCESSFULLY',
            'data' => $activity_data
        ]));
}

private function get_sub_activities($activity_id) {
    $sub_activities_data = [];

    $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, team_id, inCharges, comments_count');
    $this->db->where('parent_activity_id', $activity_id);
    $this->db->where('is_active', 1);
    $sub_activities = $this->db->get('sub_activities')->result_array();

    foreach ($sub_activities as $sub_activity) {
        $sub_inCharges_array = json_decode($sub_activity['inCharges'], true) ?: [];
        $sub_inCharges_array = array_filter(array_map('intval', $sub_inCharges_array));
        $sub_inCharges_details = $this->get_in_charge_details($sub_inCharges_array);
        $sub_team_response = [
            'name' => $sub_activity['team_id'] ? $this->db->where('id', $sub_activity['team_id'])->get('teams')->row()->name ?? 'Sub-Activity Team' : 'Sub-Activity Team',
            'members' => $sub_inCharges_details
        ];

        // Fetch follow-up activities for this sub-activity
        $follow_up_activities_data = [];
        $this->db->select('id, parent_sub_activity_id, code, name, progress, status, created_at, location, due_date, team_id, inCharges, comments_count');
        $this->db->where('parent_sub_activity_id', $sub_activity['id']);
        $this->db->where('is_active', 1);
        $follow_up_activities = $this->db->get('sub_activity_follow_up_activities')->result_array();

        foreach ($follow_up_activities as $follow_up_activity) {
            $follow_up_inCharges_array = json_decode($follow_up_activity['inCharges'], true) ?: [];
            $follow_up_inCharges_array = array_filter(array_map('intval', $follow_up_inCharges_array));
            $follow_up_inCharges_details = $this->get_in_charge_details($follow_up_inCharges_array);
            $follow_up_team_response = [
                'name' => $follow_up_activity['team_id'] ? $this->db->where('id', $follow_up_activity['team_id'])->get('teams')->row()->name ?? 'Follow-Up Activity Team' : 'Follow-Up Activity Team',
                'members' => $follow_up_inCharges_details
            ];

            $follow_up_activity_data = [
                'id' => (string)$follow_up_activity['id'],
                'progress' => (string)$follow_up_activity['progress'],
                'name' => $follow_up_activity['name'],
                'code' => floatval($follow_up_activity['code']),
                'due_date' => $follow_up_activity['due_date'],
                'team' => $follow_up_team_response,
                'status' => $follow_up_activity['status'],
                'created_at' => $follow_up_activity['created_at'],
                'location' => $follow_up_activity['location'],
                'comments_count' => (string)$follow_up_activity['comments_count'],
                'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []],
                'comments' => $this->get_comments('sub_activity_followup_activity', $follow_up_activity['id']),
                'products' => [],
                'outputProducts' => [],
                'attachments' => []
            ];
            $follow_up_activities_data[] = $follow_up_activity_data;
        }

        $sub_activity_data = [
            'id' => (string)$sub_activity['id'],
            'progress' => (string)$sub_activity['progress'],
            'name' => $sub_activity['name'],
            'code' => floatval($sub_activity['code']),
            'months' => $this->get_sub_activity_months($sub_activity['id']),
            'team' => $sub_team_response,
            'status' => $sub_activity['status'],
            'created_at' => $sub_activity['created_at'],
            'location' => $sub_activity['location'],
            'outputs' => $this->get_sub_activity_outputs($sub_activity['id']),
            'comments' => $this->get_comments('sub_activity', $sub_activity['id']),
            'comments_count' => (string)$sub_activity['comments_count'],
            'products' => $this->get_sub_activity_products($sub_activity['id']),
            'outputProducts' => [],
            'attachments' => $this->get_attachments_for_sub_activity($sub_activity['id']),
            'followUpActivities' => $follow_up_activities_data
        ];
        $sub_activities_data[] = $sub_activity_data;
    }

    return $sub_activities_data;
}

private function get_attachments_for_activity($activity_id,$isActiveOnAnnual=0)
    {
        $this->db->where('activity_id', $activity_id)->where('is_active', 1);
        if($isActiveOnAnnual==1){
        $this->db->where('isActiveOnAnnual',$isActiveOnAnnual);
        }
        
        $attachments = $this->db->get('attachments')->result_array();
        return array_map(function ($attachment) {
            return $this->get_attachment_data($attachment['id']);
        }, $attachments);
    }

public function get_activity_testeed($id)
{
    // Validate user_id (assuming it's passed via form or session for authentication)
    $user_id = $this->input->get('user_id') ?? $this->session->userdata('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Get the activity by ID
    $this->db->select('a.id, a.outcome_id, a.code, a.name, a.progress, a.status, a.created_at, a.location, a.has_sub_activities, a.has_follow_up_activities, a.inCharges, a.comments_count, a.created_by, a.updated_by, a.updated_at, a.is_active, a.deleted_at');
    $this->db->where('a.id', $id);
    $this->db->where('a.is_active', 1); // Assuming soft delete with is_active
    $activity = $this->db->get('activities a')->row_array();

    if (empty($activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACTIVITY_NOT_FOUND'
            )));
    }

    // Get outcomes for mapping outcome titles
    $this->db->select('id, title');
    $outcomes = $this->db->get('outcomes')->result_array();
    $outcome_map = array_column($outcomes, 'title', 'id');

    // Parse inCharges from JSON
    $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
    $inCharges_array = array_filter(array_map('intval', $inCharges_array));

    // Get inCharges details for the response
    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1); // Ensure users are active
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'], // Convert to string to match your response
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }

    // Structure the response with "team" as {"name": "Activity Team", "members": []}
    $team_response = [
        'name' => 'Activity Team',
        'members' => $inCharges_details
    ];

    // Fetch sub-activities for this activity
    $sub_activities_data = [];
    if ($activity['has_sub_activities']) {
        $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, team_id, inCharges, comments_count');
        $this->db->where('parent_activity_id', $activity['id']);
        $this->db->where('is_active', 1);
        $sub_activities = $this->db->get('sub_activities')->result_array();

        foreach ($sub_activities as $sub_activity) {
            $sub_inCharges_array = json_decode($sub_activity['inCharges'], true) ?: [];
            $sub_inCharges_array = array_filter(array_map('intval', $sub_inCharges_array));

            $sub_inCharges_details = [];
            if (!empty($sub_inCharges_array)) {
                $this->db->select('id, first_name, image as avatar');
                $this->db->where_in('id', $sub_inCharges_array);
                $this->db->where('is_active', 1);
                $users = $this->db->get('users')->result_array();
                foreach ($users as $user) {
                    $sub_inCharges_details[] = [
                        'id' => (string)$user['id'],
                        'first_name' => $user['first_name'],
                        'avatar' => $user['avatar'] ?? ''
                    ];
                }
            }

            $sub_team_response = [
                'name' => 'Sub-Activity Team',
                'members' => $sub_inCharges_details
            ];

            $sub_activity_data = [
                'id' => (string)$sub_activity['id'],
                'progress' => (string)$sub_activity['progress'],
                'name' => $sub_activity['name'],
                'code' => floatval($sub_activity['code']),
                'months' => $this->get_sub_activity_months($sub_activity['id']),
                'team' => $sub_team_response,
                'status' => $sub_activity['status'],
                'created_at' => $sub_activity['created_at'],
                'location' => $sub_activity['location'],
                'outputs' => $this->get_sub_activity_outputs($sub_activity['id']),
                'comments' => [], // Placeholder
                'comments_count' => (string)$sub_activity['comments_count'],
                'products' => $this->get_sub_activity_products($sub_activity['id']),
                'outputProducts' => [], // Placeholder
                'attachments' => $this->get_attachments_for_sub_activity($sub_activity['id'])
            ];
            $sub_activities_data[] = $sub_activity_data;
        }
    }

    // Prepare activity data
    $activity_data = [
        'id' => $activity['id'],
        'progress' => $activity['progress'],
        'name' => $activity['name'],
        'code' => floatval($activity['code']), // Convert decimal to float
        'months' => $this->get_activity_months($activity['id']),
        'team' => $team_response,
        'status' => $activity['status'],
        'outcome' => $outcome_map[$activity['outcome_id']] ?? 'Unknown Outcome',
        'created_at' => $activity['created_at'],
        'location' => $activity['location'],
        'followUpActivities' => [], // Placeholder
        'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
        'hasSubActivities' => (bool)$activity['has_sub_activities'],
        'subActivities' => $sub_activities_data,
        'outputs' => $this->get_outputs_for_activity($activity['id']),
        'comments' => [], // Placeholder
        'comments_count' => $activity['comments_count'],
        'products' => $this->get_products_for_activity($activity['id']),
        'outputProducts' => $this->get_output_products_for_activity($activity['id']),
        'attachments' => $this->get_attachments_for_activity($activity['id'])
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'ACTIVITY_RETRIEVED_SUCCESSFULLY',
            'data' => $activity_data
        )));
}


private function get_sub_activity_outputs($sub_activity_id)
{
    $this->db->select('id, title, status, planned, achieved, comments');
    $this->db->where('sub_activity_id', $sub_activity_id);
    $this->db->where('is_active', 1); // Assuming soft delete with is_active
    $outputs = $this->db->get('sub_activity_outputs')->result_array();

    $output_data = [
        'status' => 'Not Started', // Default or aggregate status
        'comments' => [],
        'planned' => 0,
        'achieved' => 0,
        'list' => []
    ];

    foreach ($outputs as $output) {
        $output_data['list'][] = [
            'id' => (string)$output['id'], // Convert to string to match your response
            'title' => $output['title'],
            'status' => $output['status'],
            'progress' => [
                'planned' => (int)$output['planned'],
                'achieved' => (int)$output['achieved']
            ],
            'comments' => $output['comments'] ?? ''
        ];
    }

    // Aggregate status, planned, and achieved
    if (!empty($outputs)) {
        $output_data['status'] = $this->aggregate_output_status($outputs);
        $output_data['planned'] = array_sum(array_column($outputs, 'planned'));
        $output_data['achieved'] = array_sum(array_column($outputs, 'achieved'));
        $output_data['comments'] = array_unique(array_filter(array_column($outputs, 'comments')));
    }

    return $output_data;
}

private function get_sub_activity_months($sub_activity_id)
{
    $this->db->select('month');
    $this->db->where('sub_activity_id', $sub_activity_id);
    $months = $this->db->get('sub_activity_months')->result_array();

    $month_order = [
        'January' => 1, 'February' => 2, 'March' => 3, 'April' => 4,
        'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8,
        'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12
    ];

    $month_names = array_column($months, 'month');
    usort($month_names, function($a, $b) use ($month_order) {
        return $month_order[$a] - $month_order[$b];
    });

    return $month_names;
}

private function get_sub_activity_products($sub_activity_id, $isActiveOnAnnual=0)
{
    $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
    $this->db->where('p.group', 'general');
    $this->db->where('p.sub_activity_id', $sub_activity_id);
    $this->db->where('p.is_active', 1); // Assuming soft delete with is_active
    if($isActiveOnAnnual)
    $this->db->where('p.isActiveOnAnnual',$isActiveOnAnnual);
    $products = $this->db->get('sub_activity_products p')->result_array();

    $products_data = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = [];
        if (!empty($in_charge_ids)) {
            $this->db->select('id, first_name, image as avatar');
            $this->db->where_in('id', $in_charge_ids);
            $users = $this->db->get('users')->result_array();
            foreach ($users as $user) {
                $in_charge[] = [
                    'id' => (string)$user['id'], // Convert to string to match your response
                    'first_name' => $user['first_name'],
                    'avatar' => $user['avatar'] ?? ''
                ];
            }
        }

        $product_data = [
            'id' => (string)$product['id'], // Convert to string to match your response
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'isUrgent' =>(bool)$product['isUrgent'] ?? false,
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null, // Add prod_type ID to the response
            'comments'=>$this->get_comments('sub_activity_product', $product['id'])
        ];

        // If it's a folder product, include files
        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1); // Assuming soft delete with is_active
            $files_data = $this->db->get('sub_activity_product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'], // Convert to string to match your response
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $products_data[] = $product_data;
    }

    return $products_data;
}
// Helper method to fetch attachments for a sub-activity
private function get_attachments_for_sub_activity($sub_activity_id, $isActiveOnAnnual=0)
{
    $this->db->where('sub_activity_id', $sub_activity_id);
    $this->db->where('is_active', 1);
    if($isActiveOnAnnual)
    $this->db->where('isActiveOnAnnual',$isActiveOnAnnual);
    $attachments = $this->db->get('attachments')->result_array();

    return array_map(function ($attachment) {
        return $this->get_attachment_data($attachment['id'],'sub_activity_attachment');
    }, $attachments);
}
// Helper method to fetch attachments for a follow-up activity (directly tied to activity)
private function get_attachments_for_follow_up_activity($follow_up_activity_id)
{
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('is_active', 1);
    $attachments = $this->db->get('attachments')->result_array();

    return array_map(function ($attachment) {
        return $this->get_attachment_data($attachment['id'],'followup_activity_attachment');
    }, $attachments);
}

// Helper method to fetch attachments for a follow-up activity tied to a sub-activity
private function get_attachments_for_sub_activity_follow_up($follow_up_activity_id)
{
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('is_active', 1);
    $attachments = $this->db->get('attachments')->result_array();

    return array_map(function ($attachment) {
        return $this->get_attachment_data($attachment['id']);
    }, $attachments);
}

// Helper method to fetch attachment data (consistent with add_attachment)
private function get_attachment_data($attachment_id, $entity="activity")
{
    $this->db->where('a.id', $attachment_id);
    $this->db->where('a.is_active', 1);
    $attachment = $this->db->get('attachments a')->row_array();

    if (!$attachment) return null;
    
    $entity_type = 'attachment'; // Default
    if ($entity === 'sub_activity_attachment') {
        $entity_type = 'sub_activity_attachment';
    } elseif ($entity === 'followup_activity_attachment') {
        $entity_type = 'followup_activity_attachment';
    }

    $data = [
        'id' => (string)$attachment['id'],
        'type' => $attachment['type'],
         
        'title' => $attachment['title'],
        'date' => $attachment['date'],
        'isUrgent' => (bool)$attachment['isUrgent'],
        'comments'=>  $this->get_comments($entity_type, $attachment['id'])
    ];

    if ($attachment['type'] === 'folder') {
        $this->db->where('attachment_id', $attachment_id);
        $this->db->where('is_active', 1);
        $files = $this->db->get('attachment_files')->result_array();
        $data['files'] = array_map(function ($file) {
            return [
                'id' => (string)$file['id'],
                'name' => $file['name'],
                'type' => $file['type'],
                'url' => $file['url'],
                'date' => $file['date'],
                'size' => $file['size']
            ];
        }, $files);
        $data['url'] = null;
        $data['size'] = null;
    } else {
        $data['url'] = $attachment['url'];
        $data['size'] = $attachment['size'];
        $data['files'] = [];
    }

    $in_charge_ids = json_decode($attachment['in_charge_ids'], true) ?: [];
    $data['team'] = [
        'name' => 'Attachment Team',
        'members' => $this->get_in_charge_details($in_charge_ids)
    ];

    return $data;
}

//outputs

private function get_follow_up_activity_outputs($follow_up_activity_id)
{
    $this->db->select('id, title, status, planned, achieved, comments');
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('is_active', 1);
    $outputs = $this->db->get('follow_up_activity_outputs')->result_array();

    $output_data = [
        'status' => 'Not Started',
        'comments' => [],
        'planned' => 0,
        'achieved' => 0,
        'list' => []
    ];

    foreach ($outputs as $output) {
        $output_data['list'][] = [
            'id' => (string)$output['id'],
            'title' => $output['title'],
            'status' => $output['status'],
            'progress' => [
                'planned' => (int)$output['planned'],
                'achieved' => (int)$output['achieved']
            ],
            'comments' => $output['comments'] ?? ''
        ];
    }

    if (!empty($outputs)) {
        $output_data['status'] = $this->aggregate_output_status($outputs);
        $output_data['planned'] = array_sum(array_column($outputs, 'planned'));
        $output_data['achieved'] = array_sum(array_column($outputs, 'achieved'));
        $output_data['comments'] = array_unique(array_filter(array_column($outputs, 'comments')));
    }

    return $output_data;
}

private function get_follow_up_activity_products($follow_up_activity_id)
{
    $this->db->select('p.id, p.name, p.type, p.url, p.status, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
    $this->db->where('p.group', 'general');
    $this->db->where('p.follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('p.is_active', 1);
    $products = $this->db->get('follow_up_activity_products p')->result_array();

    $products_data = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = $this->get_in_charge_details($in_charge_ids);

        $product_data = [
            'id' => (string)$product['id'],
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null
        ];

        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1);
            $files_data = $this->db->get('follow_up_activity_product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'],
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $products_data[] = $product_data;
    }

    return $products_data;
}

private function get_follow_up_activity_output_products($follow_up_activity_id)
{
    $this->db->select('p.id, p.name, p.type, p.url, p.status, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, p.output_id');
    $this->db->where('p.group', 'output');
    $this->db->where('p.follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('p.is_active', 1);
    $products = $this->db->get('follow_up_activity_products p')->result_array();

    $products_data = [];
    foreach ($products as $product) {
        $in_charge_ids = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge = $this->get_in_charge_details($in_charge_ids);

        $product_data = [
            'id' => (string)$product['id'],
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inCharge' => $in_charge,
            'status' => $product['status'] ?? 'Pending',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null,
            'output_id' => (string)$product['output_id']
        ];

        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product['id']);
            $this->db->where('is_active', 1);
            $files_data = $this->db->get('follow_up_activity_product_files')->result_array();
            $files = [];
            foreach ($files_data as $file) {
                $files[] = [
                    'id' => (string)$file['id'],
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
            $product_data['files'] = $files;
        }

        $products_data[] = $product_data;
    }

    return $products_data;
}



private function get_in_charge_details($in_charge_ids)
{
    $details = [];
    if (!empty($in_charge_ids)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $in_charge_ids);
        $this->db->where('is_active', 1);
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $details[] = [
                'id' => (string)$user['id'],
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }
    return $details;
}
private function get_follow_up_activity_months($follow_up_activity_id)
{
    $this->db->select('month');
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $months = $this->db->get('follow_up_activity_months')->result_array();

    $month_order = [
        'January' => 1, 'February' => 2, 'March' => 3, 'April' => 4,
        'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8,
        'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12
    ];

    $month_names = array_column($months, 'month');
    usort($month_names, function($a, $b) use ($month_order) {
        return $month_order[$a] - $month_order[$b];
    });

    return $month_names;
}

// yearly activities:

public function add_year_activity()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $year_outcome_id = $json_data['year_outcome_id'];
    $code = $json_data['code'] ?? 0.0;
    $name = $json_data['name'];
    $status = $json_data['status'] ?? 'Not Started';
    $created_at = $json_data['created_at'] ?? date('Y-m-d H:i:s');
    $location = $json_data['location'];
    $has_sub_activities = $json_data['has_sub_activities'] ?? 0;
    $has_follow_up_activities = $json_data['has_follow_up_activities'] ?? 0;
    $inCharges = $json_data['inCharges'] ?? null; // List of user IDs (array or string)
    $user_id = $json_data['user_id'];
    $months = $json_data['months'] ?? []; // Array of month names

    // Validate required fields
    if (empty($user_id) || empty($year_outcome_id) || empty($name)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Validate year_outcome exists and is active
    $this->db->where('id', $year_outcome_id);
    $this->db->where('is_active', 1);
    $year_outcome = $this->db->get('year_outcomes')->row_array();
    if (empty($year_outcome)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR_OUTCOME']));
    }

    // Validate status
    if (!in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
    }

    // Validate code
    $code = floatval($code);

    // Validate progress (default to 0)
    $progress = 0;

    // Parse and validate inCharges
    $inCharges_array = [];
    if ($inCharges !== null) {
        $parsed_ids = json_decode($inCharges, true);
        if (is_array($parsed_ids)) {
            $inCharges_array = array_filter(array_map('intval', $parsed_ids));
        } else {
            $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
            $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
            $inCharges_array = array_map('intval', $inCharges_array);
        }

        if (!empty($inCharges_array)) {
            $this->db->where_in('id', $inCharges_array);
            $this->db->where('is_active', 1);
            $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
            if (!$users_exist) {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
            }
        }
    }

    // Validate months
    $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    if (!empty($months) && !is_array($months)) {
        $months = explode(',', $months);
    }
    $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
        return in_array($month, $valid_months);
    });

    // Validate created_at
    $created_at = date('Y-m-d H:i:s', strtotime($created_at)) ?: date('Y-m-d H:i:s');

    // Prepare data for insertion
    $data = [
        'year_outcome_id' => $year_outcome_id,
        'name' => $name,
        'code' => $code,
        'progress' => $progress,
        'status' => $status,
        'location' => $location,
        'has_sub_activities' => (int)$has_sub_activities,
        'has_follow_up_activities' => (int)$has_follow_up_activities,
        'inCharges' => !empty($inCharges_array) ? json_encode($inCharges_array) : json_encode([]),
        'created_by' => $user_id,
        'updated_by' => $user_id,
        'created_at' => $created_at,
        'is_active' => 1
    ];

    // Start transaction
    $this->db->trans_start();

    // Insert the year activity
    $insert = $this->db->insert('year_activities', $data);
    if (!$insert) {
        $this->db->trans_rollback();
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_CREATED - ' . $this->db->error()['message']]));
    }

    $year_activity_id = $this->db->insert_id();

    // Insert year activity months
    if (!empty($months)) {
        $month_data = array_map(function($month) use ($year_activity_id, $user_id) {
            return [
                'year_activity_id' => $year_activity_id,
                'month' => $month,
                'created_by' => $user_id,
                'updated_by' => $user_id
            ];
        }, $months);

        $this->db->insert_batch('year_activity_months', $month_data);
        if ($this->db->affected_rows() === FALSE) {
            $this->db->trans_rollback();
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_MONTHS_NOT_CREATED - ' . $this->db->error()['message']]));
        }
    }

    // New Feature: Add quarterly activities based on months
    if (!empty($months)) {
        // Map months to quarters
        $quarter_map = [
            'Q1' => ['January', 'February', 'March'],
            'Q2' => ['April', 'May', 'June'],
            'Q3' => ['July', 'August', 'September'],
            'Q4' => ['October', 'November', 'December']
        ];

        $affected_quarters = [];
        foreach ($months as $month) {
            foreach ($quarter_map as $quarter => $quarter_months) {
                if (in_array($month, $quarter_months)) {
                    $affected_quarters[$quarter] = true;
                }
            }
        }
        $affected_quarters = array_keys($affected_quarters);

        // Get the year_id from the year_outcome
        $year_id = $year_outcome['year_id'];

        // Get existing quarters for this year
        $this->db->where('year_id', $year_id);
        // $this->db->where('is_active', 1); // QUARTERS CAN EVEN BE OFFLINE
        $quarters = $this->db->get('quarters')->result_array();
        $quarter_map_by_name = array_column($quarters, 'id', 'quarter');

        foreach ($affected_quarters as $quarter) {
            if (!isset($quarter_map_by_name[$quarter])) {
                // Create the quarter if it doesn’t exist
                $quarter_data = [
                    'year_id' => $year_id,
                    'quarter' => $quarter,
                    'is_active' => 1,
                    'created_by' => $user_id,
                    'updated_by' => $user_id
                ];
                $this->db->insert('quarters', $quarter_data);
                $quarter_id = $this->db->insert_id();
            } else {
                $quarter_id = $quarter_map_by_name[$quarter];
            }

            // Check if an outcome exists for this quarter with the same title as year_outcome; if not, create one
            $this->db->where('quarter_id', $quarter_id);
            $this->db->where('title', $year_outcome['title']);
            $this->db->where('is_active', 1);
            $outcome = $this->db->get('outcomes')->row_array();

            if (empty($outcome)) {
                $outcome_data = [
                    'quarter_id' => $quarter_id,
                    'title' => $year_outcome['title'], // Use the year_outcome title
                    'progress' => '0',
                    'is_active' => 1
                    // 'created_by' => $user_id,
                    // 'updated_by' => $user_id
                ];
                $this->db->insert('outcomes', $outcome_data);
                $outcome_id = $this->db->insert_id();
            } else {
                $outcome_id = $outcome['id'];
            }

            // Check if an activity with the same code exists in this quarter
            $this->db->where('outcome_id', $outcome_id);
            $this->db->where('code', $code);
            $this->db->where('is_active', 1);
            $existing_activity = $this->db->get('activities')->row_array();

            if (empty($existing_activity)) {
                // Create a new quarterly activity
                $activity_data = [
                    'outcome_id' => $outcome_id,
                    'name' => $name,
                    'code' => $code,
                    'progress' => $progress,
                    'status' => $status,
                    'location' => $location,
                    'has_sub_activities' => (int)$has_sub_activities,
                    'has_follow_up_activities' => (int)$has_follow_up_activities,
                    'inCharges' => !empty($inCharges_array) ? json_encode($inCharges_array) : json_encode([]),
                    'created_by' => $user_id,
                    'updated_by' => $user_id,
                    'created_at' => $created_at,
                    'is_active' => 1
                ];
                $this->db->insert('activities', $activity_data);
                $quarter_activity_id = $this->db->insert_id();

                // Insert activity months (only those within this quarter)
                $quarter_months = array_intersect($months, $quarter_map[$quarter]);
                if (!empty($quarter_months)) {
                    $activity_month_data = array_map(function($month) use ($quarter_activity_id, $user_id) {
                        return [
                            'activity_id' => $quarter_activity_id,
                            'month' => $month,
                            'created_by' => $user_id,
                            'updated_by' => $user_id
                        ];
                    }, $quarter_months);
                    $this->db->insert_batch('activity_months', $activity_month_data);
                }
            }
        }
    }

    // Commit transaction
    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
    }

    // Prepare response
    $inCharges_details = $this->get_in_charge_details($inCharges_array);
    $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

    $response_data = [
        'id' => (string)$year_activity_id,
        'progress' => (string)$progress,
        'name' => $name,
        'code' => $code,
        'months' => $months,
        'team' => $team_response,
        'status' => $status,
        'year_outcome' => $year_outcome['title'],
        'created_at' => $created_at,
        'location' => $location,
        'followUpActivities' => [],
        'hasFollowUpActivities' => (bool)$has_follow_up_activities,
        'hasSubActivities' => (bool)$has_sub_activities,
        'subActivities' => [],
        'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []],
        'comments' => [],
        'comments_count' => '0',
        'products' => [],
        'outputProducts' => [],
        'attachments' => []
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201)
        ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_CREATED_SUCCESSFULLY', 'data' => $response_data]));
}

// with problematic year synchronization of quauters
// public function edit_year_activity($id)
// {
//     return;
//     // Get form data from JSON input
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $name = $json_data['name'] ?? null;
//     $code = $json_data['code'] ?? null;
//     $progress = $json_data['progress'] ?? null;
//     $status = $json_data['status'] ?? null;
//     $location = $json_data['location'] ?? null;
//     $has_sub_activities = $json_data['has_sub_activities'] ?? null;
//     $has_follow_up_activities = $json_data['has_follow_up_activities'] ?? null;
//     $inCharges = $json_data['inCharges'] ?? null;
//     $user_id = $json_data['user_id'];
//     $months = $json_data['months'] ?? [];

//     // Validate required fields
//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate user exists
//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     // Validate activity exists and is active
//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $year_activity = $this->db->get('year_activities')->row_array();
//     if (empty($year_activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED']));
//     }

//     // Validate status if provided
//     if ($status && !in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//     }

//     // Validate code and progress
//     $code = $code !== null ? floatval($code) : $year_activity['code'];
//     $progress = $progress !== null && is_numeric($progress) ? (int)$progress : $year_activity['progress'];

//     // Validate has_sub_activities and has_follow_up_activities
//     $has_sub_activities = $has_sub_activities !== null ? (int)$has_sub_activities : $year_activity['has_sub_activities'];
//     $has_follow_up_activities = $has_follow_up_activities !== null ? (int)$has_follow_up_activities : $year_activity['has_follow_up_activities'];
//     if ($has_sub_activities === 1) $has_follow_up_activities = 0;
//     elseif ($has_follow_up_activities === 1) $has_sub_activities = 0;

//     // Parse and validate inCharges
//     $inCharges_array = [];
//     if ($inCharges !== null) {
//         $parsed_ids = json_decode($inCharges, true);
//         if (is_array($parsed_ids)) {
//             $inCharges_array = array_filter(array_map('intval', $parsed_ids));
//         } else {
//             $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
//             $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
//             $inCharges_array = array_map('intval', $inCharges_array);
//         }

//         if (!empty($inCharges_array)) {
//             $this->db->where_in('id', $inCharges_array);
//             $this->db->where('is_active', 1);
//             $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
//             if (!$users_exist) {
//                 return $this->output
//                     ->set_content_type('application/json')
//                     ->set_status_header(400)
//                     ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
//             }
//         }
//     } else {
//         $inCharges_array = json_decode($year_activity['inCharges'], true) ?: [];
//     }

//     // Validate months
//     $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
//     if (!empty($months) && !is_array($months)) {
//         $months = explode(',', $months);
//     }
//     $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
//         return in_array($month, $valid_months);
//     });
//     if (empty($months)) {
//         $this->db->select('month');
//         $this->db->where('year_activity_id', $id);
//         $this->db->where('is_active', 1);
//         $existing_months = $this->db->get('year_activity_months')->result_array();
//         $months = array_column($existing_months, 'month');
//     }

//     // Prepare data for update
//     $data = [];
//     if ($name !== null) $data['name'] = $name;
//     if ($code !== $year_activity['code']) $data['code'] = $code;
//     if ($progress !== null) $data['progress'] = $progress;
//     if ($status !== null) $data['status'] = $status;
//     if ($location !== null) $data['location'] = $location;
//     if ($has_sub_activities !== null) $data['has_sub_activities'] = $has_sub_activities;
//     if ($has_follow_up_activities !== null) $data['has_follow_up_activities'] = $has_follow_up_activities;
//     if ($inCharges !== null) $data['inCharges'] = json_encode($inCharges_array);
//     $data['updated_by'] = $user_id;
//     $data['updated_at'] = date('Y-m-d H:i:s');

//     // Start transaction
//     $this->db->trans_start();

//     // Update the year activity
//     if (!empty($data)) {
//         $this->db->where('id', $id);
//         $update = $this->db->update('year_activities', $data);
//         if (!$update) {
//             $this->db->trans_rollback();
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']]));
//         }
//     }

//     // Handle year activity months
//     if (!empty($months)) {
//         // Get all existing months (active and inactive) for this year_activity_id
//         $this->db->select('month, is_active');
//         $this->db->where('year_activity_id', $id);
//         $existing_months = $this->db->get('year_activity_months')->result_array();
//         $existing_months_map = array_column($existing_months, 'is_active', 'month');

//         // Determine months to reactivate, insert, or deactivate
//         $new_months = []; // Truly new months that don’t exist yet
//         $months_to_reactivate = []; // Inactive months to reactivate
//         $existing_active_months = []; // Currently active months

//         foreach ($months as $month) {
//             if (!isset($existing_months_map[$month])) {
//                 $new_months[] = $month; // Month doesn’t exist, insert it
//             } elseif ($existing_months_map[$month] == 0) {
//                 $months_to_reactivate[] = $month; // Month exists but is inactive, reactivate it
//             } else {
//                 $existing_active_months[] = $month; // Month is already active
//             }
//         }

//         // Insert truly new months
//         if (!empty($new_months)) {
//             $month_data = array_map(function($month) use ($id, $user_id) {
//                 return [
//                     'year_activity_id' => $id,
//                     'month' => $month,
//                     'created_by' => $user_id,
//                     'updated_by' => $user_id,
//                     'is_active' => 1
//                 ];
//             }, $new_months);
//             $this->db->insert_batch('year_activity_months', $month_data);
//         }

//         // Reactivate inactive months
//         if (!empty($months_to_reactivate)) {
//             $this->db->where('year_activity_id', $id);
//             $this->db->where_in('month', $months_to_reactivate);
//             $this->db->update('year_activity_months', [
//                 'is_active' => 1,
//                 'deleted_at' => null,
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }

//         // Deactivate months that are no longer selected
//         $months_to_delete = array_diff(array_keys($existing_months_map), $months);
//         if (!empty($months_to_delete)) {
//             $this->db->where('year_activity_id', $id);
//             $this->db->where_in('month', $months_to_delete);
//             $this->db->update('year_activity_months', [
//                 'is_active' => 0,
//                 'deleted_at' => date('Y-m-d H:i:s'),
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }
//     }

//     // Sync quarterly activities
//     $this->db->where('id', $year_activity['year_outcome_id']);
//     $year_outcome = $this->db->get('year_outcomes')->row_array();
//     $year_id = $year_outcome['year_id'];

//     // Map months to quarters
//     $quarter_map = [
//         'Q1' => ['January', 'February', 'March'],
//         'Q2' => ['April', 'May', 'June'],
//         'Q3' => ['July', 'August', 'September'],
//         'Q4' => ['October', 'November', 'December']
//     ];

//     $affected_quarters = [];
//     foreach ($months as $month) {
//         foreach ($quarter_map as $quarter => $quarter_months) {
//             if (in_array($month, $quarter_months)) {
//                 $affected_quarters[$quarter] = true;
//             }
//         }
//     }
//     $affected_quarters = array_keys($affected_quarters);

//     // Get existing quarters for this year
//     $this->db->where('year_id', $year_id);
//     $this->db->where('is_active', 1);
//     $quarters = $this->db->get('quarters')->result_array();
//     $quarter_map_by_name = array_column($quarters, 'id', 'quarter');

//     // Fetch all existing quarterly activities tied to this year_activity's code
//     $this->db->select('a.*, o.quarter_id, q.quarter');
//     $this->db->from('activities a');
//     $this->db->join('outcomes o', 'o.id = a.outcome_id');
//     $this->db->join('quarters q', 'q.id = o.quarter_id');
//     $this->db->where('a.code', $year_activity['code']);
//     $this->db->where('q.year_id', $year_id);
//     $this->db->where('a.is_active', 1);
//     $existing_activities = $this->db->get()->result_array();
//     $existing_quarters = array_column($existing_activities, 'quarter');

//     // Update existing quarterly activities or create new ones
//     foreach ($affected_quarters as $quarter) {
//         if (!isset($quarter_map_by_name[$quarter])) {
//             $quarter_data = [
//                 'year_id' => $year_id,
//                 'quarter' => $quarter,
//                 'is_active' => 1,
//                 'created_by' => $user_id,
//                 'updated_by' => $user_id
//             ];
//             $this->db->insert('quarters', $quarter_data);
//             $quarter_id = $this->db->insert_id();
//         } else {
//             $quarter_id = $quarter_map_by_name[$quarter];
//         }

//         $this->db->where('quarter_id', $quarter_id);
//         $this->db->where('title', $year_outcome['title']);
//         $this->db->where('is_active', 1);
//         $outcome = $this->db->get('outcomes')->row_array();

//         if (empty($outcome)) {
//             $outcome_data = [
//                 'quarter_id' => $quarter_id,
//                 'title' => $year_outcome['title'],
//                 'progress' => '0',
//                 'is_active' => 1
//                 // 'created_by' => $user_id,
//                 // 'updated_by' => $user_id
//             ];
//             $this->db->insert('outcomes', $outcome_data);
//             $outcome_id = $this->db->insert_id();
//         } else {
//             $outcome_id = $outcome['id'];
//         }

//         $activity_exists = array_search($quarter, $existing_quarters) !== false;
//         if ($activity_exists) {
//             $activity = $existing_activities[array_search($quarter, $existing_quarters)];
//             $activity_data = [
//                 'name' => $data['name'] ?? $year_activity['name'],
//                 'code' => $data['code'] ?? $year_activity['code'],
//                 'status' => $data['status'] ?? $year_activity['status'],
//                 'location' => $data['location'] ?? $year_activity['location'],
//                 'has_sub_activities' => $data['has_sub_activities'] ?? $year_activity['has_sub_activities'],
//                 'has_follow_up_activities' => $data['has_follow_up_activities'] ?? $year_activity['has_follow_up_activities'],
//                 'inCharges' => $data['inCharges'] ?? $year_activity['inCharges'],
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ];
//             $this->db->where('id', $activity['id']);
//             $this->db->update('activities', $activity_data);

//             // Sync activity months
//             $this->db->where('activity_id', $activity['id']);
//             $this->db->where('is_active', 1);
//             $existing_activity_months = $this->db->get('activity_months')->result_array();
//             $existing_activity_months = array_column($existing_activity_months, 'month');

//             $quarter_months = array_intersect($months, $quarter_map[$quarter]);
//             $new_activity_months = array_diff($quarter_months, $existing_activity_months);
//             if (!empty($new_activity_months)) {
//                 $activity_month_data = array_map(function($month) use ($activity, $user_id) {
//                     return [
//                         'activity_id' => $activity['id'],
//                         'month' => $month,
//                         'created_by' => $user_id,
//                         'updated_by' => $user_id
//                     ];
//                 }, $new_activity_months);
//                 $this->db->insert_batch('activity_months', $activity_month_data);
//             }

//             $months_to_delete = array_diff($existing_activity_months, $quarter_months);
//             if (!empty($months_to_delete)) {
//                 $this->db->where('activity_id', $activity['id']);
//                 $this->db->where_in('month', $months_to_delete);
//                 $this->db->update('activity_months', ['is_active' => 0, 'deleted_at' => date('Y-m-d H:i:s'), 'updated_by' => $user_id]);
//             }
//         } else {
//             $activity_data = [
//                 'outcome_id' => $outcome_id,
//                 'name' => $data['name'] ?? $year_activity['name'],
//                 'code' => $data['code'] ?? $year_activity['code'],
//                 'progress' => $progress,
//                 'status' => $data['status'] ?? $year_activity['status'],
//                 'location' => $data['location'] ?? $year_activity['location'],
//                 'has_sub_activities' => $data['has_sub_activities'] ?? $year_activity['has_sub_activities'],
//                 'has_follow_up_activities' => $data['has_follow_up_activities'] ?? $year_activity['has_follow_up_activities'],
//                 'inCharges' => $data['inCharges'] ?? $year_activity['inCharges'],
//                 'created_by' => $user_id,
//                 'updated_by' => $user_id,
//                 'created_at' => $year_activity['created_at'],
//                 'is_active' => 1
//             ];
//             $this->db->insert('activities', $activity_data);
//             $quarter_activity_id = $this->db->insert_id();

//             $quarter_months = array_intersect($months, $quarter_map[$quarter]);
//             if (!empty($quarter_months)) {
//                 $activity_month_data = array_map(function($month) use ($quarter_activity_id, $user_id) {
//                     return [
//                         'activity_id' => $quarter_activity_id,
//                         'month' => $month,
//                         'created_by' => $user_id,
//                         'updated_by' => $user_id
//                     ];
//                 }, $quarter_months);
//                 $this->db->insert_batch('activity_months', $activity_month_data);
//             }
//         }
//     }

//     // Deactivate quarterly activities in quarters no longer affected
//     $quarters_to_remove = array_diff($existing_quarters, $affected_quarters);
//     if (!empty($quarters_to_remove)) {
//         $quarters_list = implode("','", array_map([$this->db, 'escape_str'], $quarters_to_remove));
//         $code = $this->db->escape_str($year_activity['code']);
//         $year_id = (int)$year_id;
//         $user_id = (int)$user_id;
//         $updated_at = $this->db->escape(date('Y-m-d H:i:s'));

//         $sql = "UPDATE `activities` `a`
//                 INNER JOIN `outcomes` `o` ON `o`.`id` = `a`.`outcome_id`
//                 INNER JOIN `quarters` `q` ON `q`.`id` = `o`.`quarter_id`
//                 SET `a`.`is_active` = 0, `a`.`updated_by` = $user_id, `a`.`updated_at` = $updated_at
//                 WHERE `q`.`quarter` IN ('$quarters_list')
//                 AND `a`.`code` = '$code'
//                 AND `q`.`year_id` = $year_id
//                 AND `a`.`is_active` = 1";
        
//         $this->db->query($sql);
//         log_message('debug', 'Deactivation Query: ' . $this->db->last_query());
//     }

//     // Commit transaction
//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//     }

//     // Fetch updated data
//     $this->db->where('id', $id);
//     $updated_activity = $this->db->get('year_activities')->row_array();
//     $this->db->where('id', $updated_activity['year_outcome_id']);
//     $year_outcome = $this->db->get('year_outcomes')->row_array();

//     $inCharges_details = $this->get_in_charge_details(json_decode($updated_activity['inCharges'], true) ?: []);
//     $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

//     $response_data = [
//         'id' => (string)$updated_activity['id'],
//         'progress' => (string)$updated_activity['progress'],
//         'name' => $updated_activity['name'],
//         'code' => floatval($updated_activity['code']),
//         'months' => $this->get_year_activity_months($id),
//         'team' => $team_response,
//         'status' => $updated_activity['status'],
//         'year_outcome' => $year_outcome['title'],
//         'created_at' => $updated_activity['created_at'],
//         'location' => $updated_activity['location'],
//         'followUpActivities' => [],
//         'hasFollowUpActivities' => (bool)$updated_activity['has_follow_up_activities'],
//         'hasSubActivities' => (bool)$updated_activity['has_sub_activities'],
//         'subActivities' => [],
//         'outputs' => $this->get_year_activity_outputs($id),
//         'comments' => [],
//         'comments_count' => (string)$updated_activity['comments_count'],
//         'products' => [],
//         'outputProducts' => [],
//         'attachments' => []
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_UPDATED_SUCCESSFULLY', 'data' => $response_data]));
// }

// without problematic year synchronization of quauters
// public function edit_year_activity($id)
// {
//     return;
//     // Get form data from JSON input
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $name = $json_data['name'] ?? null;
//     $code = $json_data['code'] ?? null;
//     $progress = $json_data['progress'] ?? null;
//     $status = $json_data['status'] ?? null;
//     $location = $json_data['location'] ?? null;
//     $has_sub_activities = $json_data['has_sub_activities'] ?? null;
//     $has_follow_up_activities = $json_data['has_follow_up_activities'] ?? null;
//     $inCharges = $json_data['inCharges'] ?? null;
//     $user_id = $json_data['user_id'];
//     $months = $json_data['months'] ?? [];

//     // Validate required fields
//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate user exists
//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     // Validate activity exists and is active
//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $year_activity = $this->db->get('year_activities')->row_array();
//     if (empty($year_activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED']));
//     }

//     // Validate status if provided
//     if ($status && !in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//     }

//     // Validate code and progress
//     $code = $code !== null ? floatval($code) : $year_activity['code'];
//     $progress = $progress !== null && is_numeric($progress) ? (int)$progress : $year_activity['progress'];

//     // Validate has_sub_activities and has_follow_up_activities
//     $has_sub_activities = $has_sub_activities !== null ? (int)$has_sub_activities : $year_activity['has_sub_activities'];
//     $has_follow_up_activities = $has_follow_up_activities !== null ? (int)$has_follow_up_activities : $year_activity['has_follow_up_activities'];
//     if ($has_sub_activities === 1) $has_follow_up_activities = 0;
//     elseif ($has_follow_up_activities === 1) $has_sub_activities = 0;

//     // Parse and validate inCharges
//     $inCharges_array = [];
//     if ($inCharges !== null) {
//         $parsed_ids = json_decode($inCharges, true);
//         if (is_array($parsed_ids)) {
//             $inCharges_array = array_filter(array_map('intval', $parsed_ids));
//         } else {
//             $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
//             $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
//             $inCharges_array = array_map('intval', $inCharges_array);
//         }

//         if (!empty($inCharges_array)) {
//             $this->db->where_in('id', $inCharges_array);
//             $this->db->where('is_active', 1);
//             $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
//             if (!$users_exist) {
//                 return $this->output
//                     ->set_content_type('application/json')
//                     ->set_status_header(400)
//                     ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
//             }
//         }
//     } else {
//         $inCharges_array = json_decode($year_activity['inCharges'], true) ?: [];
//     }

//     // Validate months
//     $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
//     if (!empty($months) && !is_array($months)) {
//         $months = explode(',', $months);
//     }
//     $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
//         return in_array($month, $valid_months);
//     });
//     if (empty($months)) {
//         $this->db->select('month');
//         $this->db->where('year_activity_id', $id);
//         $this->db->where('is_active', 1);
//         $existing_months = $this->db->get('year_activity_months')->result_array();
//         $months = array_column($existing_months, 'month');
//     }

//     // Prepare data for update
//     $data = [];
//     if ($name !== null) $data['name'] = $name;
//     if ($code !== $year_activity['code']) $data['code'] = $code;
//     if ($progress !== null) $data['progress'] = $progress;
//     if ($status !== null) $data['status'] = $status;
//     if ($location !== null) $data['location'] = $location;
//     if ($has_sub_activities !== null) $data['has_sub_activities'] = $has_sub_activities;
//     if ($has_follow_up_activities !== null) $data['has_follow_up_activities'] = $has_follow_up_activities;
//     if ($inCharges !== null) $data['inCharges'] = json_encode($inCharges_array);
//     $data['updated_by'] = $user_id;
//     $data['updated_at'] = date('Y-m-d H:i:s');
//     $isImplemented = $json_data['isImplemented'] ?? null;

//     // Start transaction
//     $this->db->trans_start();

//     // Update the year activity
//     if (!empty($data)) {
//         $this->db->where('id', $id);
//         $update = $this->db->update('year_activities', $data);
//         if (!$update) {
//             $this->db->trans_rollback();
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']]));
//         }
//     }

//     // Handle year activity months
//     if (!empty($months)) {
//         // Get all existing months (active and inactive) for this year_activity_id
//         $this->db->select('month, is_active');
//         $this->db->where('year_activity_id', $id);
//         $existing_months = $this->db->get('year_activity_months')->result_array();
//         $existing_months_map = array_column($existing_months, 'is_active', 'month');

//         // Determine months to reactivate, insert, or deactivate
//         $new_months = []; // Truly new months that don’t exist yet
//         $months_to_reactivate = []; // Inactive months to reactivate
//         $existing_active_months = []; // Currently active months

//         foreach ($months as $month) {
//             if (!isset($existing_months_map[$month])) {
//                 $new_months[] = $month; // Month doesn’t exist, insert it
//             } elseif ($existing_months_map[$month] == 0) {
//                 $months_to_reactivate[] = $month; // Month exists but is inactive, reactivate it
//             } else {
//                 $existing_active_months[] = $month; // Month is already active
//             }
//         }

//         // Insert truly new months
//         if (!empty($new_months)) {
//             $month_data = array_map(function($month) use ($id, $user_id) {
//                 return [
//                     'year_activity_id' => $id,
//                     'month' => $month,
//                     'created_by' => $user_id,
//                     'updated_by' => $user_id,
//                     'is_active' => 1
//                 ];
//             }, $new_months);
//             $this->db->insert_batch('year_activity_months', $month_data);
//         }

//         // Reactivate inactive months
//         if (!empty($months_to_reactivate)) {
//             $this->db->where('year_activity_id', $id);
//             $this->db->where_in('month', $months_to_reactivate);
//             $this->db->update('year_activity_months', [
//                 'is_active' => 1,
//                 'deleted_at' => null,
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }

//         // Deactivate months that are no longer selected
//         $months_to_delete = array_diff(array_keys($existing_months_map), $months);
//         if (!empty($months_to_delete)) {
//             $this->db->where('year_activity_id', $id);
//             $this->db->where_in('month', $months_to_delete);
//             $this->db->update('year_activity_months', [
//                 'is_active' => 0,
//                 'deleted_at' => date('Y-m-d H:i:s'),
//                 'updated_by' => $user_id,
//                 'updated_at' => date('Y-m-d H:i:s')
//             ]);
//         }
//     }

//     // Commit transaction
//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//     }

//     // Fetch updated data
//     $this->db->where('id', $id);
//     $updated_activity = $this->db->get('year_activities')->row_array();
//     $this->db->where('id', $updated_activity['year_outcome_id']);
//     $year_outcome = $this->db->get('year_outcomes')->row_array();

//     $inCharges_details = $this->get_in_charge_details(json_decode($updated_activity['inCharges'], true) ?: []);
//     $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

//     $response_data = [
//         'id' => (string)$updated_activity['id'],
//         'progress' => (string)$updated_activity['progress'],
//         'name' => $updated_activity['name'],
//         'code' => floatval($updated_activity['code']),
//         'months' => $this->get_year_activity_months($id),
//         'team' => $team_response,
//         'status' => $updated_activity['status'],
//         'year_outcome' => $year_outcome['title'],
//         'created_at' => $updated_activity['created_at'],
//         'location' => $updated_activity['location'],
//         'followUpActivities' => [],
//         'hasFollowUpActivities' => (bool)$updated_activity['has_follow_up_activities'],
//         'hasSubActivities' => (bool)$updated_activity['has_sub_activities'],
//         'subActivities' => [],
//         'outputs' => $this->get_year_activity_outputs($id),
//         'comments' => [],
//         'comments_count' => (string)$updated_activity['comments_count'],
//         'products' => [],
//         'outputProducts' => [],
//         'attachments' => []
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_UPDATED_SUCCESSFULLY', 'data' => $response_data]));
// }

public function edit_year_activity($id)
{
    // return;
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $name = $json_data['name'] ?? null;
    $code = $json_data['code'] ?? null;
    $progress = $json_data['progress'] ?? null;
    $status = $json_data['status'] ?? null;
    $location = $json_data['location'] ?? null;
    $has_sub_activities = $json_data['has_sub_activities'] ?? null;
    $has_follow_up_activities = $json_data['has_follow_up_activities'] ?? null;
    $inCharges = $json_data['inCharges'] ?? null;
    $user_id = $json_data['user_id'];
    $months = $json_data['months'] ?? [];
    $isImplemented = $json_data['isImplemented'] ?? null;

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Validate activity exists and is active
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $year_activity = $this->db->get('year_activities')->row_array();
    if (empty($year_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED']));
    }

    // Validate status if provided
    if ($status && !in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
    }

    // Validate code and progress
    $code = $code !== null ? floatval($code) : $year_activity['code'];
    $progress = $progress !== null && is_numeric($progress) ? (int)$progress : $year_activity['progress'];

    // Validate has_sub_activities and has_follow_up_activities
    $has_sub_activities = $has_sub_activities !== null ? (int)$has_sub_activities : $year_activity['has_sub_activities'];
    $has_follow_up_activities = $has_follow_up_activities !== null ? (int)$has_follow_up_activities : $year_activity['has_follow_up_activities'];
    if ($has_sub_activities === 1) $has_follow_up_activities = 0;
    elseif ($has_follow_up_activities === 1) $has_sub_activities = 0;

    // Parse and validate inCharges
    $inCharges_array = [];
    if ($inCharges !== null) {
        $parsed_ids = json_decode($inCharges, true);
        if (is_array($parsed_ids)) {
            $inCharges_array = array_filter(array_map('intval', $parsed_ids));
        } else {
            $ids = explode(',', str_replace(['[', ']', '"'], '', $inCharges));
            $inCharges_array = array_filter(array_map('trim', $ids), 'strlen');
            $inCharges_array = array_map('intval', $inCharges_array);
        }

        if (!empty($inCharges_array)) {
            $this->db->where_in('id', $inCharges_array);
            $this->db->where('is_active', 1);
            $users_exist = $this->db->get('users')->num_rows() === count($inCharges_array);
            if (!$users_exist) {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INCHARGE_IDS']));
            }
        }
    } else {
        $inCharges_array = json_decode($year_activity['inCharges'], true) ?: [];
    }

    // Validate months
    $valid_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    if (!empty($months) && !is_array($months)) {
        $months = explode(',', $months);
    }
    $months = array_filter(array_map('trim', (array)$months), function($month) use ($valid_months) {
        return in_array($month, $valid_months);
    });
    if (empty($months)) {
        $this->db->select('month');
        $this->db->where('year_activity_id', $id);
        $this->db->where('is_active', 1);
        $existing_months = $this->db->get('year_activity_months')->result_array();
        $months = array_column($existing_months, 'month');
    }

    // Prepare data for update
    $data = [];
    if ($name !== null) $data['name'] = $name;
    if ($code !== $year_activity['code']) $data['code'] = $code;
    if ($progress !== null) $data['progress'] = $progress;
    if ($status !== null) $data['status'] = $status;
    if ($location !== null) $data['location'] = $location;
    if ($has_sub_activities !== null) $data['has_sub_activities'] = $has_sub_activities;
    if ($has_follow_up_activities !== null) $data['has_follow_up_activities'] = $has_follow_up_activities;
    if ($inCharges !== null) $data['inCharges'] = json_encode($inCharges_array);
    $data['updated_by'] = $user_id;
    $data['updated_at'] = date('Y-m-d H:i:s');
    $data['isImplemented'] = $isImplemented;
    

    // Start transaction
    $this->db->trans_start();

    // Update the year activity
    if (!empty($data)) {
        $this->db->where('id', $id);
        $update = $this->db->update('year_activities', $data);
        if (!$update) {
            $this->db->trans_rollback();
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']]));
        }
    }

    // Handle year activity months
    if (!empty($months)) {
        // Get all existing months (active and inactive) for this year_activity_id
        $this->db->select('month, is_active');
        $this->db->where('year_activity_id', $id);
        $existing_months = $this->db->get('year_activity_months')->result_array();
        $existing_months_map = array_column($existing_months, 'is_active', 'month');

        // Determine months to reactivate, insert, or deactivate
        $new_months = []; // Truly new months that don’t exist yet
        $months_to_reactivate = []; // Inactive months to reactivate
        $existing_active_months = []; // Currently active months

        foreach ($months as $month) {
            if (!isset($existing_months_map[$month])) {
                $new_months[] = $month; // Month doesn’t exist, insert it
            } elseif ($existing_months_map[$month] == 0) {
                $months_to_reactivate[] = $month; // Month exists but is inactive, reactivate it
            } else {
                $existing_active_months[] = $month; // Month is already active
            }
        }

        // Insert truly new months
        if (!empty($new_months)) {
            $month_data = array_map(function($month) use ($id, $user_id) {
                return [
                    'year_activity_id' => $id,
                    'month' => $month,
                    'created_by' => $user_id,
                    'updated_by' => $user_id,
                    'is_active' => 1
                ];
            }, $new_months);
            $this->db->insert_batch('year_activity_months', $month_data);
        }

        // Reactivate inactive months
        if (!empty($months_to_reactivate)) {
            $this->db->where('year_activity_id', $id);
            $this->db->where_in('month', $months_to_reactivate);
            $this->db->update('year_activity_months', [
                'is_active' => 1,
                'deleted_at' => null,
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        // Deactivate months that are no longer selected
        $months_to_delete = array_diff(array_keys($existing_months_map), $months);
        if (!empty($months_to_delete)) {
            $this->db->where('year_activity_id', $id);
            $this->db->where_in('month', $months_to_delete);
            $this->db->update('year_activity_months', [
                'is_active' => 0,
                'deleted_at' => date('Y-m-d H:i:s'),
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }
    }

    // Commit transaction
    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
    }

    // Fetch updated data
    $this->db->where('id', $id);
    $updated_activity = $this->db->get('year_activities')->row_array();
    $this->db->where('id', $updated_activity['year_outcome_id']);
    $year_outcome = $this->db->get('year_outcomes')->row_array();

    $inCharges_details = $this->get_in_charge_details(json_decode($updated_activity['inCharges'], true) ?: []);
    $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

    $response_data = [
        'id' => (string)$updated_activity['id'],
        'progress' => (string)$updated_activity['progress'],
        'name' => $updated_activity['name'],
        'code' => floatval($updated_activity['code']),
        'months' => $this->get_year_activity_months($id),
        'team' => $team_response,
        'status' => $updated_activity['status'],
        'year_outcome' => $year_outcome['title'],
        'created_at' => $updated_activity['created_at'],
        'location' => $updated_activity['location'],
        'followUpActivities' => [],
        'hasFollowUpActivities' => (bool)$updated_activity['has_follow_up_activities'],
        'hasSubActivities' => (bool)$updated_activity['has_sub_activities'],
        'subActivities' => [],
        'outputs' => $this->get_year_activity_outputs($id),
        'comments' => [],
        'comments_count' => (string)$updated_activity['comments_count'],
        'products' => [],
        'outputProducts' => [],
        'attachments' => []
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_UPDATED_SUCCESSFULLY', 'data' => $response_data]));
}

public function get_all_year_activities()
{
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $country_code = $this->input->get('country');
    $programme_code = $this->input->get('programme');
    $year = $this->input->get('year');

    if (empty($country_code) || empty($programme_code) || empty($year) || !is_numeric($year) || strlen($year) !== 4) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate country, programme, and year
    $this->db->where('code', $country_code);
    $this->db->where('is_active', 1);
    $country = $this->db->get('countries')->row_array();
    if (empty($country)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'COUNTRY_NOT_FOUND']));
    }

    $this->db->where('country_id', $country['id']);
    $this->db->where('code', $programme_code);
    $this->db->where('is_active', 1);
    $programme = $this->db->get('programmes')->row_array();
    if (empty($programme)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'PROGRAMME_NOT_FOUND']));
    }

    $this->db->where('programme_id', $programme['id']);
    $this->db->where('year', $year);
    $this->db->where('is_active', 1);
    $year_record = $this->db->get('years')->row_array();
    if (empty($year_record)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'YEAR_NOT_FOUND']));
    }

    // Get year outcomes
    $this->db->select('id, title');
    $this->db->where('year_id', $year_record['id']);
    $this->db->where('is_active', 1);
    $year_outcomes = $this->db->get('year_outcomes')->result_array();

    $response_data = [
        'country' => $country_code,
        'programme' => $programme_code,
        'year' => $year,
        'outcomes' => []
    ];

    foreach ($year_outcomes as $outcome) {
        $this->db->where('year_outcome_id', $outcome['id']);
        $this->db->where('is_active', 1);
        $activities = $this->db->get('year_activities')->result_array();

        $outcome_data = [
            'id' => (string)$outcome['id'],
            'title' => $outcome['title'],
            'activities' => []
        ];

        foreach ($activities as $activity) {
            $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
            $inCharges_details = $this->get_in_charge_details($inCharges_array);
            $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

            // Fetch quarterly activities with the same code, linked to the same year via outcomes and quarters
            $this->db->select('activities.id, quarters.quarter');
            $this->db->from('activities');
            $this->db->join('outcomes', 'outcomes.id = activities.outcome_id');
            $this->db->join('quarters', 'quarters.id = outcomes.quarter_id');
            $this->db->where('activities.code', $activity['code']);
            $this->db->where('activities.is_active', 1);
            $this->db->where('quarters.year_id', $year_record['id']); // Match the year
            $quarterly_activities = $this->db->get()->result_array();

            $quarter_data = [];
            foreach ($quarterly_activities as $qa) {
                $quarter_data[] = [
                    'quarter' => $qa['quarter'], // e.g., 'Q1', 'Q2'
                    'activity_id' => (string)$qa['id']
                ];
            }

            $activity_data = [
                'id' => (string)$activity['id'],
                'progress' => (string)$activity['progress'],
                'name' => $activity['name'],
                'code' => floatval($activity['code']),
                'months' => $this->get_year_activity_months($activity['id']),
                'team' => $team_response,
                'status' => $activity['status'],
                'year_outcome' => $outcome['title'],
                'created_at' => $activity['created_at'],
                'location' => $activity['location'],
                'followUpActivities' => [], // Placeholder
                'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
                'hasSubActivities' => (bool)$activity['has_sub_activities'],
                'isImplemented' =>(bool)$activity['isImplemented'],
                'subActivities' => [], // Placeholder
                'outputs' => $this->get_year_activity_outputs($activity['id']),
                'quarter_data' => $quarter_data, // Quarterly activities linked by code and year
                'comments' =>$this->get_comments('activity', $activity['id'],'yearly'),
                'comments_count' => (string)$activity['comments_count'],
                'products' => [], // Placeholder
                'outputProducts' => [], // Placeholder
                'attachments' => [] // Placeholder
            ];
            $outcome_data['activities'][] = $activity_data;
        }

        $response_data['outcomes'][] = $outcome_data;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITIES_RETRIEVED_SUCCESSFULLY', 'data' => $response_data]));
}

// public function get_year_activity($id)
// {
//     $user_id = $this->input->get('user_id') ?? $this->session->userdata('user_id');
//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $activity = $this->db->get('year_activities')->row_array();
//     if (empty($activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND']));
//     }

//     $this->db->select('id, title');
//     $year_outcomes = $this->db->get('year_outcomes')->result_array();
//     $outcome_map = array_column($year_outcomes, 'title', 'id');

//     $inCharges_array = json_decode($activity['inCharges'], true) ?: [];
//     $inCharges_details = $this->get_in_charge_details($inCharges_array);
//     $team_response = ['name' => 'Year Activity Team', 'members' => $inCharges_details];

//     $activity_data = [
//         'id' => (string)$activity['id'],
//         'progress' => (string)$activity['progress'],
//         'name' => $activity['name'],
//         'code' => floatval($activity['code']),
//         'months' => $this->get_year_activity_months($activity['id']),
//         'team' => $team_response,
//         'status' => $activity['status'],
//         'year_outcome' => $outcome_map[$activity['year_outcome_id']] ?? 'Unknown Outcome',
//         'created_at' => $activity['created_at'],
//         'location' => $activity['location'],
//         'followUpActivities' => [], // Placeholder
//         'hasFollowUpActivities' => (bool)$activity['has_follow_up_activities'],
//         'hasSubActivities' => (bool)$activity['has_sub_activities'],
//         'subActivities' => [], // Placeholder
//         'outputs' => $this->get_year_activity_outputs($activity['id']),
//         'comments' => [], // Placeholder
//         'comments_count' => (string)$activity['comments_count'],
//         'products' => [], // Placeholder
//         'outputProducts' => [], // Placeholder
//         'attachments' => [] // Placeholder
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_RETRIEVED_SUCCESSFULLY', 'data' => $activity_data]));
// }

// public function get_year_activity($id)
// {
//     $user_id = $this->input->get('user_id'); // Assuming user_id is passed for validation or permissions

//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     // Validate user exists
//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     // Fetch the year_activity
//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $year_activity = $this->db->get('year_activities')->row_array();

//     if (empty($year_activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_DELETED']));
//     }

//     // Fetch year_outcome and year_id
//     $year_outcome_id = $year_activity['year_outcome_id'];
//     $this->db->where('id', $year_outcome_id);
//     $year_outcome = $this->db->get('year_outcomes')->row_array();
//     $year_id = $year_outcome['year_id'] ?? null;

//     if (empty($year_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR_OUTCOME']));
//     }

//     // Fetch quarters for the year
//     $this->db->where('year_id', $year_id);
//     $this->db->where('is_active', 1);
//     $quarters = $this->db->get('quarters')->result_array();

//     // Initialize aggregated arrays
//     $all_sub_activities = [];
//     $all_products = [];
//     $all_output_products = [];
//     $all_attachments = [];

//     // Loop through each quarter
//     foreach ($quarters as $quarter) {
//         $quarter_id = $quarter['id'];
//         $quarter_name = $quarter['quarter'];

//         // Fetch outcomes for the quarter
//         $this->db->where('quarter_id', $quarter_id);
//         $this->db->where('is_active', 1);
//         $outcomes = $this->db->get('outcomes')->result_array();

//         foreach ($outcomes as $outcome) {
//             $outcome_id = $outcome['id'];

//             // Fetch activities with matching code
//             $this->db->where('outcome_id', $outcome_id);
//             $this->db->where('code', $year_activity['code']);
//             $this->db->where('is_active', 1);
//             $activities = $this->db->get('activities')->result_array();

//             foreach ($activities as $activity) {
//                 $activity_id = $activity['id'];

//                 // Fetch and augment sub_activities
//                 $sub_activities = $this->get_sub_activities_for_activity($activity_id); // Assuming this helper exists, similar to get_products_for_activity
//                 foreach ($sub_activities as &$sub_activity) {
//                     $sub_activity['quarter'] = $quarter_name;
//                 }
//                 $all_sub_activities = array_merge($all_sub_activities, $sub_activities);

//                 // Fetch and augment products
//                 $products = $this->get_products_for_activity($activity_id);
//                 foreach ($products as &$product) {
//                     $product['quarter'] = $quarter_name;
//                 }
//                 $all_products = array_merge($all_products, $products);

//                 // Fetch and augment outputProducts
//                 $output_products = $this->get_output_products_for_activity($activity_id);
//                 foreach ($output_products as &$output_product) {
//                     $output_product['quarter'] = $quarter_name;
//                 }
//                 $all_output_products = array_merge($all_output_products, $output_products);

//                 // Fetch and augment attachments
//                 $attachments = $this->get_attachments_for_activity($activity_id); // Assuming this helper exists
//                 foreach ($attachments as &$attachment) {
//                     $attachment['quarter'] = $quarter_name;
//                 }
//                 $all_attachments = array_merge($all_attachments, $attachments);
//             }
//         }
//     }

//     // Fetch other details similar to edit_activity or get_activity
//     $this->db->select('yo.title as outcome_title');
//     $this->db->from('year_outcomes yo');
//     $this->db->where('yo.id', $year_activity['year_outcome_id']);
//     $outcome = $this->db->get()->row_array();

//     // Fetch months for the year_activity (assuming year_activity_months table)
//     $this->db->select('month');
//     $this->db->where('year_activity_id', $id);
//     $this->db->where('is_active', 1);
//     $months_result = $this->db->get('year_activity_months')->result_array();
//     $months = array_column($months_result, 'month');

//     // Fetch team details
//     $inCharges_array = json_decode($year_activity['inCharges'] ?? '[]', true);
//     $inCharges_details = [];
//     if (!empty($inCharges_array)) {
//         $this->db->select('id, first_name, image as avatar');
//         $this->db->where_in('id', $inCharges_array);
//         $this->db->where('is_active', 1);
//         $users = $this->db->get('users')->result_array();
//         foreach ($users as $user) {
//             $inCharges_details[] = [
//                 'id' => (string)$user['id'],
//                 'first_name' => $user['first_name'],
//                 'avatar' => $user['avatar'] ?? ''
//             ];
//         }
//     }
//     $team_response = [
//         'name' => 'Year Activity Team',
//         'members' => $inCharges_details
//     ];

//     // Prepare response data
//     $response_data = [
//         'id' => (string)$year_activity['id'],
//         'progress' => (string)$year_activity['progress'],
//         'name' => $year_activity['name'],
//         'code' => floatval($year_activity['code']),
//         'months' => $months,
//         'team' => $team_response,
//         'status' => $year_activity['status'],
//         'outcome' => $outcome['outcome_title'] ?? '',
//         'created_at' => $year_activity['created_at'],
//         'location' => $year_activity['location'],
//         'followUpActivities' => [], // Assuming not consolidated for now
//         'hasFollowUpActivities' => (bool)$year_activity['has_follow_up_activities'],
//         'hasSubActivities' => !empty($all_sub_activities),
//         'subActivities' => $all_sub_activities,
//         'outputs' => $this->get_outputs_for_year_activity($id), // Assuming a helper for year-specific outputs if needed
//         'comments' => $this->get_comments('year_activity', $id),
//         'comments_count' => (string)$year_activity['comments_count'],
//         'products' => $all_products,
//         'outputProducts' => $all_output_products,
//         'attachments' => $all_attachments
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_FETCHED_SUCCESSFULLY', 'data' => $response_data]));
// }

// public function get_year_activity($id)
// {
//     $user_id = $this->input->get('user_id');

//     if (empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     $this->db->where('id', $user_id);
//     $user_exists = $this->db->get('users')->num_rows() > 0;
//     if (!$user_exists) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }

//     $this->db->where('id', $id);
//     $this->db->where('is_active', 1);
//     $year_activity = $this->db->get('year_activities')->row_array();

//     if (empty($year_activity)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_DELETED']));
//     }

//     $year_outcome_id = $year_activity['year_outcome_id'];
//     $this->db->where('id', $year_outcome_id);
//     $year_outcome = $this->db->get('year_outcomes')->row_array();
//     $year_id = $year_outcome['year_id'] ?? null;

//     if (empty($year_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR_OUTCOME']));
//     }

//     $this->db->where('year_id', $year_id);
//     $this->db->where('is_active', 1);
//     $quarters = $this->db->get('quarters')->result_array();

//     $all_sub_activities = [];
//     $all_products = [];
//     $all_output_products = [];
//     $all_attachments = [];
//     $all_outputs_list = [];

//     foreach ($quarters as $quarter) {
//         $quarter_id = $quarter['id'];
//         $quarter_name = $quarter['quarter'];

//         $this->db->where('quarter_id', $quarter_id);
//         $this->db->where('is_active', 1);
//         $outcomes = $this->db->get('outcomes')->result_array();

//         foreach ($outcomes as $outcome) {
//             $outcome_id = $outcome['id'];

//             $this->db->where('outcome_id', $outcome_id);
//             $this->db->where('code', $year_activity['code']);
//             $this->db->where('is_active', 1);
//             $activities = $this->db->get('activities')->result_array();

//             foreach ($activities as $activity) {
//                 $activity_id = $activity['id'];

//                 // Fetch sub_activities
//                 $this->db->where('parent_activity_id', $activity_id);
//                 $this->db->where('is_active', 1);
//                 $subs = $this->db->get('sub_activities')->result_array();

//                 foreach ($subs as $sub) {
//                     $inCharges_array = json_decode($sub['inCharges'] ?? '[]', true);
//                     $members = [];
//                     if (!empty($inCharges_array)) {
//                         $this->db->select('id, first_name, image as avatar');
//                         $this->db->where_in('id', $inCharges_array);
//                         $this->db->where('is_active', 1);
//                         $users = $this->db->get('users')->result_array();
//                         foreach ($users as $user) {
//                             $members[] = [
//                                 'id' => (string)$user['id'],
//                                 'first_name' => $user['first_name'],
//                                 'avatar' => $user['avatar'] ?? ''
//                             ];
//                         }
//                     }
//                     $sub_data = [
//                         'id' => (string)$sub['id'],
//                         'code' => floatval($sub['code']),
//                         'name' => $sub['name'],
//                         'progress' => (string)$sub['progress'],
//                         'status' => $sub['status'],
//                         'created_at' => $sub['created_at'],
//                         'location' => $sub['location'],
//                         // 'has_follow_up_activities' => (bool)$sub['has_follow_up_activities'],
//                         'products' => $this->get_sub_activity_products($sub['id']),
                
//                         'attachments' => $this->get_attachments_for_sub_activity($sub['id']),
//                         'team' => ['name' => 'Sub Activity Team', 'members' => $members],
//                         'comments_count' => (string)$sub['comments_count'],
//                         'quarter' => $quarter_name
//                     ];
//                     $all_sub_activities[] = $sub_data;

//                     // Fetch sub_activity_products (general)
//                     $this->db->select('sp.id, sp.name, sp.type, sp.url, sp.status, sp.isUrgent, sp.isRequiredToProceed, sp.date_submitted, sp.last_updated, sp.in_charge_ids, sp.prod_type');
//                     $this->db->from('sub_activity_products sp');
//                     $this->db->where('sp.sub_activity_id', $sub['id']);
//                     $this->db->where('sp.group', 'general');
//                     $this->db->where('sp.is_active', 1);
//                     $sub_products = $this->db->get()->result_array();
//                     foreach ($sub_products as $product) {
//                         $prod_data = [
//                             'id' => (string)$product['id'],
//                             'name' => $product['name'],
//                             'type' => $product['type'] ?? '',
//                             'url' => $product['url'] ?? '',
//                             'inChargeIds' => json_decode($product['in_charge_ids'], true) ?: [],
//                             'status' => $product['status'] ?? 'Pending',
//                             'isUrgent' => (bool)$product['isUrgent'] ?? false,
//                             'isRequiredToProceed' => (bool)$product['isRequiredToProceed'] ?? false,
//                             'dateSubmitted' => $product['date_submitted'] ?? '',
//                             'comments' => $this->get_comments('sub_activity_product', $product['id']),
//                             'lastUpdated' => $product['last_updated'] ?? '',
//                             'prod_type' => $product['prod_type'] ?? null,
//                             'quarter' => $quarter_name
//                         ];
//                         $all_products[] = $prod_data;
//                     }

//                     // Fetch sub_activity_products (output)
//                     $this->db->select('sp.id, sp.name, sp.type, sp.url, sp.status, sp.isUrgent, sp.isRequiredToProceed, sp.date_submitted, sp.last_updated, sp.in_charge_ids, sp.prod_type');
//                     $this->db->from('sub_activity_products sp');
//                     $this->db->where('sp.sub_activity_id', $sub['id']);
//                     $this->db->where('sp.group', 'output');
//                     $this->db->where('sp.is_active', 1);
//                     $sub_output_products = $this->db->get()->result_array();
//                     foreach ($sub_output_products as $product) {
//                         $prod_data = [
//                             'id' => (string)$product['id'],
//                             'name' => $product['name'],
//                             'type' => $product['type'] ?? '',
//                             'url' => $product['url'] ?? '',
//                             'inChargeIds' => json_decode($product['in_charge_ids'], true) ?: [],
//                             'status' => $product['status'] ?? 'Pending',
//                             'isUrgent' => (bool)$product['isUrgent'] ?? false,
//                             'isRequiredToProceed' => (bool)$product['isRequiredToProceed'] ?? false,
//                             'dateSubmitted' => $product['date_submitted'] ?? '',
//                             'comments' => $this->get_comments('sub_activity_product', $product['id']),
//                             'lastUpdated' => $product['last_updated'] ?? '',
//                             'prod_type' => $product['prod_type'] ?? null,
//                             'quarter' => $quarter_name
//                         ];
//                         $all_output_products[] = $prod_data;
//                     }

//                     // Fetch attachments for sub_activity
//                     $this->db->select('id, title, created_at');
//                     $this->db->where('sub_activity_id', $sub['id']);
//                     $this->db->where('is_active', 1);
//                     $sub_atts = $this->db->get('attachments')->result_array();
//                     foreach ($sub_atts as $att) {
//                         $att_data = [
//                             'id' => (string)$att['id'],
//                             'title' => $att['title'],
//                             // 'description' => $att['description'],
//                             'created_at' => $att['created_at'],
//                             'quarter' => $quarter_name
//                         ];
//                         $all_attachments[] = $att_data;
//                     }
//                 }

//                 // Fetch activity products (general)
//                 $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
//                 $this->db->from('products p');
//                 $this->db->where('p.activity_id', $activity_id);
//                 $this->db->where('p.group', 'general');
//                 $this->db->where('p.is_active', 1);
//                 $products = $this->db->get()->result_array();
//                 foreach ($products as $product) {
//                     $prod_data = [
//                         'id' => (string)$product['id'],
//                         'name' => $product['name'],
//                         'type' => $product['type'] ?? '',
//                         'url' => $product['url'] ?? '',
//                         'inChargeIds' => json_decode($product['in_charge_ids'], true) ?: [],
//                         'status' => $product['status'] ?? 'Pending',
//                         'isUrgent' => (bool)$product['isUrgent'] ?? false,
//                         'isRequiredToProceed' => (bool)$product['isRequiredToProceed'] ?? false,
//                         'dateSubmitted' => $product['date_submitted'] ?? '',
//                         'comments' => $this->get_comments('activity_product', $product['id']),
//                         'lastUpdated' => $product['last_updated'] ?? '',
//                         'prod_type' => $product['prod_type'] ?? null,
//                         'quarter' => $quarter_name
//                     ];
//                     $all_products[] = $prod_data;
//                 }

//                 // Fetch activity outputProducts (output)
//                 $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
//                 $this->db->from('products p');
//                 $this->db->where('p.activity_id', $activity_id);
//                 $this->db->where('p.group', 'output');
//                 $this->db->where('p.is_active', 1);
//                 $output_products = $this->db->get()->result_array();
//                 foreach ($output_products as $product) {
//                     $prod_data = [
//                         'id' => (string)$product['id'],
//                         'name' => $product['name'],
//                         'type' => $product['type'] ?? '',
//                         'url' => $product['url'] ?? '',
//                         'inChargeIds' => json_decode($product['in_charge_ids'], true) ?: [],
//                         'status' => $product['status'] ?? 'Pending',
//                         'isUrgent' => (bool)$product['isUrgent'] ?? false,
//                         'isRequiredToProceed' => (bool)$product['isRequiredToProceed'] ?? false,
//                         'dateSubmitted' => $product['date_submitted'] ?? '',
//                         'comments' => $this->get_comments('activity_product', $product['id']),
//                         'lastUpdated' => $product['last_updated'] ?? '',
//                         'prod_type' => $product['prod_type'] ?? null,
//                         'quarter' => $quarter_name
//                     ];
//                     $all_output_products[] = $prod_data;
//                 }

//                 // Fetch attachments for activity
//                 $this->db->select('id, title, created_at');
//                 $this->db->where('activity_id', $activity_id);
//                 $this->db->where('sub_activity_id IS NULL');
//                 $this->db->where('follow_up_activity_id IS NULL');
//                 $this->db->where('is_active', 1);
//                 $atts = $this->db->get('attachments')->result_array();
//                 foreach ($atts as $att) {
//                     $att_data = [
//                         'id' => (string)$att['id'],
//                         'title' => $att['title'],
//                         // 'description' => $att['description'],
//                         'created_at' => $att['created_at'],
//                         'quarter' => $quarter_name
//                     ];
//                     $all_attachments[] = $att_data;
//                 }

//                 // Fetch outputs for activity
//                 $this->db->select('id, title, created_at');
//                 $this->db->where('activity_id', $activity_id);
//                 $this->db->where('is_active', 1);
//                 $outs = $this->db->get('outputs')->result_array();
//                 foreach ($outs as $out) {
//                     $out_data = [
//                         'id' => (string)$out['id'],
//                         'title' => $out['title'],
//                         'created_at' => $out['created_at'],
//                         'quarter' => $quarter_name
//                     ];
//                     $all_outputs_list[] = $out_data;
//                 }
//             }
//         }
//     }

//     // Fetch outcome title
//     $this->db->select('title as outcome_title');
//     $this->db->where('id', $year_outcome_id);
//     $outcome = $this->db->get('year_outcomes')->row_array();

//     // Fetch months
//     $this->db->select('month');
//     $this->db->where('year_activity_id', $id);
//     $this->db->where('is_active', 1);
//     $months_result = $this->db->get('year_activity_months')->result_array();
//     $months = array_column($months_result, 'month');

//     // Fetch team
//     $inCharges_array = json_decode($year_activity['inCharges'] ?? '[]', true);
//     $inCharges_details = [];
//     if (!empty($inCharges_array)) {
//         $this->db->select('id, first_name, image as avatar');
//         $this->db->where_in('id', $inCharges_array);
//         $this->db->where('is_active', 1);
//         $users = $this->db->get('users')->result_array();
//         foreach ($users as $user) {
//             $inCharges_details[] = [
//                 'id' => (string)$user['id'],
//                 'first_name' => $user['first_name'],
//                 'avatar' => $user['avatar'] ?? ''
//             ];
//         }
//     }
//     $team_response = [
//         'name' => 'Year Activity Team',
//         'members' => $inCharges_details
//     ];

//     $response_data = [
//         'id' => (string)$year_activity['id'],
//         'progress' => (string)$year_activity['progress'],
//         'name' => $year_activity['name'],
//         'code' => floatval($year_activity['code']),
//         'months' => $months,
//         'team' => $team_response,
//         'status' => $year_activity['status'],
//         'outcome' => $outcome['outcome_title'] ?? '',
//         'created_at' => $year_activity['created_at'],
//         'location' => $year_activity['location'],
//         'followUpActivities' => [],
//         'hasFollowUpActivities' => (bool)$year_activity['has_follow_up_activities'],
//         'hasSubActivities' => !empty($all_sub_activities),
//         'subActivities' => $all_sub_activities,
//         'outputs' => [
//             'status' => 'Not Started',
//             'comments' => [],
//             'planned' => count($all_outputs_list),
//             'achieved' => 0,
//             'list' => $all_outputs_list
//         ],
//         'comments' => $this->get_comments('year_activity', $id),
//         'comments_count' => (string)$year_activity['comments_count'],
//         'products' => $all_products,
//         'outputProducts' => $all_output_products,
//         'attachments' => $all_attachments
//     ];

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_FETCHED_SUCCESSFULLY', 'data' => $response_data]));
// }

public function get_year_activity($id)
{
    $user_id = $this->input->get('user_id');

    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $year_activity = $this->db->get('year_activities')->row_array();

    if (empty($year_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_DELETED']));
    }

    $year_outcome_id = $year_activity['year_outcome_id'];
    $this->db->where('id', $year_outcome_id);
    $year_outcome = $this->db->get('year_outcomes')->row_array();
    $year_id = $year_outcome['year_id'] ?? null;

    if (empty($year_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR_OUTCOME']));
    }

    $this->db->where('year_id', $year_id);
    $this->db->where('is_active', 1);
    $quarters = $this->db->get('quarters')->result_array();

    $all_sub_activities = [];
    $all_products = [];
    $all_output_products = [];
    $all_attachments = [];
    $all_outputs_list = [];

    foreach ($quarters as $quarter) {
        $quarter_id = $quarter['id'];
        $quarter_name = $quarter['quarter'];

        $this->db->where('quarter_id', $quarter_id);
        $this->db->where('is_active', 1);
        $outcomes = $this->db->get('outcomes')->result_array();

        foreach ($outcomes as $outcome) {
            $outcome_id = $outcome['id'];

            $this->db->where('outcome_id', $outcome_id);
            $this->db->where('code', $year_activity['code']);
            $this->db->where('is_active', 1);
            $activities = $this->db->get('activities')->result_array();

            foreach ($activities as $activity) {
                $activity_id = $activity['id'];

                // Fetch sub_activities
                $this->db->where('parent_activity_id', $activity_id);
                $this->db->where('is_active', 1);
                $this->db->where('isActiveOnAnnual',1);
                $subs = $this->db->get('sub_activities')->result_array();

                foreach ($subs as $sub) {
                    $inCharges_array = json_decode($sub['inCharges'] ?? '[]', true);
                    $members = [];
                    if (!empty($inCharges_array)) {
                        $this->db->select('id, first_name, image as avatar');
                        $this->db->where_in('id', $inCharges_array);
                        $this->db->where('is_active', 1);
                        $users = $this->db->get('users')->result_array();
                        foreach ($users as $user) {
                            $members[] = [
                                'id' => (string)$user['id'],
                                'first_name' => $user['first_name'],
                                'avatar' => $user['avatar'] ?? ''
                            ];
                        }
                    }
                    $sub_data = [
                        'id' => (string)$sub['id'],
                        'code' => floatval($sub['code']),
                        'name' => $sub['name'],
                        'progress' => (string)$sub['progress'],
                        'status' => $sub['status'],
                        'created_at' => $sub['created_at'],
                        'parent_activity_id'=>$sub['parent_activity_id'],
                        'location' => $sub['location'],
                        // 'has_follow_up_activities' => (bool)$sub['has_follow_up_activities'],
                        'products' => $this->get_sub_activity_products($sub['id'],$isActiveOnAnnual=1),
                        'months'=>$this->get_sub_activity_months($sub['id']),
                
                        'attachments' => $this->get_attachments_for_sub_activity($sub['id'],$isActiveOnAnnual=1),
                        'team' => ['name' => 'Sub Activity Team', 'members' => $members],
                        'comments_count' => (string)$sub['comments_count'],
                        'quarter' => $quarter_name
                    ];
                    $all_sub_activities[] = $sub_data;
                   
                }

                // Fetch activity products (general)
                // $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
                // $this->db->from('products p');
                // $this->db->where('p.activity_id', $activity_id);
                // $this->db->where('p.group', 'general');
                // $this->db->where('p.is_active', 1);
                // $products = $this->db->get()->result_array();
                $activity_products = $this->get_products_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_products = array_merge($all_products, $activity_products);
                // foreach ($products as $product) {
                //     $prod_data = $this->get_products_for_activity($activity_id);
                //     $prod_data['quarter'] = $quarter_name;
                //     $all_products[] = $this->get_products_for_activity($activity_id);
                // }

                // Fetch activity outputProducts (output)
                // $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
                // $this->db->from('products p');
                // $this->db->where('p.activity_id', $activity_id);
                // $this->db->where('p.group', 'output');
                // $this->db->where('p.is_active', 1);
                // $output_products = $this->db->get()->result_array();
                // foreach ($output_products as $product) {
                //     $prod_data = $this->get_output_products_for_activity($activity_id);
                //     $prod_data['quarter'] = $quarter_name;
                //     $all_output_products[] = $prod_data;
                // }
                
                
                $output_products = $this->get_output_products_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_output_products = array_merge($all_output_products, $output_products);

                // Fetch attachments for activity
                // $this->db->select('id, title, created_at');
                // $this->db->where('activity_id', $activity_id);
                // $this->db->where('sub_activity_id IS NULL');
                // $this->db->where('follow_up_activity_id IS NULL');
                // $this->db->where('is_active', 1);
                // $atts = $this->db->get('attachments')->result_array();
                //   foreach ($atts as $att) {
                //     $att_data = $this->get_attachments_for_activity($activity_id);
                //     $att_data['quarter'] = $quarter_name;
                //     $all_attachments[] = $att_data;
                // }
                
                
                $atts = $this->get_attachments_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_attachments = array_merge($all_attachments, $atts);

                // Fetch outputs for activity
                $this->db->select('id, title, created_at');
                $this->db->where('activity_id', $activity_id);
                $this->db->where('is_active', 1);
                $outs = $this->db->get('outputs')->result_array();
                foreach ($outs as $out) {
                    $out_data = [
                        'id' => (string)$out['id'],
                        'title' => $out['title'],
                        'created_at' => $out['created_at'],
                        'quarter' => $quarter_name
                    ];
                    $all_outputs_list[] = $out_data;
                }
            }
        }
    }

    // Fetch outcome title
    $this->db->select('title as outcome_title');
    $this->db->where('id', $year_outcome_id);
    $outcome = $this->db->get('year_outcomes')->row_array();

    // Fetch months
    $this->db->select('month');
    $this->db->where('year_activity_id', $id);
    $this->db->where('is_active', 1);
    $months_result = $this->db->get('year_activity_months')->result_array();
    $months = array_column($months_result, 'month');

    // Fetch team
    $inCharges_array = json_decode($year_activity['inCharges'] ?? '[]', true);
    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1);
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'],
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }
    $team_response = [
        'name' => 'Year Activity Team',
        'members' => $inCharges_details
    ];


    $year_activity_outputs = $this->db->get_where('year_activity_outputs',array('year_activity_id'=>$year_activity['id']))->result_array();

    // Calculate sums
    $total_planned = 0;
    $total_achieved = 0;
    foreach ($year_activity_outputs as $output) {
      $total_planned += (float)$output['planned'];
      $total_achieved += (float)$output['achieved'];
    }

    $response_data = [
      'id' => (string)$year_activity['id'],
      'progress' => (string)$year_activity['progress'],
      'name' => $year_activity['name'],
      'code' => floatval($year_activity['code']),
      'months' => $months,
      'team' => $team_response,
      'status' => $year_activity['status'],
      'outcome' => $outcome['outcome_title'] ?? '',
      'created_at' => $year_activity['created_at'],
      'location' => $year_activity['location'],
      'followUpActivities' => [],
      'hasFollowUpActivities' => (bool)$year_activity['has_follow_up_activities'],
      'hasSubActivities' => !empty($all_sub_activities),
      'subActivities' => $all_sub_activities,
      'outputs' => [
        'status' => $year_activity_outputs[0]['status'] ?? '',
        'comments' => [],
        'planned' => $total_planned,
        'achieved' => $total_achieved,
        'list' => $year_activity_outputs
      ],
      'comments' => $this->get_comments('year_activity', $id),
      'comments_count' => (string)$year_activity['comments_count'],
      'products' => $all_products,
      'outputProducts' => $all_output_products,
      'attachments' => $all_attachments
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_FETCHED_SUCCESSFULLY', 'data' => $response_data]));
}

public function get_year_activity_test($id)
{
    $user_id = $this->input->get('user_id');

    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $year_activity = $this->db->get('year_activities')->row_array();

    if (empty($year_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_DELETED']));
    }

    $year_outcome_id = $year_activity['year_outcome_id'];
    $this->db->where('id', $year_outcome_id);
    $year_outcome = $this->db->get('year_outcomes')->row_array();
    $year_id = $year_outcome['year_id'] ?? null;

    if (empty($year_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR_OUTCOME']));
    }

    $this->db->where('year_id', $year_id);
    $this->db->where('is_active', 1);
    $quarters = $this->db->get('quarters')->result_array();

    $all_sub_activities = [];
    $all_products = [];
    $all_output_products = [];
    $all_attachments = [];
    $all_outputs_list = [];

    foreach ($quarters as $quarter) {
        $quarter_id = $quarter['id'];
        $quarter_name = $quarter['quarter'];

        $this->db->where('quarter_id', $quarter_id);
        $this->db->where('is_active', 1);
        $outcomes = $this->db->get('outcomes')->result_array();

        foreach ($outcomes as $outcome) {
            $outcome_id = $outcome['id'];

            $this->db->where('outcome_id', $outcome_id);
            $this->db->where('code', $year_activity['code']);
            $this->db->where('is_active', 1);
            $activities = $this->db->get('activities')->result_array();

            foreach ($activities as $activity) {
                $activity_id = $activity['id'];

                // Fetch sub_activities
                $this->db->where('parent_activity_id', $activity_id);
                $this->db->where('is_active', 1);
                $this->db->where('isActiveOnAnnual',1);
                $subs = $this->db->get('sub_activities')->result_array();

                foreach ($subs as $sub) {
                    $inCharges_array = json_decode($sub['inCharges'] ?? '[]', true);
                    $members = [];
                    if (!empty($inCharges_array)) {
                        $this->db->select('id, first_name, image as avatar');
                        $this->db->where_in('id', $inCharges_array);
                        $this->db->where('is_active', 1);
                        $users = $this->db->get('users')->result_array();
                        foreach ($users as $user) {
                            $members[] = [
                                'id' => (string)$user['id'],
                                'first_name' => $user['first_name'],
                                'avatar' => $user['avatar'] ?? ''
                            ];
                        }
                    }
                    $sub_data = [
                        'id' => (string)$sub['id'],
                        'code' => floatval($sub['code']),
                        'name' => $sub['name'],
                        'progress' => (string)$sub['progress'],
                        'status' => $sub['status'],
                        'created_at' => $sub['created_at'],
                        'location' => $sub['location'],
                        // 'has_follow_up_activities' => (bool)$sub['has_follow_up_activities'],
                        'products' => $this->get_sub_activity_products($sub['id'],$isActiveOnAnnual=1),
                        'months'=>$this->get_sub_activity_months($sub['id']),
                
                        'attachments' => $this->get_attachments_for_sub_activity($sub['id'],$isActiveOnAnnual=1),
                        'team' => ['name' => 'Sub Activity Team', 'members' => $members],
                        'comments_count' => (string)$sub['comments_count'],
                        'quarter' => $quarter_name
                    ];
                    $all_sub_activities[] = $sub_data;
                   
                }

                // Fetch activity products (general)
                // $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
                // $this->db->from('products p');
                // $this->db->where('p.activity_id', $activity_id);
                // $this->db->where('p.group', 'general');
                // $this->db->where('p.is_active', 1);
                // $products = $this->db->get()->result_array();
                $activity_products = $this->get_products_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_products = array_merge($all_products, $activity_products);
                // foreach ($products as $product) {
                //     $prod_data = $this->get_products_for_activity($activity_id);
                //     $prod_data['quarter'] = $quarter_name;
                //     $all_products[] = $this->get_products_for_activity($activity_id);
                // }

                // Fetch activity outputProducts (output)
                // $this->db->select('p.id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type');
                // $this->db->from('products p');
                // $this->db->where('p.activity_id', $activity_id);
                // $this->db->where('p.group', 'output');
                // $this->db->where('p.is_active', 1);
                // $output_products = $this->db->get()->result_array();
                // foreach ($output_products as $product) {
                //     $prod_data = $this->get_output_products_for_activity($activity_id);
                //     $prod_data['quarter'] = $quarter_name;
                //     $all_output_products[] = $prod_data;
                // }
                
                
                $output_products = $this->get_output_products_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_output_products = array_merge($all_output_products, $output_products);

                // Fetch attachments for activity
                // $this->db->select('id, title, created_at');
                // $this->db->where('activity_id', $activity_id);
                // $this->db->where('sub_activity_id IS NULL');
                // $this->db->where('follow_up_activity_id IS NULL');
                // $this->db->where('is_active', 1);
                // $atts = $this->db->get('attachments')->result_array();
                //   foreach ($atts as $att) {
                //     $att_data = $this->get_attachments_for_activity($activity_id);
                //     $att_data['quarter'] = $quarter_name;
                //     $all_attachments[] = $att_data;
                // }
                
                
                $atts = $this->get_attachments_for_activity($activity_id, $isActiveOnAnnual=1);
                $all_attachments = array_merge($all_attachments, $atts);

                // Fetch outputs for activity
                $this->db->select('id, title, created_at');
                $this->db->where('activity_id', $activity_id);
                $this->db->where('is_active', 1);
                $outs = $this->db->get('outputs')->result_array();
                foreach ($outs as $out) {
                    $out_data = [
                        'id' => (string)$out['id'],
                        'title' => $out['title'],
                        'created_at' => $out['created_at'],
                        'quarter' => $quarter_name
                    ];
                    $all_outputs_list[] = $out_data;
                }
            }
        }
    }

    // Fetch outcome title
    $this->db->select('title as outcome_title');
    $this->db->where('id', $year_outcome_id);
    $outcome = $this->db->get('year_outcomes')->row_array();

    // Fetch months
    $this->db->select('month');
    $this->db->where('year_activity_id', $id);
    $this->db->where('is_active', 1);
    $months_result = $this->db->get('year_activity_months')->result_array();
    $months = array_column($months_result, 'month');

    // Fetch team
    $inCharges_array = json_decode($year_activity['inCharges'] ?? '[]', true);
    $inCharges_details = [];
    if (!empty($inCharges_array)) {
        $this->db->select('id, first_name, image as avatar');
        $this->db->where_in('id', $inCharges_array);
        $this->db->where('is_active', 1);
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $inCharges_details[] = [
                'id' => (string)$user['id'],
                'first_name' => $user['first_name'],
                'avatar' => $user['avatar'] ?? ''
            ];
        }
    }
    $team_response = [
        'name' => 'Year Activity Team',
        'members' => $inCharges_details
    ];


    $year_activity_outputs = $this->db->get_where('year_activity_outputs',array('year_activity_id'=>$year_activity['id']))->result_array();

    // Calculate sums
    $total_planned = 0;
    $total_achieved = 0;
    foreach ($year_activity_outputs as $output) {
      $total_planned += (float)$output['planned'];
      $total_achieved += (float)$output['achieved'];
    }

    $response_data = [
      'id' => (string)$year_activity['id'],
      'progress' => (string)$year_activity['progress'],
      'name' => $year_activity['name'],
      'code' => floatval($year_activity['code']),
      'months' => $months,
      'team' => $team_response,
      'status' => $year_activity['status'],
      'outcome' => $outcome['outcome_title'] ?? '',
      'created_at' => $year_activity['created_at'],
      'location' => $year_activity['location'],
      'followUpActivities' => [],
      'hasFollowUpActivities' => (bool)$year_activity['has_follow_up_activities'],
      'hasSubActivities' => !empty($all_sub_activities),
      'subActivities' => $all_sub_activities,
      'outputs' => [
        'status' => $year_activity_outputs[0]['status'] ?? '',
        'comments' => [],
        'planned' => $total_planned,
        'achieved' => $total_achieved,
        'list' => $all_outputs_list
      ],
      'comments' => $this->get_comments('year_activity', $id),
      'comments_count' => (string)$year_activity['comments_count'],
      'products' => $all_products,
      'outputProducts' => $all_output_products,
      'attachments' => $all_attachments
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'YEAR_ACTIVITY_FETCHED_SUCCESSFULLY', 'data' => $response_data]));
}

private function get_year_activity_months($year_activity_id)
{
    $this->db->select('month');
    $this->db->where('year_activity_id', $year_activity_id);
    $this->db->where('is_active', 1);
    $months = $this->db->get('year_activity_months')->result_array();

    $month_order = [
        'January' => 1, 'February' => 2, 'March' => 3, 'April' => 4,
        'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8,
        'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12
    ];

    $month_names = array_column($months, 'month');
    usort($month_names, function($a, $b) use ($month_order) {
        return $month_order[$a] - $month_order[$b];
    });

    return $month_names;
}


private function get_year_activity_outputs($year_activity_id)
{
    $this->db->select('id, title, status, planned, achieved, comments');
    $this->db->where('year_activity_id', $year_activity_id);
    $this->db->where('is_active', 1);
    $outputs = $this->db->get('year_activity_outputs')->result_array();

    $output_data = [
        'status' => 'Not Started',
        'comments' =>$this->get_comments('outputs', $year_activity_id,'yearly'),
        'planned' => 0,
        'achieved' => 0,
        'list' => []
    ];

    foreach ($outputs as $output) {
        $output_data['list'][] = [
            'id' => (string)$output['id'],
            'title' => $output['title'],
            'status' => $output['status'],
            'progress' => [
                'planned' => (int)$output['planned'],
                'achieved' => (int)$output['achieved']
            ],
            'comments' => $output['comments'] ?? ''
        ];
    }

    if (!empty($outputs)) {
        $output_data['status'] = $this->aggregate_output_status($outputs);
        $output_data['planned'] = array_sum(array_column($outputs, 'planned'));
        $output_data['achieved'] = array_sum(array_column($outputs, 'achieved'));
        // $output_data['comments'] = array_unique(array_filter(array_column($outputs, 'comments')));
    }

    return $output_data;
}

public function delete_year_activity()
{
    // Validate user_id (assuming it's passed via GET or form for authentication)
    $id = $this->input->get("year_activity_id");
    $user_id = $this->input->get('user_id');
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'INVALID_USER_ID'
            ]));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'INVALID_USER_ID'
            ]));
    }

    // Validate year activity exists and is active
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $year_activity = $this->db->get('year_activities')->row_array();

    if (empty($year_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'YEAR_ACTIVITY_NOT_FOUND_OR_ALREADY_DELETED'
            ]));
    }

    // Start a transaction
    $this->db->trans_start();

    // Determine delete type (soft by default, hard if specified)
    $delete_type = $this->input->get('delete_type') ?? 'soft';
    if (!in_array($delete_type, ['soft', 'hard'])) {
        $this->db->trans_rollback();
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'INVALID_DELETE_TYPE'
            ]));
    }

    if ($delete_type === 'soft') {
        // Perform soft delete: update is_active to 0 and set deleted_at
        $data = [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ];

        // Update year activity
        $this->db->where('id', $id);
        $this->db->update('year_activities', $data);

        // Soft delete related outputs
        $this->db->where('year_activity_id', $id);
        $this->db->where('is_active', 1);
        $this->db->update('year_activity_outputs', $data);

        // Soft delete related months
        $this->db->where('year_activity_id', $id);
        $this->db->where('is_active', 1);
        $this->db->update('year_activity_months', $data);
    } else {
        // Perform hard delete: delete the year activity and related records
        $this->db->where('id', $id);
        $this->db->delete('year_activities');

        // Delete related outputs
        $this->db->where('year_activity_id', $id);
        $this->db->delete('year_activity_outputs');

        // Delete related months
        $this->db->where('year_activity_id', $id);
        $this->db->delete('year_activity_months');
    }

    // Commit the transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'DELETE_FAILED - ' . $this->db->error()['message']
            ]));
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode([
            'success' => true,
            'message' => ($delete_type === 'soft' ? 'YEAR_ACTIVITY_SOFT_DELETED_SUCCESSFULLY' : 'YEAR_ACTIVITY_HARD_DELETED_SUCCESSFULLY'),
            'data' => [
                'year_activity_id' => $id,
                'delete_type' => $delete_type
            ]
        ]));
}

public function sync_all_quarterly_activities()
{
    // Step 1: Fetch all active year_activities
    $this->db->where('is_active', 1);
    $year_activities = $this->db->get('year_activities')->result_array();

    if (empty($year_activities)) {
        return ['success' => false, 'message' => 'NO_ACTIVE_YEAR_ACTIVITIES_FOUND'];
    }

    // Step 2: Quarter mapping
    $quarter_map = [
        'Q1' => ['January', 'February', 'March'],
        'Q2' => ['April', 'May', 'June'],
        'Q3' => ['July', 'August', 'September'],
        'Q4' => ['October', 'November', 'December']
    ];

    // Step 3: Process each year_activity
    $this->db->trans_start();
    $processed = 0;
    $errors = [];

    foreach ($year_activities as $year_activity) {
        $year_activity_id = $year_activity['id'];

        // Fetch active months for this year_activity
        $this->db->select('month');
        $this->db->where('year_activity_id', $year_activity_id);
        $this->db->where('is_active', 1);
        $active_months = $this->db->get('year_activity_months')->result_array();
        $active_months = array_column($active_months, 'month');

        if (empty($active_months)) {
            log_message('debug', "No active months found for year_activity_id: $year_activity_id");
            continue; // Skip if no active months
        }

        // Determine affected quarters
        $affected_quarters = [];
        foreach ($active_months as $month) {
            foreach ($quarter_map as $quarter => $quarter_months) {
                if (in_array($month, $quarter_months)) {
                    $affected_quarters[$quarter] = true;
                }
            }
        }
        $affected_quarters = array_keys($affected_quarters);

        // Get year_id from year_outcome
        $this->db->where('id', $year_activity['year_outcome_id']);
        $year_outcome = $this->db->get('year_outcomes')->row_array();
        if (empty($year_outcome)) {
            $errors[] = "Year outcome not found for year_activity_id: $year_activity_id";
            continue;
        }
        $year_id = $year_outcome['year_id'];

        // Get existing quarters for this year
        $this->db->where('year_id', $year_id);
        // $this->db->where('is_active', 1);
        $quarters = $this->db->get('quarters')->result_array();
        $quarter_map_by_name = array_column($quarters, 'id', 'quarter');

        // Fetch existing quarterly activities for this year_activity's code
        $this->db->select('a.id, a.outcome_id, q.quarter');
        $this->db->from('activities a');
        $this->db->join('outcomes o', 'o.id = a.outcome_id');
        $this->db->join('quarters q', 'q.id = o.quarter_id');
        $this->db->where('a.code', $year_activity['code']);
        $this->db->where('q.year_id', $year_id);
        $this->db->where('a.is_active', 1);
        $existing_activities = $this->db->get()->result_array();
        $existing_quarters = array_column($existing_activities, 'quarter');

        // Create missing quarterly activities
        $user_id = $year_activity['updated_by']; // Use last updater as creator
        foreach ($affected_quarters as $quarter) {
            if (!in_array($quarter, $existing_quarters)) {
                // Create or fetch quarter
                if (!isset($quarter_map_by_name[$quarter])) {
                    $quarter_data = [
                        'year_id' => $year_id,
                        'quarter' => $quarter,
                        'is_active' => 1,
                        // 'created_by' => $user_id,
                        // 'updated_by' => $user_id,
                        // 'created_at' => date('Y-m-d H:i:s'),
                        // 'updated_at' => date('Y-m-d H:i:s')
                    ];
                    $this->db->insert('quarters', $quarter_data);
                    $quarter_id = $this->db->insert_id();
                } else {
                    $quarter_id = $quarter_map_by_name[$quarter];
                }

                // Create or fetch outcome
                $this->db->where('quarter_id', $quarter_id);
                $this->db->where('title', $year_outcome['title']);
                $this->db->where('is_active', 1);
                $outcome = $this->db->get('outcomes')->row_array();

                if (empty($outcome)) {
                    $outcome_data = [
                        'quarter_id' => $quarter_id,
                        'title' => $year_outcome['title'],
                        'progress' => '0',
                        'is_active' => 1,
                        // 'created_by' => $user_id,
                        // 'updated_by' => $user_id,
                        // 'created_at' => date('Y-m-d H:i:s'),
                        // 'updated_at' => date('Y-m-d H:i:s')
                    ];
                    $this->db->insert('outcomes', $outcome_data);
                    $outcome_id = $this->db->insert_id();
                } else {
                    $outcome_id = $outcome['id'];
                }

                // Create the missing activity
                $activity_data = [
                    'outcome_id' => $outcome_id,
                    'name' => $year_activity['name'],
                    'code' => $year_activity['code'],
                    'progress' => $year_activity['progress'],
                    'status' => $year_activity['status'],
                    'location' => $year_activity['location'],
                    'has_sub_activities' => $year_activity['has_sub_activities'],
                    'has_follow_up_activities' => $year_activity['has_follow_up_activities'],
                    'inCharges' => $year_activity['inCharges'],
                    'created_by' => $user_id,
                    'updated_by' => $user_id,
                    'created_at' => $year_activity['created_at'],
                    'updated_at' => date('Y-m-d H:i:s'),
                    'is_active' => 1
                ];
                $this->db->insert('activities', $activity_data);
                $activity_id = $this->db->insert_id();

                // Add corresponding months to activity_months
                $quarter_months = array_intersect($active_months, $quarter_map[$quarter]);
                if (!empty($quarter_months)) {
                    $activity_month_data = array_map(function($month) use ($activity_id, $user_id) {
                        return [
                            'activity_id' => $activity_id,
                            'month' => $month,
                            'created_by' => $user_id,
                            'updated_by' => $user_id,
                            'created_at' => date('Y-m-d H:i:s'),
                            'updated_at' => date('Y-m-d H:i:s'),
                            'is_active' => 1
                        ];
                    }, $quarter_months);
                    $this->db->insert_batch('activity_months', $activity_month_data);
                }

                $processed++;
                log_message('debug', "Created quarterly activity for year_activity_id: $year_activity_id, quarter: $quarter");
            }
        }
    }

    // Step 4: Commit transaction
    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        return [
            'success' => false,
            'message' => 'TRANSACTION_FAILED',
            'errors' => $errors,
            'processed' => $processed
        ];
    }

    return [
        'success' => true,
        'message' => 'ALL_QUARTERLY_ACTIVITIES_SYNCED_SUCCESSFULLY',
        'processed' => $processed,
        'errors' => $errors
    ];
}

public function run_sync_all_quarterly_activities()
{
    $result = $this->sync_all_quarterly_activities();
    $this->output
        ->set_content_type('application/json')
        ->set_status_header($result['success'] ? 200 : 400)
        ->set_output(json_encode($result));
}

public function transfer_products_to_activity()
{
    // Get form data
    $source_activity_id = $this->input->post('source_activity_id');
    $target_activity_id = $this->input->post('target_activity_id');
    $user_id = $this->input->post('user_id'); // User initiating the transfer
    $product_ids = $this->input->post('product_ids'); // Optional: specific product IDs to transfer, else all active products

    // Validate required fields
    if (empty($source_activity_id) || empty($target_activity_id) || empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }

    // Validate source and target activities
    $this->db->where('id', $source_activity_id);
    $this->db->where('is_active', 1);
    $source_activity = $this->db->get('activities')->row_array();
    if (empty($source_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'SOURCE_ACTIVITY_NOT_FOUND']));
    }

    $this->db->where('id', $target_activity_id);
    $this->db->where('is_active', 1);
    $target_activity = $this->db->get('activities')->row_array();
    if (empty($target_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'TARGET_ACTIVITY_NOT_FOUND']));
    }

    // Validate different quarters
    $this->db->select('q.quarter');
    $this->db->from('quarters q');
    $this->db->join('outcomes o', 'o.quarter_id = q.id');
    $this->db->where('o.id', $source_activity['outcome_id']);
    $source_quarter = $this->db->get()->row('quarter');

    $this->db->select('q.quarter');
    $this->db->from('quarters q');
    $this->db->join('outcomes o', 'o.quarter_id = q.id');
    $this->db->where('o.id', $target_activity['outcome_id']);
    $target_quarter = $this->db->get()->row('quarter');

    if ($source_quarter === $target_quarter) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'SOURCE_AND_TARGET_MUST_BE_IN_DIFFERENT_QUARTERS']));
    }

    // Fetch products to transfer
    $this->db->where('activity_id', $source_activity_id);
    $this->db->where('is_active', 1); // Assuming products have an is_active flag
    if (!empty($product_ids)) {
        $parsed_ids = json_decode($product_ids, true);
        if (is_array($parsed_ids)) {
            $this->db->where_in('id', array_filter(array_map('intval', $parsed_ids)));
        } else {
            $ids = explode(',', str_replace(['[', ']', '"'], '', $product_ids));
            $this->db->where_in('id', array_filter(array_map('trim', $ids), 'strlen'));
        }
    }
    $products = $this->db->get('products')->result_array();

    if (empty($products)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'NO_PRODUCTS_FOUND_TO_TRANSFER']));
    }

    // Start transaction
    $this->db->trans_start();

    $transferred_products = [];
    $directory = "products";
    if (!file_exists($directory)) {
        mkdir($directory, 0777, true);
    }

    foreach ($products as $product) {
        // Prepare new product data
        $new_product_data = [
            'activity_id' => $target_activity_id,
            'name' => $product['name'],
            'type' => $product['type'],
            'url' => '', // Will be updated if file is copied
            'status' => $product['status'],
            'date_submitted' => $product['date_submitted'],
            'last_updated' => date('Y-m-d'), // Update to current date
            'in_charge_ids' => $product['in_charge_ids'], // Retain original in_charge_ids
            'prod_type' => $product['prod_type'],
            'group' => $product['group'],
            'output_id' => $product['output_id'],
            'created_by' => $product['created_by'], // Retain original creator
            'updated_by' => $user_id,
            'is_active' => 1
        ];

        // Insert new product
        $this->db->insert('products', $new_product_data);
        $new_product_id = $this->db->insert_id();

        // Handle file transfer
        if ($product['type'] === 'folder') {
            // Transfer multiple files from product_files
            $this->db->where('product_id', $product['id']);
            $product_files = $this->db->get('product_files')->result_array();

            if (!empty($product_files)) {
                $new_files = [];
                foreach ($product_files as $file) {
                    $old_file_path = FCPATH . $file['url'];
                    $new_file_name = uniqid() . '_' . $file['name'];
                    $new_file_path = "$directory/$new_file_name";

                    if (file_exists($old_file_path)) {
                        if (copy($old_file_path, FCPATH . $new_file_path)) {
                            $new_files[] = [
                                'product_id' => $new_product_id,
                                'name' => $file['name'],
                                'type' => $file['type'],
                                'url' => $new_file_path,
                                'date' => $file['date'],
                                'size' => $file['size'],
                                'created_by' => $file['created_by'],
                                'updated_by' => $user_id
                            ];
                        } else {
                            $this->db->trans_rollback();
                            log_message('error', "Failed to copy file: $old_file_path to $new_file_path");
                            return $this->output
                                ->set_content_type('application/json')
                                ->set_status_header(400)
                                ->set_output(json_encode(['success' => false, 'message' => 'FILE_COPY_FAILED']));
                        }
                    }
                }
                if (!empty($new_files)) {
                    $this->db->insert_batch('product_files', $new_files);
                }
            }
        } else {
            // Transfer single file
            if (!empty($product['url'])) {
                $old_file_path = FCPATH . $product['url'];
                $file_extension = pathinfo($product['url'], PATHINFO_EXTENSION);
                $new_file_name = uniqid() . '.' . $file_extension;
                $new_file_path = "$directory/$new_file_name";

                if (file_exists($old_file_path)) {
                    if (copy($old_file_path, FCPATH . $new_file_path)) {
                        $this->db->where('id', $new_product_id);
                        $this->db->update('products', ['url' => $new_file_path]);
                    } else {
                        $this->db->trans_rollback();
                        log_message('error', "Failed to copy file: $old_file_path to $new_file_path");
                        return $this->output
                            ->set_content_type('application/json')
                            ->set_status_header(400)
                            ->set_output(json_encode(['success' => false, 'message' => 'FILE_COPY_FAILED']));
                    }
                }
            }
        }

        // Optionally deactivate the source product
        $this->db->where('id', $product['id']);
        $this->db->update('products', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $transferred_products[] = $new_product_id;
    }

    // Update target activity status
    if (!empty($transferred_products)) {
        $this->db->where('id', $target_activity_id);
        $target_activity_status = $this->db->get('activities')->row('status');
        if ($target_activity_status !== 'Finalised') {
            $this->db->where('id', $target_activity_id);
            $this->db->update('activities', [
                'status' => 'In Progress',
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }
    }

    // Commit transaction
    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
    }

    // Fetch transferred products for response
    $response_data = [];
    foreach ($transferred_products as $product_id) {
        $this->db->where('id', $product_id);
        $product = $this->db->get('products')->row_array();

        $in_charge_ids_array = json_decode($product['in_charge_ids'], true) ?: [];
        $in_charge_details = [];
        if (!empty($in_charge_ids_array)) {
            $this->db->select('id, first_name, image as avatar');
            $this->db->where_in('id', $in_charge_ids_array);
            $users = $this->db->get('users')->result_array();
            foreach ($users as $user) {
                $in_charge_details[] = [
                    'id' => $user['id'],
                    'first_name' => $user['first_name'],
                    'avatar' => $user['avatar']
                ];
            }
        }

        $product_files = [];
        if ($product['type'] === 'folder') {
            $this->db->where('product_id', $product_id);
            $files_data = $this->db->get('product_files')->result_array();
            foreach ($files_data as $file) {
                $product_files[] = [
                    'id' => $file['id'],
                    'name' => $file['name'],
                    'type' => $file['type'],
                    'url' => $file['url'],
                    'date' => $file['date'],
                    'size' => $file['size']
                ];
            }
        }

        $response_data[] = [
            'id' => $product['id'],
            'type' => $product['type'],
            'name' => $product['name'],
            'url' => $product['url'],
            'inCharge' => $in_charge_details,
            'status' => $product['status'],
            'dateSubmitted' => $product['date_submitted'],
            'lastUpdated' => $product['last_updated'],
            'files' => $product_files
        ];
    }

    // Optional notification logic (similar to create_product)
    $this->load->library('phpmailer_lib');
    $mail = $this->phpmailer_lib->load();
    $mail->isSMTP();
    $mail->Host = 'smarthub.ovalspace.co';
    $mail->SMTPAuth = true;
    $mail->Username = 'notifications@smarthub.ovalspace.co';
    $mail->Password = 'wgw6.)O7sCTy';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
    $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
    $mail->isHTML(true);

    // Fetch activity details for link
    $this->db->select('a.name as activity_name, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
    $this->db->from('activities a');
    $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
    $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
    $this->db->join('years y', 'q.year_id = y.id', 'left');
    $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
    $this->db->where('a.id', $target_activity_id);
    $target_activity_data = $this->db->get()->row_array();

    $activity_name = $target_activity_data['activity_name'] ?? 'Unknown Activity';
    $programme_code = $target_activity_data['programme_code'] ?? 'SDLG';
    $quarter = $target_activity_data['quarter'] ?? 'Q1';
    $year = $target_activity_data['year'] ?? '2025';
    $app_link = "http://localhost:8080/ug/programmes";
    $activity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$target_activity_id}";

    // Fetch creator details
    $this->db->select('first_name');
    $this->db->where('id', $user_id);
    $creator = $this->db->get('users')->row_array();
    $creator_name = $creator['first_name'] ?? 'Unknown';

    $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
        . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
        . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
        . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
        . '</div>';

    $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
        . '&copy; 2025 VNG International | SmartHub<br>'
        . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
        . '</div>';

    // Notify target activity team
    $in_charge_ids_array = json_decode($target_activity['inCharges'], true) ?: [];
    if (!empty($in_charge_ids_array)) {
        $this->db->select('id, email');
        $this->db->where_in('id', $in_charge_ids_array);
        $team_members = $this->db->get('users')->result_array();
        $team_emails = array_column($team_members, 'email');
        $team_user_ids = array_column($team_members, 'id');

        if (!empty($team_emails)) {
            foreach ($team_emails as $email) {
                // $mail->addAddress($email);
                $mail->addAddress("kimbowaandrew@gmail.com");
            }

            $product_count = count($transferred_products);
            $notification_title = 'Products Transferred';
            $notification_message = "$product_count product(s) have been transferred to activity: $activity_name from Q$source_quarter by $creator_name.";
            $email_subject = 'Products Transferred to Your Activity';
            $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                . "<tr><td>$header</td></tr>"
                . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                . "<h2 style='color: #333; margin: 0 0 20px;'>Products Transferred to Your Activity</h2>"
                . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
                . "<p style='margin: 0 0 15px;'><strong>$product_count product(s)</strong> have been transferred to activity: "
                . "<a href='$activity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($activity_name) . "</a> "
                . "from Q$source_quarter by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
                . "<p style='margin: 0;'>Please review the transferred products.</p>"
                . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                . "</td></tr>"
                . "<tr><td align='center'>$footer</td></tr>"
                . "</table></body></html>";
            $email_alt_body = "Dear Team,\n\n$product_count product(s) have been transferred to activity: $activity_name ($activity_link) from Q$source_quarter by $creator_name.\n\nPlease review the transferred products.\n\nRegards,\nSmartHub";

            foreach ($team_user_ids as $team_user_id) {
                $this->db->insert('notifications', [
                    'user_id' => $team_user_id,
                    'type' => 'PRODUCT_TRANSFER',
                    'title' => $notification_title,
                    'message' => $notification_message,
                    'link' => $activity_link,
                    'is_read' => 0,
                    'created_by' => $user_id
                ]);
            }

            $mail->Subject = $email_subject;
            $mail->Body = $email_body;
            $mail->AltBody = $email_alt_body;
            if (!$mail->send()) {
                log_message('error', 'Failed to send email to team: ' . $mail->ErrorInfo);
            }
            $mail->clearAddresses();
        }
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201)
        ->set_output(json_encode([
            'success' => true,
            'message' => 'PRODUCTS_TRANSFERRED_SUCCESSFULLY',
            'data' => $response_data
        ]));
}

//incorporating quarterly and yearly: 

// Add a comment to any entity without notifications
    // public function add_comment()
    // {
    //     $json_data = json_decode(@file_get_contents('php://input'), true);
    //     $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
    //     $entity_id = $json_data['entity_id'];
    //     $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
    //     $body = $json_data['body'];
    //     $user_id = $json_data['user_id'];

    //     // Validate inputs
    //     if (empty($entity_id) || empty($body) || empty($user_id)) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    //     }

    //     // Validate time_frame
    //     if (!in_array($time_frame, ['quarterly', 'yearly'])) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
    //     }

    //     // Validate user exists
    //     $this->db->where('id', $user_id);
    //     if ($this->db->get('users')->num_rows() == 0) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    //     }

    //     // Determine the table and validate entity based on entity_type and time_frame
    //     $table = $this->get_entity_table($entity_type, $time_frame);
    //     $this->db->where('id', $entity_id);
    //     $this->db->where('is_active', 1);
    //     if ($this->db->get($table)->num_rows() == 0) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
    //     }

    //     // Insert comment with is_quarterly flag
    //     $data = [
    //         'entity_type' => $entity_type,
    //         'entity_id' => $entity_id,
    //         'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
    //         'body' => $body,
    //         'created_by' => $user_id,
    //         'updated_by' => $user_id,
    //         'is_active' => 1
    //     ];
    //     $this->db->trans_start();
    //     $this->db->insert('comments', $data);
    //     $comment_id = $this->db->insert_id();

    //     // Update comments_count for supported entities
    //     if ($entity_type === 'activity') {
    //         $this->db->set('comments_count', 'comments_count + 1', FALSE);
    //         $this->db->where('id', $entity_id);
    //         $this->db->update($table); // Use the determined table
    //     }

    //     $this->db->trans_complete();
    //     if ($this->db->trans_status() === FALSE) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(500)
    //             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
    //     }

    //     $comment = $this->get_comment_details($comment_id);
    //     return $this->output
    //         ->set_content_type('application/json')
    //         ->set_status_header(201)
    //         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
    // }
    
    
// Add a comment to any entity with notifications
// live
// public function add_comment()
// {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
//     $entity_id = $json_data['entity_id'];
//     $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     // Validate inputs
//     if (empty($entity_id) || empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate time_frame
//     if (!in_array($time_frame, ['quarterly', 'yearly'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
//     }

//     // Validate user and fetch main_office
//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $creator_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
//     }

//     // Insert comment
//     $data = [
//         'entity_type' => $entity_type,
//         'entity_id' => $entity_id,
//         'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
//         'body' => $body,
//         'created_by' => $user_id,
//         'updated_by' => $user_id,
//         'is_active' => 1
//     ];
//     $this->db->trans_start();
//     $this->db->insert('comments', $data);
//     $comment_id = $this->db->insert_id();

//     // Update comments_count for supported entities
//     if ($entity_type === 'activity') {
//         $this->db->set('comments_count', 'comments_count + 1', FALSE);
//         $this->db->where('id', $entity_id);
//         $this->db->update($table);
//     }

//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(500)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
//     }

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//         case 'activity_output_product':
//         case 'sub_activity_product':
//         case 'followup_activity_product':
//         case 'sub_activity_followup_activity_product':
//             $this->db->select('activity_id, sub_activity_id, follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ??
//                                     ($product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('in_charge_ids, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['in_charge_ids'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude creator)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude creator
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude creator from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->result_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude creator)
//     $admin_emails = ['admin1@smarthub.ovalspace.co', 'admin2@smarthub.ovalspace.co']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude creator
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'New Comment Added';
//         $notification_message = "A new comment on the {$entity_display_type}: \"{$entity_name}\" has been added by {$creator_name}.";
//         $email_subject = 'New Comment Notification';
//         $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//             . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//             . "<tr><td>$header</td></tr>"
//             . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//             . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
//             . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//             . "<p style='margin: 0 0 15px;'>A new comment has been added on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//             . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//             . "by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
//             . "<p style='margin: 0;'>Comment: \"" . htmlspecialchars($body) . "\"</p>"
//             . "<p style='margin: 0;'>Please review as necessary.</p>"
//             . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//             . "</td></tr>"
//             . "<tr><td align='center'>$footer</td></tr>"
//             . "</table></body></html>";
//         $email_alt_body = "Dear Team,\n\nA new comment has been added on the {$entity_display_type}: {$entity_name} ($entity_link) by {$creator_name}.\nComment: \"$body\"\n\nPlease review as necessary.\n\nRegards,\nSmartHub";

//         // Send email
//         foreach ($all_emails as $email) {
//             $mail->addAddress($email);
//         }
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_CREATION',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(201)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
// }


// public function add_comment()
// {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
//     $entity_id = $json_data['entity_id'];
//     $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     // Validate inputs
//     if (empty($entity_id) || empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate time_frame
//     if (!in_array($time_frame, ['quarterly', 'yearly'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
//     }

//     // Validate user and fetch main_office
//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $creator_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
//     }

//     // Insert comment
//     $data = [
//         'entity_type' => $entity_type,
//         'entity_id' => $entity_id,
//         'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
//         'body' => $body,
//         'created_by' => $user_id,
//         'updated_by' => $user_id,
//         'is_active' => 1
//     ];
//     $this->db->trans_start();
//     $this->db->insert('comments', $data);
//     $comment_id = $this->db->insert_id();

//     // Update comments_count for supported entities
//     if ($entity_type === 'activity') {
//         $this->db->set('comments_count', 'comments_count + 1', FALSE);
//         $this->db->where('id', $entity_id);
//         $this->db->update($table);
//     }

//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(500)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
//     }

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//         case 'activity_output_product':
//         case 'sub_activity_product':
//         case 'followup_activity_product':
//         case 'sub_activity_followup_activity_product':
//             $this->db->select('activity_id, sub_activity_id, follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ??
//                                     ($product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude creator)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude creator
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude creator from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->result_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude creator)
//     $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude creator
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'New Comment Added';
//         $notification_message = "A new comment on the {$entity_display_type}: \"{$entity_name}\" has been added by {$creator_name}.";
//         $email_subject = 'New Comment Notification';
//       $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//     . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//     . "<tr><td>$header</td></tr>"
//     . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//     . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
//     . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//     . "<p style='margin: 0 0 15px;'>A new comment has been added on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//     . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//     . "by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
//     . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
//     . "<p style='color: #333; margin: 0; font-weight: bold;'>Comment:</p>"
//     . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
//     . "</div>"
//     . "<p style='margin: 0;'>Please review as necessary.</p>"
//     . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//     . "</td></tr>"
//     . "<tr><td align='center'>$footer</td></tr>"
//     . "</table></body></html>";
// $email_alt_body = "Dear Team,\n\nA new comment has been added on the {$entity_display_type}: {$entity_name} ($entity_link) by {$creator_name}.\n\nComment: \"$body\"\n\nPlease review as necessary.\n\nRegards,\nSmartHub";
//         // Send email
//         foreach ($all_emails as $email) {
//             // $mail->addAddress("kimbowaandrew@gmail.com");
//             $mail->addAddress($email);
//         }
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_CREATION',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(201)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
// }

// public function add_comment()
// {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
//     $entity_id = $json_data['entity_id'];
//     $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     // Validate inputs
//     if (empty($entity_id) || empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate time_frame
//     if (!in_array($time_frame, ['quarterly', 'yearly'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
//     }

//     // Validate user and fetch main_office
//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $creator_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
//     }

//     // Insert comment
//     $data = [
//         'entity_type' => $entity_type,
//         'entity_id' => $entity_id,
//         'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
//         'body' => $body,
//         'created_by' => $user_id,
//         'updated_by' => $user_id,
//         'is_active' => 1
//     ];
//     $this->db->trans_start();
//     $this->db->insert('comments', $data);
//     $comment_id = $this->db->insert_id();

//     // Update comments_count for supported entities
//     if ($entity_type === 'activity') {
//         $this->db->set('comments_count', 'comments_count + 1', FALSE);
//         $this->db->where('id', $entity_id);
//         $this->db->update($table);
//     }

//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(500)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
//     }

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//         case 'activity_output_product':
//             $this->db->select('activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ?? null;
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         case 'sub_activity_product':
//             $this->db->select('sub_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('sub_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         case 'followup_activity_product':
//             $this->db->select('follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('follow_up_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude creator)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude creator
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude creator from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->result_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude creator)
//     // $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
//     $admin_emails = ['andrew@ovalspace.co']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude creator
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'New Comment Added';
//         $notification_message = "A new comment on the {$entity_display_type}: \"{$entity_name}\" has been added by {$creator_name}.";
//         $email_subject = 'New Comment Notification';
//         $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//             . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//             . "<tr><td>$header</td></tr>"
//             . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//             . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
//             . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//             . "<p style='margin: 0 0 15px;'>A new comment has been added on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//             . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//             . "by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
//             . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
//             . "<p style='color: #333; margin: 0; font-weight: bold;'>Comment:</p>"
//             . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
//             . "</div>"
//             . "<p style='margin: 0;'>Please review as necessary.</p>"
//             . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//             . "</td></tr>"
//             . "<tr><td align='center'>$footer</td></tr>"
//             . "</table></body></html>";
//         $email_alt_body = "Dear Team,\n\nA new comment has been added on the {$entity_display_type}: {$entity_name} ($entity_link) by {$creator_name}.\n\nComment: \"$body\"\n\nPlease review as necessary.\n\nRegards,\nSmartHub";

//         // Send email
//         foreach ($all_emails as $email) {
//             // $mail->addAddress($email);
//             $mail->addAddress('kimbowaandrew@gmail.com');
//         }
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_CREATION',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(201)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
// }
    
    //without AIM tasks
//     public function add_comment()
//   {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
//     $entity_id = $json_data['entity_id'];
//     $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     // Validate inputs
//     if (empty($entity_id) || empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     // Validate time_frame
//     if (!in_array($time_frame, ['quarterly', 'yearly'])) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
//     }

//     // Validate user and fetch main_office
//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $creator_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
//     }

//     // Insert comment
//     $data = [
//         'entity_type' => $entity_type,
//         'entity_id' => $entity_id,
//         'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
//         'body' => $body,
//         'created_by' => $user_id,
//         'updated_by' => $user_id,
//         'is_active' => 1
//     ];
//     $this->db->trans_start();
//     $this->db->insert('comments', $data);
//     $comment_id = $this->db->insert_id();

//     // Update comments_count for supported entities
//     if ($entity_type === 'activity') {
//         $this->db->set('comments_count', 'comments_count + 1', FALSE);
//         $this->db->where('id', $entity_id);
//         $this->db->update($table);
//     }

//     $this->db->trans_complete();
//     if ($this->db->trans_status() === FALSE) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(500)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
//     }

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//             $this->db->select('activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ?? null;
//                 $entity_name = $product['name'] ?? 'Unknown Activity Product';
//                 $entity_display_type = 'Activity Product';
//             }
//             break;
//         case 'activity_output_product':
//             $this->db->select('activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ?? null;
//                 $entity_name = $product['name'] ?? 'Unknown Activity Output Product';
//                 $entity_display_type = 'Activity Output Product';
//             }
//             break;
//         case 'sub_activity_product':
//             $this->db->select('sub_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('sub_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Sub Activity Product';
//                 $entity_display_type = 'Sub Activity Product';
//             }
//             break;
//         case 'followup_activity_product':
//             $this->db->select('follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('follow_up_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Follow Up Activity Product';
//                 $entity_display_type = 'Follow Up Activity Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude creator)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude creator
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude creator from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->result_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude creator)
//     $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude creator
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'New Comment Added';
//         $notification_message = "A new comment on the {$entity_display_type}: \"{$entity_name}\" has been added by {$creator_name}.";
//         $email_subject = 'New Comment Notification';
//         $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//             . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//             . "<tr><td>$header</td></tr>"
//             . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//             . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
//             . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//             . "<p style='margin: 0 0 15px;'>A new comment has been added on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//             . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//             . "by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
//             . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
//             . "<p style='color: #333; margin: 0; font-weight: bold;'>Comment:</p>"
//             . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
//             . "</div>"
//             . "<p style='margin: 0;'>Please review as necessary.</p>"
//             . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//             . "</td></tr>"
//             . "<tr><td align='center'>$footer</td></tr>"
//             . "</table></body></html>";
//         $email_alt_body = "Dear Team,\n\nA new comment has been added on the {$entity_display_type}: {$entity_name} ($entity_link) by {$creator_name}.\n\nComment: \"$body\"\n\nPlease review as necessary.\n\nRegards,\nSmartHub";

//         // Send email
//         foreach ($all_emails as $email) {
//             $mail->addAddress($email);
//          }
         
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_CREATION',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(201)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
// }


// with AIM tasks
 public function add_comment()
   {
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $entity_type = $json_data['entity_type'] ?? 'activity'; // Default to 'activity'
    $entity_id = $json_data['entity_id'];
    $time_frame = $json_data['time_frame'] ?? 'quarterly'; // Default to 'quarterly'
    $body = $json_data['body'];
    $user_id = $json_data['user_id'];

    // Validate inputs
    if (empty($entity_id) || empty($body) || empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    // Validate time_frame
    if (!in_array($time_frame, ['quarterly', 'yearly'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIME_FRAME']));
    }

    // Validate user and fetch main_office
    $this->db->select('id, first_name, main_office');
    $this->db->where('id', $user_id);
    $user = $this->db->get('users')->row_array();
    if (!$user) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }
    $creator_name = $user['first_name'];
    $main_office = strtolower($user['main_office'] ?? '');

    // Determine the table and validate entity
    $table = $this->get_entity_table($entity_type, $time_frame);
    $this->db->where('id', $entity_id);
    $this->db->where('is_active', 1);
    if ($this->db->get($table)->num_rows() == 0) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => strtoupper($entity_type) . '_NOT_FOUND']));
    }

    // Insert comment
    $data = [
        'entity_type' => $entity_type,
        'entity_id' => $entity_id,
        'is_quarterly' => ($time_frame === 'quarterly') ? 1 : 0,
        'body' => $body,
        'created_by' => $user_id,
        'updated_by' => $user_id,
        'is_active' => 1
    ];
    $this->db->trans_start();
    $this->db->insert('comments', $data);
    $comment_id = $this->db->insert_id();

    // Update comments_count for supported entities
    if ($entity_type === 'activity') {
        $this->db->set('comments_count', 'comments_count + 1', FALSE);
        $this->db->where('id', $entity_id);
        $this->db->update($table);
    }

    $this->db->trans_complete();
    if ($this->db->trans_status() === FALSE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_ADD_FAILED']));
    }

    // Notification logic
    $this->load->library('phpmailer_lib');
    $mail = $this->phpmailer_lib->load();
    $mail->isSMTP();
    $mail->Host = 'smarthub.ovalspace.co';
    $mail->SMTPAuth = true;
    $mail->Username = 'notifications@smarthub.ovalspace.co';
    $mail->Password = 'wgw6.)O7sCTy';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
    $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
    $mail->isHTML(true);

    // Determine entity details and main activity ID
    $main_activity_id = null;
    $entity_name = '';
    $entity_link = '';
    $entity_display_type = '';
    $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
    $in_charge_ids = [];
    $notify_finance = false;
    $task_entity;

    // Fetch entity-specific details
    switch ($entity_type) {
        case 'attachment':
        case 'sub_activity_attachment':
        case 'followup_activity_attachment':
        case 'sub_activity_followup_activity_attachment':
            $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
            $this->db->where('id', $entity_id);
            $attachment = $this->db->get('attachments')->row_array();
            if ($attachment) {
                $entity_name = $attachment['title'] ?? 'Unknown Attachment';
                $entity_display_type = 'Attachment';
                $notify_finance = $attachment['notify_finance_team'] == 1;
                $main_activity_id = $attachment['activity_id'] ??
                                    ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
                                    ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
            }
            break;
        case 'activity':
            $main_activity_id = $entity_id;
            $this->db->select('name');
            $this->db->where('id', $entity_id);
            $activity = $this->db->get($table)->row_array();
            $entity_name = $activity['name'] ?? 'Unknown Activity';
            $entity_display_type = 'Activity';
            break;
        case 'sub_activity':
            $this->db->select('parent_activity_id, name');
            $this->db->where('id', $entity_id);
            $sub_activity = $this->db->get('sub_activities')->row_array();
            $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
            $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
            $entity_display_type = 'Sub Activity';
            break;
        case 'followup_activity':
            $this->db->select('parent_activity_id, name');
            $this->db->where('id', $entity_id);
            $follow_up = $this->db->get('follow_up_activities')->row_array();
            $main_activity_id = $follow_up['parent_activity_id'] ?? null;
            $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
            $entity_display_type = 'Follow Up Activity';
            break;
        case 'outputs':
            $this->db->select('id, name');
            $this->db->where('id', $entity_id);
            $activity = $this->db->get('activities')->row_array();
            $main_activity_id = $activity['id'] ?? null;
            $entity_name = $activity['name'] ?? 'Outputs';
            $entity_display_type = 'Outputs of Activity';
            break;
        case 'activity_product':
            $this->db->select('activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('products')->row_array();
            if ($product) {
                $main_activity_id = $product['activity_id'] ?? null;
                $entity_name = $product['name'] ?? 'Unknown Activity Product';
                $entity_display_type = 'Activity Product';
            }
            break;
        case 'activity_output_product':
            $this->db->select('activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('products')->row_array();
            if ($product) {
                $main_activity_id = $product['activity_id'] ?? null;
                $entity_name = $product['name'] ?? 'Unknown Activity Output Product';
                $entity_display_type = 'Activity Output Product';
            }
            break;
        case 'sub_activity_product':
            $this->db->select('sub_activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('sub_activity_products')->row_array();
            if ($product) {
                $main_activity_id = $product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null;
                $entity_name = $product['name'] ?? 'Unknown Sub Activity Product';
                $entity_display_type = 'Sub Activity Product';
            }
            break;
        case 'followup_activity_product':
            $this->db->select('follow_up_activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('follow_up_activity_products')->row_array();
            if ($product) {
                $main_activity_id = $product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null;
                $entity_name = $product['name'] ?? 'Unknown Follow Up Activity Product';
                $entity_display_type = 'Follow Up Activity Product';
            }
            case 'task':
            $this->db->select('t.task, t.task_date, u.first_name as task_owner, u.email as task_owner_email, u.id as task_owner_id');
            $this->db->from('aim_tasks t');
            $this->db->join('timesheets ts', 't.timesheet_id = ts.id', 'left');
            $this->db->join('users u', 'ts.created_by = u.id', 'left');
            $this->db->where('t.id', $entity_id);
            $task = $this->db->get()->row_array();
            if ($task) {
                $entity_name = $task['task'];
                $entity_display_type = 'Task';
                $task_entity = $task;
            }
            break;
                default:
                    $entity_name = "Unknown $entity_type";
                    $entity_display_type = ucfirst($entity_type);
                    break;
            }

            // Fetch main activity details for link and in-charges
            if ($main_activity_id) {
                $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
                $this->db->from('activities a');
                $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
                $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
                $this->db->join('years y', 'q.year_id = y.id', 'left');
                $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
                $this->db->where('a.id', $main_activity_id);
                $activity_data = $this->db->get()->row_array();
                if ($activity_data) {
                    $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
                    $programme_code = $activity_data['programme_code'] ?? 'SDLG';
                    $quarter = $activity_data['quarter'] ?? 'Q1';
                    $year = $activity_data['year'] ?? '2025';
                    $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
                } else {
                    $entity_link = $app_link;
                }
            } else {
                $entity_link = $app_link;
            }

            // Define recipient groups
            // In-charges (exclude creator)
            $in_charge_emails = [];
            $in_charge_ids_filtered = [];
            if (!empty($in_charge_ids)) {
                $this->db->select('id, email');
                $this->db->where_in('id', $in_charge_ids);
                $this->db->where('id !=', $user_id); // Exclude creator
                $this->db->where('is_active', 1);
                $in_charge_users = $this->db->get('users')->result_array();
                $in_charge_emails = array_column($in_charge_users, 'email');
                $in_charge_ids_filtered = array_column($in_charge_users, 'id');
            }

            // Task owner (include even if they're the creator)
            $task_owner_email = [];
            $task_owner_id = [];
            if ($entity_type === 'task' && !empty($task_entity['task_owner_email'])) {
                $task_owner_email[] = $task_entity['task_owner_email'];
                $task_owner_id[] = $task_entity['task_owner_id'];
            }

              // Previous commenters on this task
            $previous_commenter_emails = [];
            $previous_commenter_ids = [];
            if ($entity_type === 'task') {
                $this->db->distinct();
                $this->db->select('u.id, u.email');
                $this->db->from('comments c');
                $this->db->join('users u', 'c.created_by = u.id', 'left');
                $this->db->where('c.entity_type', 'task');
                $this->db->where('c.entity_id', $entity_id);
                $this->db->where('c.is_active', 1);
                $this->db->where('u.id !=', $user_id); // Exclude current user
                $this->db->where('u.is_active', 1);
                $previous_commenters = $this->db->get()->result_array();
                $previous_commenter_emails = array_column($previous_commenters, 'email');
                $previous_commenter_ids = array_column($previous_commenters, 'id');
            }

            // Finance team (only if notify_finance_team is 1)
            $finance_emails = [];
            $finance_user_ids = [];
            if ($notify_finance) {
                $finance_team_map = [
                    'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
                    'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
                ];
                $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
                $finance_emails = $default_finance_emails;
                foreach ($finance_team_map as $office_key => $emails) {
                    if (stripos($main_office, $office_key) !== false) {
                        $finance_emails = $emails;
                        break;
                    }
                }
                // Exclude creator from finance team
                $this->db->select('id, email');
                $this->db->where_in('email', $finance_emails);
                $this->db->where('id !=', $user_id);
                $finance_users = $this->db->get('users')->result_array();
                $finance_emails = array_column($finance_users, 'email');
                $finance_user_ids = array_column($finance_users, 'id');
            }

            // Admin team (exclude creator)
            $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
            $this->db->select('id, email');
            $this->db->where_in('email', $admin_emails);
            $this->db->where('id !=', $user_id); // Exclude creator
            $admin_users = $this->db->get('users')->result_array();
            $admin_emails = array_column($admin_users, 'email');
            $admin_user_ids = array_column($admin_users, 'id');
            
            

            // Combine recipients
            $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails, $task_owner_email, $previous_commenter_emails));
            $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids, $task_owner_id, $previous_commenter_ids));

            if (!empty($all_emails)) {
                // Email template
                $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
                    . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
                    . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
                    . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
                    . '</div>';
                $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
                    . '&copy; 2025 VNG International | SmartHub<br>'
                    . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
                    . '</div>';

                $notification_title = 'New Comment Added';
                $notification_message = "A new comment on the {$entity_display_type}: \"{$entity_name}\" has been added by {$creator_name}.";
                $email_subject = 'New Comment Notification';
                // Check if entity type is task and customize email content accordingly
                 if ($entity_type === 'task') {
                    $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                            . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                            . "<tr><td>$header</td></tr>"
                            . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                            . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
                            . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
                            . "<p style='margin: 0 0 15px;'><strong>" . htmlspecialchars($creator_name) . "</strong> has added a comment in the Activity Implementation Matrix on " . htmlspecialchars($task_entity['task_owner']) . "'s Task: <strong>" . htmlspecialchars($entity_name) . "</strong>" . (isset($task_entity['task_date']) ? " scheduled on " . date('l jS F, Y', strtotime($task_entity['task_date'])) : "") . ".</p>"
                            . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
                            . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
                            . "</div>"
                            . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                            . "</td></tr>"
                            . "<tr><td align='center'>$footer</td></tr>"
                            . "</table></body></html>";
                    $email_alt_body = "Dear Team,\n\n" . $creator_name . " has added a comment in the Activity Implementation Matrix on {$entity_type}: {$entity_name}.\n\nComment: \"$body\"\n\nRegards,\nSmartHub";
                }  else { 
                    $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                            . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                            . "<tr><td>$header</td></tr>"
                            . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                            . "<h2 style='color: #333; margin: 0 0 20px;'>New Comment Notification</h2>"
                            . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
                            . "<p style='margin: 0 0 15px;'>A new comment has been added on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
                            . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
                            . "by <strong>" . htmlspecialchars($creator_name) . "</strong>.</p>"
                            . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
                            . "<p style='color: #333; margin: 0; font-weight: bold;'>Comment:</p>"
                            . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
                            . "</div>"
                            . "<p style='margin: 0;'>Please review as necessary.</p>"
                            . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                            . "</td></tr>"
                            . "<tr><td align='center'>$footer</td></tr>"
                            . "</table></body></html>";
                    $email_alt_body = "Dear Team,\n\nA new comment has been added on the {$entity_display_type}: {$entity_name} ($entity_link) by {$creator_name}.\n\nComment: \"$body\"\n\nPlease review as necessary.\n\nRegards,\nSmartHub";
                }

        // Send email
        foreach ($all_emails as $email) {
            $mail->addAddress($email);
            
         }
         
        $mail->Subject = $email_subject;
        $mail->Body = $email_body;
        $mail->AltBody = $email_alt_body;
        if (!$mail->send()) {
            log_message('error', 'Failed to send comment notification email: ' . $mail->ErrorInfo);
        }
        $mail->clearAddresses();

        // Store in-app notifications
        foreach ($all_user_ids as $user_id_to_notify) {
            $this->db->insert('notifications', [
                'user_id' => $user_id_to_notify,
                'type' => 'COMMENT_CREATION',
                'title' => $notification_title,
                'message' => $notification_message,
                'link' => $entity_link,
                'is_read' => 0,
                'created_by' => $user_id
            ]);
        }
    }

    $comment = $this->get_comment_details($comment_id);
    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201)
        ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_ADDED', 'data' => $comment]));
}


    // Edit a comment without notifications
    // public function edit_comment($comment_id)
    // {
    //     $json_data = json_decode(@file_get_contents('php://input'), true);
    //     $body = $json_data['body'];
    //     $user_id = $json_data['user_id'];

    //     if (empty($body) || empty($user_id)) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    //     }

    //     $this->db->where('id', $comment_id);
    //     $this->db->where('is_active', 1);
    //     $comment = $this->db->get('comments')->row_array();
    //     if (empty($comment)) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_NOT_FOUND']));
    //     }

    //     $this->db->where('id', $user_id);
    //     if ($this->db->get('users')->num_rows() == 0) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    //     }

    //     $data = [
    //         'body' => $body,
    //         'updated_by' => $user_id,
    //         'updated_at' => date('Y-m-d H:i:s')
    //     ];
    //     $this->db->where('id', $comment_id);
    //     $this->db->update('comments', $data);

    //     $updated_comment = $this->get_comment_details($comment_id);
    //     return $this->output
    //         ->set_content_type('application/json')
    //         ->set_status_header(200)
    //         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
    // }
    
    // with notifications
    
//     public function edit_comment($comment_id)
// {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     if (empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     $this->db->where('id', $comment_id);
//     $this->db->where('is_active', 1);
//     $comment = $this->db->get('comments')->row_array();
//     if (empty($comment)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_NOT_FOUND']));
//     }

//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $editor_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Update the comment
//     $data = [
//         'body' => $body,
//         'updated_by' => $user_id,
//         'updated_at' => date('Y-m-d H:i:s')
//     ];
//     $this->db->where('id', $comment_id);
//     $this->db->update('comments', $data);

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $entity_type = $comment['entity_type'];
//     $entity_id = $comment['entity_id'];
//     $time_frame = $comment['is_quarterly'] ? 'quarterly' : 'yearly';
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         // Proceed without notification if entity is not found (soft fail)
//         $updated_comment = $this->get_comment_details($comment_id);
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
//     }

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//         case 'activity_output_product':
//         case 'sub_activity_product':
//         case 'followup_activity_product':
//         case 'sub_activity_followup_activity_product':
//             $this->db->select('activity_id, sub_activity_id, follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ??
//                                     ($product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//                 $entity_name = $product['name'] ?? 'Unknown Product';
//                 $entity_display_type = 'Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude editor)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude editor
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude editor from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->result_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude editor)
//     $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude editor
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'Comment Updated';
//         $notification_message = "A comment on the {$entity_display_type}: \"{$entity_name}\" has been updated by {$editor_name}.";
//         $email_subject = 'Comment Updated Notification';
//         $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//             . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//             . "<tr><td>$header</td></tr>"
//             . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//             . "<h2 style='color: #333; margin: 0 0 20px;'>Comment Updated Notification</h2>"
//             . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//             . "<p style='margin: 0 0 15px;'>A comment on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//             . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//             . "has been updated by <strong>" . htmlspecialchars($editor_name) . "</strong>.</p>"
//             . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
//             . "<p style='color: #333; margin: 0; font-weight: bold;'>Updated Comment:</p>"
//             . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
//             . "</div>"
//             . "<p style='margin: 0;'>Please review as necessary.</p>"
//             . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//             . "</td></tr>"
//             . "<tr><td align='center'>$footer</td></tr>"
//             . "</table></body></html>";
//         $email_alt_body = "Dear Team,\n\nA comment on the {$entity_display_type}: {$entity_name} ($entity_link) has been updated by {$editor_name}.\n\nUpdated Comment: " . strip_tags($body) . "\n\nPlease review as necessary.\n\nRegards,\nSmartHub";

//         // Send email
//         foreach ($all_emails as $email) {
//             // $mail->addAddress('kimbowaandrew@gmail.com');
//             $mail->addAddress($email);
//         }
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment update notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_UPDATE',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $updated_comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
// }

// without AIM tasks
// public function edit_comment($comment_id)
// {
//     $json_data = json_decode(@file_get_contents('php://input'), true);
//     $body = $json_data['body'];
//     $user_id = $json_data['user_id'];

//     if (empty($body) || empty($user_id)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//     }

//     $this->db->where('id', $comment_id);
//     $this->db->where('is_active', 1);
//     $comment = $this->db->get('comments')->row_array();
//     if (empty($comment)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_NOT_FOUND']));
//     }

//     $this->db->select('id, first_name, main_office');
//     $this->db->where('id', $user_id);
//     $user = $this->db->get('users')->row_array();
//     if (!$user) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//     }
//     $editor_name = $user['first_name'];
//     $main_office = strtolower($user['main_office'] ?? '');

//     // Update the comment
//     $data = [
//         'body' => $body,
//         'updated_by' => $user_id,
//         'updated_at' => date('Y-m-d H:i:s')
//     ];
//     $this->db->where('id', $comment_id);
//     $this->db->update('comments', $data);

//     // Notification logic
//     $this->load->library('phpmailer_lib');
//     $mail = $this->phpmailer_lib->load();
//     $mail->isSMTP();
//     $mail->Host = 'smarthub.ovalspace.co';
//     $mail->SMTPAuth = true;
//     $mail->Username = 'notifications@smarthub.ovalspace.co';
//     $mail->Password = 'wgw6.)O7sCTy';
//     $mail->SMTPSecure = 'ssl';
//     $mail->Port = 465;
//     $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//     $mail->isHTML(true);

//     // Determine entity details and main activity ID
//     $entity_type = $comment['entity_type'];
//     $entity_id = $comment['entity_id'];
//     $time_frame = $comment['is_quarterly'] ? 'quarterly' : 'yearly';
//     $main_activity_id = null;
//     $entity_name = '';
//     $entity_link = '';
//     $entity_display_type = '';
//     $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
//     $in_charge_ids = [];
//     $notify_finance = false;

//     // Determine the table and validate entity
//     $table = $this->get_entity_table($entity_type, $time_frame);
//     $this->db->where('id', $entity_id);
//     $this->db->where('is_active', 1);
//     if ($this->db->get($table)->num_rows() == 0) {
//         // Proceed without notification if entity is not found (soft fail)
//         $updated_comment = $this->get_comment_details($comment_id);
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
//     }

//     // Fetch entity-specific details
//     switch ($entity_type) {
//         case 'attachment':
//         case 'sub_activity_attachment':
//         case 'followup_activity_attachment':
//         case 'sub_activity_followup_activity_attachment':
//             $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
//             $this->db->where('id', $entity_id);
//             $attachment = $this->db->get('attachments')->row_array();
//             if ($attachment) {
//                 $entity_name = $attachment['title'] ?? 'Unknown Attachment';
//                 $entity_display_type = 'Attachment';
//                 $notify_finance = $attachment['notify_finance_team'] == 1;
//                 $main_activity_id = $attachment['activity_id'] ??
//                                     ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
//                                     ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
//             }
//             break;
//         case 'activity':
//             $main_activity_id = $entity_id;
//             $this->db->select('name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get($table)->row_array();
//             $entity_name = $activity['name'] ?? 'Unknown Activity';
//             $entity_display_type = 'Activity';
//             break;
//         case 'sub_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $sub_activity = $this->db->get('sub_activities')->row_array();
//             $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
//             $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
//             $entity_display_type = 'Sub Activity';
//             break;
//         case 'followup_activity':
//             $this->db->select('parent_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $follow_up = $this->db->get('follow_up_activities')->row_array();
//             $main_activity_id = $follow_up['parent_activity_id'] ?? null;
//             $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
//             $entity_display_type = 'Follow Up Activity';
//             break;
//         case 'outputs':
//             $this->db->select('id, name');
//             $this->db->where('id', $entity_id);
//             $activity = $this->db->get('activities')->row_array();
//             $main_activity_id = $activity['id'] ?? null;
//             $entity_name = $activity['name'] ?? 'Outputs';
//             $entity_display_type = 'Outputs of Activity';
//             break;
//         case 'activity_product':
//             $this->db->select('activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ?? null;
//                 $entity_name = $product['name'] ?? 'Unknown Activity Product';
//                 $entity_display_type = 'Activity Product';
//             }
//             break;
//         case 'activity_output_product':
//             $this->db->select('activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['activity_id'] ?? null;
//                 $entity_name = $product['name'] ?? 'Unknown Activity Output Product';
//                 $entity_display_type = 'Activity Output Product';
//             }
//             break;
//         case 'sub_activity_product':
//             $this->db->select('sub_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('sub_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Sub Activity Product';
//                 $entity_display_type = 'Sub Activity Product';
//             }
//             break;
//         case 'followup_activity_product':
//             $this->db->select('follow_up_activity_id, name');
//             $this->db->where('id', $entity_id);
//             $product = $this->db->get('follow_up_activity_products')->row_array();
//             if ($product) {
//                 $main_activity_id = $product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null;
//                 $entity_name = $product['name'] ?? 'Unknown Follow Up Activity Product';
//                 $entity_display_type = 'Follow Up Activity Product';
//             }
//             break;
//         default:
//             $entity_name = "Unknown $entity_type";
//             $entity_display_type = ucfirst($entity_type);
//             break;
//     }

//     // Fetch main activity details for link and in-charges
//     if ($main_activity_id) {
//         $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
//         $this->db->from('activities a');
//         $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
//         $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
//         $this->db->join('years y', 'q.year_id = y.id', 'left');
//         $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
//         $this->db->where('a.id', $main_activity_id);
//         $activity_data = $this->db->get()->row_array();
//         if ($activity_data) {
//             $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
//             $programme_code = $activity_data['programme_code'] ?? 'SDLG';
//             $quarter = $activity_data['quarter'] ?? 'Q1';
//             $year = $activity_data['year'] ?? '2025';
//             $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
//         } else {
//             $entity_link = $app_link;
//         }
//     } else {
//         $entity_link = $app_link;
//     }

//     // Define recipient groups
//     // In-charges (exclude editor)
//     $in_charge_emails = [];
//     $in_charge_ids_filtered = [];
//     if (!empty($in_charge_ids)) {
//         $this->db->select('id, email');
//         $this->db->where_in('id', $in_charge_ids);
//         $this->db->where('id !=', $user_id); // Exclude editor
//         $this->db->where('is_active', 1);
//         $in_charge_users = $this->db->get('users')->result_array();
//         $in_charge_emails = array_column($in_charge_users, 'email');
//         $in_charge_ids_filtered = array_column($in_charge_users, 'id');
//     }

//     // Finance team (only if notify_finance_team is 1)
//     $finance_emails = [];
//     $finance_user_ids = [];
//     if ($notify_finance) {
//         $finance_team_map = [
//             'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//             'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
//         ];
//         $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//         $finance_emails = $default_finance_emails;
//         foreach ($finance_team_map as $office_key => $emails) {
//             if (stripos($main_office, $office_key) !== false) {
//                 $finance_emails = $emails;
//                 break;
//             }
//         }
//         // Exclude editor from finance team
//         $this->db->select('id, email');
//         $this->db->where_in('email', $finance_emails);
//         $this->db->where('id !=', $user_id);
//         $finance_users = $this->db->get('users')->row_array();
//         $finance_emails = array_column($finance_users, 'email');
//         $finance_user_ids = array_column($finance_users, 'id');
//     }

//     // Admin team (exclude editor)
//     $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
//     $this->db->select('id, email');
//     $this->db->where_in('email', $admin_emails);
//     $this->db->where('id !=', $user_id); // Exclude editor
//     $admin_users = $this->db->get('users')->result_array();
//     $admin_emails = array_column($admin_users, 'email');
//     $admin_user_ids = array_column($admin_users, 'id');

//     // Combine recipients
//     $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails));
//     $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids));

//     if (!empty($all_emails)) {
//         // Email template
//         $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//             . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//             . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//             . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//             . '</div>';
//         $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//             . '&copy; 2025 VNG International | SmartHub<br>'
//             . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//             . '</div>';

//         $notification_title = 'Comment Updated';
//         $notification_message = "A comment on the {$entity_display_type}: \"{$entity_name}\" has been updated by {$editor_name}.";
//         $email_subject = 'Comment Updated Notification';
//         $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//             . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//             . "<tr><td>$header</td></tr>"
//             . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//             . "<h2 style='color: #333; margin: 0 0 20px;'>Comment Updated Notification</h2>"
//             . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
//             . "<p style='margin: 0 0 15px;'>A comment on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
//             . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
//             . "has been updated by <strong>" . htmlspecialchars($editor_name) . "</strong>.</p>"
//             . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
//             . "<p style='color: #333; margin: 0; font-weight: bold;'>Updated Comment:</p>"
//             . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
//             . "</div>"
//             . "<p style='margin: 0;'>Please review as necessary.</p>"
//             . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//             . "</td></tr>"
//             . "<tr><td align='center'>$footer</td></tr>"
//             . "</table></body></html>";
//         $email_alt_body = "Dear Team,\n\nA comment on the {$entity_display_type}: {$entity_name} ($entity_link) has been updated by {$editor_name}.\n\nUpdated Comment: " . strip_tags($body) . "\n\nPlease review as necessary.\n\nRegards,\nSmartHub";

//         // Send email
//         foreach ($all_emails as $email) {
//             $mail->addAddress($email);
//         }
//         $mail->Subject = $email_subject;
//         $mail->Body = $email_body;
//         $mail->AltBody = $email_alt_body;
//         if (!$mail->send()) {
//             log_message('error', 'Failed to send comment update notification email: ' . $mail->ErrorInfo);
//         }
//         $mail->clearAddresses();

//         // Store in-app notifications
//         foreach ($all_user_ids as $user_id_to_notify) {
//             $this->db->insert('notifications', [
//                 'user_id' => $user_id_to_notify,
//                 'type' => 'COMMENT_UPDATE',
//                 'title' => $notification_title,
//                 'message' => $notification_message,
//                 'link' => $entity_link,
//                 'is_read' => 0,
//                 'created_by' => $user_id
//             ]);
//         }
//     }

//     $updated_comment = $this->get_comment_details($comment_id);
//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
// }

// with AIM tasks

public function edit_comment($comment_id)
{
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $body = $json_data['body'];
    $user_id = $json_data['user_id'];

    if (empty($body) || empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    }

    $this->db->where('id', $comment_id);
    $this->db->where('is_active', 1);
    $comment = $this->db->get('comments')->row_array();
    if (empty($comment)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_NOT_FOUND']));
    }

    $this->db->select('id, first_name, main_office');
    $this->db->where('id', $user_id);
    $user = $this->db->get('users')->row_array();
    if (!$user) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    }
    $editor_name = $user['first_name'];
    $main_office = strtolower($user['main_office'] ?? '');

    // Update the comment
    $data = [
        'body' => $body,
        'updated_by' => $user_id,
        'updated_at' => date('Y-m-d H:i:s')
    ];
    $this->db->where('id', $comment_id);
    $this->db->update('comments', $data);

    // Notification logic
    $this->load->library('phpmailer_lib');
    $mail = $this->phpmailer_lib->load();
    $mail->isSMTP();
    $mail->Host = 'smarthub.ovalspace.co';
    $mail->SMTPAuth = true;
    $mail->Username = 'notifications@smarthub.ovalspace.co';
    $mail->Password = 'wgw6.)O7sCTy';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;
    $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
    $mail->isHTML(true);

    // Determine entity details and main activity ID
    $entity_type = $comment['entity_type'];
    $entity_id = $comment['entity_id'];
    $time_frame = $comment['is_quarterly'] ? 'quarterly' : 'yearly';
    $main_activity_id = null;
    $entity_name = '';
    $entity_link = '';
    $entity_display_type = '';
    $app_link = "https://www.smarthub.ovalspace.co/ug/programmes";
    $in_charge_ids = [];
    $notify_finance = false;

    // Determine the table and validate entity
    $table = $this->get_entity_table($entity_type, $time_frame);
    $this->db->where('id', $entity_id);
    $this->db->where('is_active', 1);
    if ($this->db->get($table)->num_rows() == 0) {
        // Proceed without notification if entity is not found (soft fail)
        $updated_comment = $this->get_comment_details($comment_id);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
    }

    // Fetch entity-specific details
    switch ($entity_type) {
        case 'attachment':
        case 'sub_activity_attachment':
        case 'followup_activity_attachment':
        case 'sub_activity_followup_activity_attachment':
            $this->db->select('title, activity_id, sub_activity_id, follow_up_activity_id, notify_finance_team');
            $this->db->where('id', $entity_id);
            $attachment = $this->db->get('attachments')->row_array();
            if ($attachment) {
                $entity_name = $attachment['title'] ?? 'Unknown Attachment';
                $entity_display_type = 'Attachment';
                $notify_finance = $attachment['notify_finance_team'] == 1;
                $main_activity_id = $attachment['activity_id'] ??
                                    ($attachment['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null) ??
                                    ($attachment['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $attachment['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null);
            }
            break;
        case 'activity':
            $main_activity_id = $entity_id;
            $this->db->select('name');
            $this->db->where('id', $entity_id);
            $activity = $this->db->get($table)->row_array();
            $entity_name = $activity['name'] ?? 'Unknown Activity';
            $entity_display_type = 'Activity';
            break;
        case 'sub_activity':
            $this->db->select('parent_activity_id, name');
            $this->db->where('id', $entity_id);
            $sub_activity = $this->db->get('sub_activities')->row_array();
            $main_activity_id = $sub_activity['parent_activity_id'] ?? null;
            $entity_name = $sub_activity['name'] ?? 'Unknown Sub Activity';
            $entity_display_type = 'Sub Activity';
            break;
        case 'followup_activity':
            $this->db->select('parent_activity_id, name');
            $this->db->where('id', $entity_id);
            $follow_up = $this->db->get('follow_up_activities')->row_array();
            $main_activity_id = $follow_up['parent_activity_id'] ?? null;
            $entity_name = $follow_up['name'] ?? 'Unknown Follow Up Activity';
            $entity_display_type = 'Follow Up Activity';
            break;
        case 'outputs':
            $this->db->select('id, name');
            $this->db->where('id', $entity_id);
            $activity = $this->db->get('activities')->row_array();
            $main_activity_id = $activity['id'] ?? null;
            $entity_name = $activity['name'] ?? 'Outputs';
            $entity_display_type = 'Outputs of Activity';
            break;
        case 'activity_product':
            $this->db->select('activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('products')->row_array();
            if ($product) {
                $main_activity_id = $product['activity_id'] ?? null;
                $entity_name = $product['name'] ?? 'Unknown Activity Product';
                $entity_display_type = 'Activity Product';
            }
            break;
        case 'activity_output_product':
            $this->db->select('activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('products')->row_array();
            if ($product) {
                $main_activity_id = $product['activity_id'] ?? null;
                $entity_name = $product['name'] ?? 'Unknown Activity Output Product';
                $entity_display_type = 'Activity Output Product';
            }
            break;
        case 'sub_activity_product':
            $this->db->select('sub_activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('sub_activity_products')->row_array();
            if ($product) {
                $main_activity_id = $product['sub_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['sub_activity_id'])->get('sub_activities')->row()->parent_activity_id ?? null : null;
                $entity_name = $product['name'] ?? 'Unknown Sub Activity Product';
                $entity_display_type = 'Sub Activity Product';
            }
            break;
        case 'followup_activity_product':
            $this->db->select('follow_up_activity_id, name');
            $this->db->where('id', $entity_id);
            $product = $this->db->get('follow_up_activity_products')->row_array();
            if ($product) {
                $main_activity_id = $product['follow_up_activity_id'] ? $this->db->select('parent_activity_id')->where('id', $product['follow_up_activity_id'])->get('follow_up_activities')->row()->parent_activity_id ?? null : null;
                $entity_name = $product['name'] ?? 'Unknown Follow Up Activity Product';
                $entity_display_type = 'Follow Up Activity Product';
            }
            break;
            
        case 'task':
            $this->db->select('t.task, t.task_date, u.first_name as task_owner, u.email as task_owner_email, u.id as task_owner_id');
            $this->db->from('aim_tasks t');
            $this->db->join('timesheets ts', 't.timesheet_id = ts.id', 'left');
            $this->db->join('users u', 'ts.created_by = u.id', 'left');
            $this->db->where('t.id', $entity_id);
            $task = $this->db->get()->row_array();
            if ($task) {
                $entity_name = $task['task'];
                $entity_display_type = 'Task';
                $task_entity = $task;
            }
            break;
        default:
            $entity_name = "Unknown $entity_type";
            $entity_display_type = ucfirst($entity_type);
            break;
    }

    // Fetch main activity details for link and in-charges
    if ($main_activity_id) {
        $this->db->select('inCharges, o.quarter_id, q.quarter, q.year_id, y.year, p.code as programme_code');
        $this->db->from('activities a');
        $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
        $this->db->join('years y', 'q.year_id = y.id', 'left');
        $this->db->join('programmes p', 'y.programme_id = p.id', 'left');
        $this->db->where('a.id', $main_activity_id);
        $activity_data = $this->db->get()->row_array();
        if ($activity_data) {
            $in_charge_ids = json_decode($activity_data['inCharges'], true) ?: [];
            $programme_code = $activity_data['programme_code'] ?? 'SDLG';
            $quarter = $activity_data['quarter'] ?? 'Q1';
            $year = $activity_data['year'] ?? '2025';
            $entity_link = "$app_link/{$programme_code}/activities/{$quarter}/{$year}/{$main_activity_id}";
        } else {
            $entity_link = $app_link;
        }
    } else {
        $entity_link = $app_link;
    }

    // Define recipient groups
    // In-charges (exclude editor)
    $in_charge_emails = [];
    $in_charge_ids_filtered = [];
    if (!empty($in_charge_ids)) {
        $this->db->select('id, email');
        $this->db->where_in('id', $in_charge_ids);
        $this->db->where('id !=', $user_id); // Exclude editor
        $this->db->where('is_active', 1);
        $in_charge_users = $this->db->get('users')->result_array();
        $in_charge_emails = array_column($in_charge_users, 'email');
        $in_charge_ids_filtered = array_column($in_charge_users, 'id');
    }


         // Task owner (include even if they're the creator)
            $task_owner_email = [];
            $task_owner_id = [];
            if ($entity_type === 'task' && !empty($task_entity['task_owner_email'])) {
                $task_owner_email[] = $task_entity['task_owner_email'];
                $task_owner_id[] = $task_entity['task_owner_id'];
            }

              // Previous commenters on this task
            $previous_commenter_emails = [];
            $previous_commenter_ids = [];
            if ($entity_type === 'task') {
                $this->db->distinct();
                $this->db->select('u.id, u.email');
                $this->db->from('comments c');
                $this->db->join('users u', 'c.created_by = u.id', 'left');
                $this->db->where('c.entity_type', 'task');
                $this->db->where('c.entity_id', $entity_id);
                $this->db->where('c.is_active', 1);
                $this->db->where('u.id !=', $user_id); // Exclude current user
                $this->db->where('u.is_active', 1);
                $previous_commenters = $this->db->get()->result_array();
                $previous_commenter_emails = array_column($previous_commenters, 'email');
                $previous_commenter_ids = array_column($previous_commenters, 'id');
            }
            
            
    // Finance team (only if notify_finance_team is 1)
    $finance_emails = [];
    $finance_user_ids = [];
    if ($notify_finance) {
        $finance_team_map = [
            'arua' => ['topista.oleru@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
            'kampala' => ['nakitende.millen@vngi.org', 'paul.bate@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'],
        ];
        $default_finance_emails = ['paul.bate@vngi.org', 'nakitende.millen@vngi.org', 'sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
        $finance_emails = $default_finance_emails;
        foreach ($finance_team_map as $office_key => $emails) {
            if (stripos($main_office, $office_key) !== false) {
                $finance_emails = $emails;
                break;
            }
        }
        // Exclude editor from finance team
        $this->db->select('id, email');
        $this->db->where_in('email', $finance_emails);
        $this->db->where('id !=', $user_id);
        $finance_users = $this->db->get('users')->row_array();
        $finance_emails = array_column($finance_users, 'email');
        $finance_user_ids = array_column($finance_users, 'id');
    }

    // Admin team (exclude editor)
    $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org']; // Adjust as needed
    $this->db->select('id, email');
    $this->db->where_in('email', $admin_emails);
    $this->db->where('id !=', $user_id); // Exclude editor
    $admin_users = $this->db->get('users')->result_array();
    $admin_emails = array_column($admin_users, 'email');
    $admin_user_ids = array_column($admin_users, 'id');

   
    
         // Combine recipients
            $all_emails = array_unique(array_merge($in_charge_emails, $finance_emails, $admin_emails, $task_owner_email, $previous_commenter_emails));
            $all_user_ids = array_unique(array_merge($in_charge_ids_filtered, $finance_user_ids, $admin_user_ids, $task_owner_id, $previous_commenter_ids));

    if (!empty($all_emails)) {
        // Email template
        $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
            . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
            . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
            . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
            . '</div>';
        $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
            . '&copy; 2025 VNG International | SmartHub<br>'
            . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
            . '</div>';

        $notification_title = 'Comment Updated';
        $notification_message = "A comment on the {$entity_display_type}: \"{$entity_name}\" has been updated by {$editor_name}.";
        $email_subject = 'Comment Updated Notification';
        
        
        if($entity_type ==='task'){
            
             $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                            . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                            . "<tr><td>$header</td></tr>"
                            . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                            . "<h2 style='color: #333; margin: 0 0 20px;'>Comment Updated Notification</h2>"
                            . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
                            . "<p style='margin: 0 0 15px;'><strong>" . htmlspecialchars($editor_name) . "</strong> has updated a comment in the Activity Implementation Matrix on " . htmlspecialchars($task_entity['task_owner']) . "'s Task: <strong>" . htmlspecialchars($entity_name) . "</strong>" . (isset($task_entity['task_date']) ? " scheduled on " . date('l jS F, Y', strtotime($task_entity['task_date'])) : "") . ".</p>"
                            . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
                            . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
                            . "</div>"
                            . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                            . "</td></tr>"
                            . "<tr><td align='center'>$footer</td></tr>"
                            . "</table></body></html>";
                    $email_alt_body = "Dear Team,\n\n" . $editor_name . " has updated a comment in the Activity Implementation Matrix on {$entity_type}: {$entity_name}.\n\nComment: \"$body\"\n\nRegards,\nSmartHub";
            
        }else{
        
        
        $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
            . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
            . "<tr><td>$header</td></tr>"
            . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
            . "<h2 style='color: #333; margin: 0 0 20px;'>Comment Updated Notification</h2>"
            . "<p style='margin: 0 0 15px;'>Dear Team,</p>"
            . "<p style='margin: 0 0 15px;'>A comment on the <strong>" . htmlspecialchars($entity_display_type) . "</strong>: "
            . "<a href='$entity_link' style='color: #00A1E5; text-decoration: underline;'>" . htmlspecialchars($entity_name) . "</a> "
            . "has been updated by <strong>" . htmlspecialchars($editor_name) . "</strong>.</p>"
            . "<div style='background-color: #f8f8f8; border-left: 4px solid #FDB913; padding: 15px; margin: 20px 0; border-radius: 4px;'>"
            . "<p style='color: #333; margin: 0; font-weight: bold;'>Updated Comment:</p>"
            . "<div style='color: #333; line-height: 1.6; margin: 10px 0 0;'>" . $body . "</div>"
            . "</div>"
            . "<p style='margin: 0;'>Please review as necessary.</p>"
            . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
            . "</td></tr>"
            . "<tr><td align='center'>$footer</td></tr>"
            . "</table></body></html>";
        $email_alt_body = "Dear Team,\n\nA comment on the {$entity_display_type}: {$entity_name} ($entity_link) has been updated by {$editor_name}.\n\nUpdated Comment: " . strip_tags($body) . "\n\nPlease review as necessary.\n\nRegards,\nSmartHub";
}
        // Send email
        foreach ($all_emails as $email) {
            $mail->addAddress($email);
            
            
        }
        $mail->Subject = $email_subject;
        $mail->Body = $email_body;
        $mail->AltBody = $email_alt_body;
        if (!$mail->send()) {
            log_message('error', 'Failed to send comment update notification email: ' . $mail->ErrorInfo);
        }
        $mail->clearAddresses();

        // Store in-app notifications
        foreach ($all_user_ids as $user_id_to_notify) {
            $this->db->insert('notifications', [
                'user_id' => $user_id_to_notify,
                'type' => 'COMMENT_UPDATE',
                'title' => $notification_title,
                'message' => $notification_message,
                'link' => $entity_link,
                'is_read' => 0,
                'created_by' => $user_id
            ]);
        }
    }

    $updated_comment = $this->get_comment_details($comment_id);
    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_UPDATED', 'data' => $updated_comment]));
}








    // Delete a comment (soft delete)
    public function delete_comment($comment_id)
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        if ($this->db->get('users')->num_rows() == 0) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $comment_id);
        $this->db->where('is_active', 1);
        $comment = $this->db->get('comments')->row_array();
        if (empty($comment)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'COMMENT_NOT_FOUND']));
        }

        $this->db->trans_start();
        $this->db->where('id', $comment_id);
        $this->db->update('comments', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id
        ]);

        // Decrease comments_count for supported entities
        if ($comment['entity_type'] === 'activity') {
            $table = $comment['is_quarterly'] ? 'activities' : 'year_activities';
            $this->db->set('comments_count', 'comments_count - 1', FALSE);
            $this->db->where('id', $comment['entity_id']);
            $this->db->where('comments_count >', 0);
            $this->db->update($table);
        }

        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'DELETE_FAILED']));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'COMMENT_DELETED']));
    }

    // Helper method to determine the correct table based on entity_type and time_frame
    private function get_entity_table($entity_type, $time_frame)
    {
        $entity_tables = [
            'activity' => ($time_frame === 'quarterly') ? 'activities' : 'year_activities',
            'outputs' =>  ($time_frame === 'quarterly') ? 'outputs' : 'year_activity_outputs',
            'sub_activity' => 'sub_activities',
            'followup_activity' => 'follow_up_activities',
            'sub_activity_followup_activity' => 'sub_activity_follow_up_activities',
            'activity_product' => 'products',
            'activity_output_product' => 'products',
            'sub_activity_product' => 'sub_activity_products',
            'followup_activity_product' => 'follow_up_activity_products',
            'sub_activity_followup_activity_product' => 'sub_activity_follow_up_activity_products', // pending implementation
            'attachment' => 'attachments',
            'sub_activity_attachment' => 'attachments',
            'followup_activity_attachment' => 'attachments',
            'sub_activity_followup_activity_attachment' => 'attachments' ,// pending implementation
            'task' => 'aim_tasks' 
        ];

        return $entity_tables[$entity_type];
    }

    // Helper method to validate entity existence
    private function validate_entity($entity_type, $entity_id, $time_frame = 'quarterly')
    {
        $table = $this->get_entity_table($entity_type, $time_frame);
        $this->db->where('id', $entity_id);
        $this->db->where('is_active', 1);
        return $this->db->get($table)->num_rows() > 0;
    }

    // Helper method to fetch comment details with user info
    private function get_comment_details($comment_id)
    {
        $this->db->select('c.id, c.body, c.created_at, c.updated_at, c.is_quarterly, u.id as user_id, u.first_name, u.last_name, u.image as avatar');
        $this->db->from('comments c');
        $this->db->join('users u', 'u.id = c.created_by', 'left');
        $this->db->where('c.id', $comment_id);
        $this->db->where('c.is_active', 1);
        $comment = $this->db->get()->row_array();

        if ($comment) {
            return [
                'id' => (string)$comment['id'],
                'body' => $comment['body'],
                'created_at' => $comment['created_at'],
                'updated_at' => $comment['updated_at'],
                'time_frame' => $comment['is_quarterly'] ? 'quarterly' : 'yearly', // Return as string
                'user' => [
                    'id' => (string)$comment['user_id'],
                    'first_name' => $comment['first_name'],
                    'last_name' => $comment['last_name'],
                    'avatar' => $comment['avatar'] ? $comment['avatar'] : ''
                ]
            ];
        }
        return null;
    }

    // Helper method to fetch all comments for an entity
    private function get_comments($entity_type, $entity_id, $time_frame = 'quarterly')
    {
       
        $this->db->select('c.id, c.body, c.created_at, c.updated_at, c.is_quarterly, u.id as user_id, u.first_name, u.last_name, u.image as avatar');
        $this->db->from('comments c');
        $this->db->join('users u', 'u.id = c.created_by', 'left');
        $this->db->where('c.entity_type', $entity_type);
        $this->db->where('c.entity_id', $entity_id);
        $this->db->where('c.is_quarterly', ($time_frame === 'quarterly') ? 1 : 0);
        $this->db->where('c.is_active', 1);
        $this->db->order_by('c.created_at', 'DESC'); // Latest first
        $comments = $this->db->get()->result_array();

        return array_map(function ($comment) {
            return [
                'id' => (string)$comment['id'],
                'body' => $comment['body'],
                'created_at' => $comment['created_at'],
                'updated_at' => $comment['updated_at'],
                'time_frame' => $comment['is_quarterly'] ? 'quarterly' : 'yearly',
                'user' => [
                    'id' => (string)$comment['user_id'],
                    'first_name' => $comment['first_name'],
                    'last_name' => $comment['last_name'],
                    'avatar' => $comment['avatar'] ? $comment['avatar'] : ''
                ]
            ];
        }, $comments);
    }

   
 public function add_aim_task()
    {
        $json_data = json_decode(@file_get_contents('php://input'), true);
        $task = $json_data['task'] ?? null;
        $task_date = $json_data['task_date'] ?? null;
        $activity_id = $json_data['activity_id'] ?? null;
        $location = $json_data['location'] ?? null;
        $priority = $json_data['priority'] ?? 'NORMAL';
        $status_update = $json_data['status_update'] ?? null;
        $status = $json_data['status'] ?? 'PENDING';
        $project_code = $json_data['project_code'] ?? null;
        $user_id = $json_data['user_id'] ?? null;

        // Validate required fields
        if (empty($user_id) || empty($task) || empty($task_date)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
        }

        // Validate user exists
        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        // Validate task_date
        $task_date = date('Y-m-d', strtotime($task_date));
        if (!$task_date || $task_date === '1970-01-01') {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TASK_DATE']));
        }

        // Extract month and year from task_date
        $month = date('F', strtotime($task_date));
        $year = date('Y', strtotime($task_date));

        // Validate priority
        if (!in_array($priority, ['NORMAL', 'HIGH'])) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_PRIORITY']));
        }

        // Validate status
        if (!in_array($status, ['PENDING', 'DONE'])) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
        }

        // Validate activity_id if provided
        if ($activity_id !== null) {
            $this->db->where('id', $activity_id);
            $this->db->where('is_active', 1);
            $activity_exists = $this->db->get('activities')->num_rows() > 0;
            if (!$activity_exists) {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_ACTIVITY_ID']));
            }
        }

        // Start transaction
        $this->db->trans_start();

        // Check if timesheet exists for the month/year and user
        $this->db->where('user_id', $user_id);
        $this->db->where('month', $month);
        $this->db->where('year', $year);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();

        if (!$timesheet) {
            // Create new timesheet
            $timesheet_data = [
                'month' => $month,
                'year' => $year,
                'user_id' => $user_id,
                'created_by' => $user_id,
                'total_days_worked' => 0,
                'status' => 'PENDING',
                'updated_by' => $user_id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];
            $this->db->insert('timesheets', $timesheet_data);
            $timesheet_id = $this->db->insert_id();
        } else {
            $timesheet_id = $timesheet['id'];
        }

        // Insert task
        $task_data = [
            'task' => $task,
            'task_date' => $task_date,
            'activity_id' => $activity_id,
            'timesheet_id' => $timesheet_id,
            'location' => $location,
            'priority' => $priority,
            'status_update' => $status_update,
            'is_active' => 1,
            'status' => $status,
            'project_code' => $project_code,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ];
        $insert = $this->db->insert('aim_tasks', $task_data);
        if (!$insert) {
            $this->db->trans_rollback();
            log_message('error', "Failed to insert AIM task: " . $this->db->error()['message']);
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TASK_NOT_CREATED - ' . $this->db->error()['message']]));
        }
        $task_id = $this->db->insert_id();

        // Commit transaction
        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            log_message('error', "Transaction failed: " . $this->db->error()['message']);
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
        }

        // Fetch task details for response
        $task_details = $this->get_aim_task_details($task_id);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(201)
            ->set_output(json_encode(['success' => true, 'message' => 'TASK_CREATED_SUCCESSFULLY', 'data' => $task_details]));
    }

 
  public function edit_aim_task($task_id)
    {
        $json_data = json_decode(@file_get_contents('php://input'), true);
        $task = $json_data['task'] ?? null;
        $task_date = $json_data['task_date'] ?? null;
        $activity_id = $json_data['activity_id'] ?? null;
        $location = $json_data['location'] ?? null;
        $priority = $json_data['priority'] ?? null;
        $status_update = $json_data['status_update'] ?? null;
        $status = $json_data['status'] ?? null;
        $project_code = $json_data['project_code'] ?? null;
        $user_id = $json_data['user_id'] ?? null;

        // Validate required fields
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
        }

        // Validate user exists
        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        // Validate task exists
        $this->db->where('id', $task_id);
        $this->db->where('is_active', 1);
        $existing_task = $this->db->get('aim_tasks')->row_array();
        if (!$existing_task) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TASK_NOT_FOUND']));
        }

        // Prepare update data
        $update_data = [];
        if ($task !== null) $update_data['task'] = $task;
        if ($location !== null) $update_data['location'] = $location;
        if ($status_update !== null) $update_data['status_update'] = $status_update;
        if ($project_code !== null) $update_data['project_code'] = $project_code;
        if ($priority !== null && in_array($priority, ['NORMAL', 'HIGH'])) {
            $update_data['priority'] = $priority;
        }
        if ($status !== null && in_array($status, ['PENDING', 'DONE'])) {
            $update_data['status'] = $status;
        }
        if ($activity_id !== null) {
            if ($activity_id === '') {
                $update_data['activity_id'] = null;
            } else {
                $this->db->where('id', $activity_id);
                $this->db->where('is_active', 1);
                $activity_exists = $this->db->get('activities')->num_rows() > 0;
                if (!$activity_exists) {
                    return $this->output
                        ->set_content_type('application/json')
                        ->set_status_header(400)
                        ->set_output(json_encode(['success' => false, 'message' => 'INVALID_ACTIVITY_ID']));
                }
                $update_data['activity_id'] = $activity_id;
            }
        }

        // Handle task_date change
        $timesheet_id = $existing_task['timesheet_id'];
        $original_task_date = $existing_task['task_date'];
        if ($task_date !== null) {
            $task_date = date('Y-m-d', strtotime($task_date));
            if (!$task_date || $task_date === '1970-01-01') {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TASK_DATE']));
            }
            $update_data['task_date'] = $task_date;

            // Check if month/year changed
            $new_month = date('F', strtotime($task_date));
            $new_year = date('Y', strtotime($task_date));
            $this->db->where('id', $timesheet_id);
            $current_timesheet = $this->db->get('timesheets')->row_array();
            if ($current_timesheet['month'] !== $new_month || $current_timesheet['year'] !== $new_year) {
                // Find or create new timesheet
                $this->db->where('user_id', $user_id);
                $this->db->where('month', $new_month);
                $this->db->where('year', $new_year);
                $this->db->where('is_active', 1);
                $new_timesheet = $this->db->get('timesheets')->row_array();

                if (!$new_timesheet) {
                    $timesheet_data = [
                        'month' => $new_month,
                        'year' => $new_year,
                        'user_id' => $user_id,
                        'created_by' => $user_id,
                        'total_days_worked' => 0,
                        'status' => 'PENDING',
                        'updated_by' => $user_id,
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                    $this->db->insert('timesheets', $timesheet_data);
                    $timesheet_id = $this->db->insert_id();
                } else {
                    $timesheet_id = $new_timesheet['id'];
                }
                $update_data['timesheet_id'] = $timesheet_id;
            }
        }

        if (empty($update_data)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'NO_CHANGES_PROVIDED']));
        }

        $update_data['updated_at'] = date('Y-m-d H:i:s');

        // Start transaction
        $this->db->trans_start();

        // Update task
        $this->db->where('id', $task_id);
        $update = $this->db->update('aim_tasks', $update_data);
        if (!$update) {
            $this->db->trans_rollback();
            log_message('error', "Failed to update AIM task: " . $this->db->error()['message']);
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TASK_NOT_UPDATED - ' . $this->db->error()['message']]));
        }

        // Handle user_days_worked for the effective task date
        $effective_task_date = $task_date ?? $existing_task['task_date'];
        $effective_timesheet_id = $update_data['timesheet_id'] ?? $existing_task['timesheet_id'];

        // Check if any tasks are DONE for the effective date and timesheet
        $this->db->where('timesheet_id', $effective_timesheet_id);
        $this->db->where('task_date', $effective_task_date);
        $this->db->where('status', 'DONE');
        $this->db->where('is_active', 1);
        $has_done_tasks = $this->db->get('aim_tasks')->num_rows() > 0;

        // Check if user_days_worked record exists
        $this->db->where('timesheet_id', $effective_timesheet_id);
        $this->db->where('date', $effective_task_date);
        $this->db->where('is_active', 1);
        $existing_day = $this->db->get('user_days_worked')->row_array();

        if ($has_done_tasks) {
            // If there are DONE tasks, ensure a user_days_worked record with days_worked = 1
            if ($existing_day) {
                if ($existing_day['days_worked'] !== '1') {
                    $this->db->where('id', $existing_day['id']);
                    $update_days = $this->db->update('user_days_worked', [
                        'days_worked' => 1,
                        'updated_at' => date('Y-m-d H:i:s')
                    ]);
                    if (!$update_days) {
                        $this->db->trans_rollback();
                        log_message('error', "Failed to update user_days_worked: " . $this->db->error()['message']);
                        return $this->output
                            ->set_content_type('application/json')
                            ->set_status_header(400)
                            ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
                    }
                }
            } else {
                // Insert new user_days_worked record
                $days_worked_data = [
                    'timesheet_id' => $effective_timesheet_id,
                    'date' => $effective_task_date,
                    'days_worked' => 1,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                    'is_active' => 1
                ];
                $insert_days = $this->db->insert('user_days_worked', $days_worked_data);
                if (!$insert_days) {
                    $this->db->trans_rollback();
                    log_message('error', "Failed to insert user_days_worked: " . $this->db->error()['message']);
                    return $this->output
                        ->set_content_type('application/json')
                        ->set_status_header(400)
                        ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_CREATED - ' . $this->db->error()['message']]));
                }
            }
        } else {
            // If no DONE tasks, set days_worked = 0 if record exists
            if ($existing_day) {
                $this->db->where('id', $existing_day['id']);
                $update_days = $this->db->update('user_days_worked', [
                    'days_worked' => 0,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
                if (!$update_days) {
                    $this->db->trans_rollback();
                    log_message('error', "Failed to update user_days_worked: " . $this->db->error()['message']);
                    return $this->output
                        ->set_content_type('application/json')
                        ->set_status_header(400)
                        ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
                }
            }
            // If no record exists, do nothing (no insert needed)
        }

        // Handle original task date if it changed
        if ($task_date !== null && $task_date !== $original_task_date) {
            // Check if any tasks are DONE for the original date and timesheet
            $this->db->where('timesheet_id', $existing_task['timesheet_id']);
            $this->db->where('task_date', $original_task_date);
            $this->db->where('status', 'DONE');
            $this->db->where('is_active', 1);
            $has_done_tasks_original = $this->db->get('aim_tasks')->num_rows() > 0;

            // Check if user_days_worked record exists for original date
            $this->db->where('timesheet_id', $existing_task['timesheet_id']);
            $this->db->where('date', $original_task_date);
            $this->db->where('is_active', 1);
            $existing_day_original = $this->db->get('user_days_worked')->row_array();

            if ($existing_day_original) {
                if ($has_done_tasks_original) {
                    // Ensure days_worked = 1 if there are still DONE tasks
                    if ($existing_day_original['days_worked'] !== '1') {
                        $this->db->where('id', $existing_day_original['id']);
                        $update_days = $this->db->update('user_days_worked', [
                            'days_worked' => 1,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]);
                        if (!$update_days) {
                            $this->db->trans_rollback();
                            log_message('error', "Failed to update user_days_worked for original date: " . $this->db->error()['message']);
                            return $this->output
                                ->set_content_type('application/json')
                                ->set_status_header(400)
                                ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
                        }
                    }
                } else {
                    // Set days_worked = 0 if no DONE tasks
                    $this->db->where('id', $existing_day_original['id']);
                    $update_days = $this->db->update('user_days_worked', [
                        'days_worked' => 0,
                        'updated_at' => date('Y-m-d H:i:s')
                    ]);
                    if (!$update_days) {
                        $this->db->trans_rollback();
                        log_message('error', "Failed to update user_days_worked for original date: " . $this->db->error()['message']);
                        return $this->output
                            ->set_content_type('application/json')
                            ->set_status_header(400)
                            ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
                    }
                }
            }
        }

        // Commit transaction
        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
        }

        // Fetch updated task details
        $task_details = $this->get_aim_task_details($task_id);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TASK_UPDATED_SUCCESSFULLY', 'data' => $task_details]));
    }
    
    
 public function set_days_worked()
 {
        $json_data = json_decode(@file_get_contents('php://input'), true);
        $user_id = $json_data['user_id'] ?? null;
        $timesheet_id = $json_data['timesheet_id'] ?? null;
        $date = $json_data['date'] ?? null;
        $days_worked = $json_data['days_worked'] ?? null;

        // Validate required fields
        if (empty($user_id) || empty($timesheet_id) || empty($date) || !isset($days_worked)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
        }

        // Validate user exists
        $this->db->where('id', $user_id);
        $this->db->where('is_active', 1);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        // Validate timesheet exists and belongs to the user
        $this->db->where('id', $timesheet_id);
        $this->db->where('user_id', $user_id);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();
        if (!$timesheet) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TIMESHEET_ID']));
        }

        // Validate date
        $date = date('Y-m-d', strtotime($date));
        if (!$date || $date === '1970-01-01') {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_DATE']));
        }

        // Validate days_worked
        if (!is_numeric($days_worked) || $days_worked < 0) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_DAYS_WORKED']));
        }

        // Check for at least one DONE task for the timesheet_id and date
        $this->db->where('timesheet_id', $timesheet_id);
        $this->db->where('task_date', $date);
        $this->db->where('status', 'DONE');
        $this->db->where('is_active', 1);
        $has_done_tasks = $this->db->get('aim_tasks')->num_rows() > 0;
        if (!$has_done_tasks) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'NO_DONE_TASKS']));
        }

        // Start transaction
        $this->db->trans_start();

        // Check if user_days_worked record exists
        $this->db->where('timesheet_id', $timesheet_id);
        $this->db->where('date', $date);
        $this->db->where('is_active', 1);
        $existing_day = $this->db->get('user_days_worked')->row_array();

        if ($existing_day) {
            // Update existing record
            $update_data = [
                'days_worked' => $days_worked,
                'updated_at' => date('Y-m-d H:i:s')
            ];
            $this->db->where('id', $existing_day['id']);
            $update = $this->db->update('user_days_worked', $update_data);
            if (!$update) {
                $this->db->trans_rollback();
                log_message('error', "Failed to update user_days_worked: " . $this->db->error()['message']);
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
            }
        } else {
            // Insert new record
            $insert_data = [
                'timesheet_id' => $timesheet_id,
                'date' => $date,
                'days_worked' => $days_worked,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
                'is_active' => 1
            ];
            $insert = $this->db->insert('user_days_worked', $insert_data);
            if (!$insert) {
                $this->db->trans_rollback();
                log_message('error', "Failed to insert user_days_worked: " . $this->db->error()['message']);
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_CREATED - ' . $this->db->error()['message']]));
            }
        }

        // Commit transaction
        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'DAYS_WORKED_UPDATED_SUCCESSFULLY',
                'data' => [
                    'user_id' => (string)$user_id,
                    'timesheet_id' => (string)$timesheet_id,
                    'date' => $date,
                    'days_worked' => (float)$days_worked
                ]
            ]));
    }
  
    public function populate_user_days_worked()
    {
        // Start transaction
        $this->db->trans_start();

        // Fetch all distinct timesheet_id and task_date combinations with DONE tasks
        $this->db->select('at.timesheet_id, at.task_date');
        $this->db->from('aim_tasks at');
        $this->db->join('timesheets t', 'at.timesheet_id = t.id');
        $this->db->where('at.status', 'DONE');
        $this->db->where('at.is_active', 1);
        $this->db->where('t.is_active', 1);
        $this->db->group_by('at.timesheet_id, at.task_date');
        $done_tasks = $this->db->get()->result_array();

        $inserted = 0;
        $updated = 0;
        $skipped = 0;

        foreach ($done_tasks as $task) {
            $timesheet_id = $task['timesheet_id'];
            $date = $task['task_date'];

            // Check if user_days_worked record exists
            $this->db->where('timesheet_id', $timesheet_id);
            $this->db->where('date', $date);
            $this->db->where('is_active', 1);
            $existing_day = $this->db->get('user_days_worked')->row_array();

            if ($existing_day) {
                // Update only if days_worked is not 1.00
                if ($existing_day['days_worked'] != 1.00) {
                    $update_data = [
                        'days_worked' => 1.00,
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                    $this->db->where('id', $existing_day['id']);
                    $update = $this->db->update('user_days_worked', $update_data);
                    if (!$update) {
                        $this->db->trans_rollback();
                        log_message('error', "Failed to update user_days_worked for timesheet_id: {$timesheet_id}, date: {$date}: " . $this->db->error()['message']);
                        return $this->output
                            ->set_content_type('application/json')
                            ->set_status_header(400)
                            ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_UPDATED - ' . $this->db->error()['message']]));
                    }
                    $updated++;
                } else {
                    $skipped++;
                }
            } else {
                // Insert new user_days_worked record
                $insert_data = [
                    'timesheet_id' => $timesheet_id,
                    'date' => $date,
                    'days_worked' => 1.00,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                    'is_active' => 1
                ];
                $insert = $this->db->insert('user_days_worked', $insert_data);
                if (!$insert) {
                    $this->db->trans_rollback();
                    log_message('error', "Failed to insert user_days_worked for timesheet_id: {$timesheet_id}, date: {$date}: " . $this->db->error()['message']);
                    return $this->output
                        ->set_content_type('application/json')
                        ->set_status_header(400)
                        ->set_output(json_encode(['success' => false, 'message' => 'USER_DAYS_WORKED_NOT_CREATED - ' . $this->db->error()['message']]));
                }
                $inserted++;
            }
        }

        // Commit transaction
        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'USER_DAYS_WORKED_POPULATED_SUCCESSFULLY',
                'data' => [
                    'inserted' => $inserted,
                    'updated' => $updated,
                    'skipped' => $skipped
                ]
            ]));
    }

    
    // AIM Tasks: Get a single task
    public function get_aim_task($task_id)
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $task_details = $this->get_aim_task_details($task_id);
        if (!$task_details) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TASK_NOT_FOUND']));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TASK_RETRIEVED_SUCCESSFULLY', 'data' => $task_details]));
    }

   
    public function get_aim_tasks()
    {
        $user_id = $this->input->get('user_id');
        $from_date = $this->input->get('start_date');
        $to_date = $this->input->get('end_date');

        // Validate user_id
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        // Validate user exists
        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        // Validate from_date if provided
        if (!empty($from_date)) {
            $from_date = date('Y-m-d', strtotime($from_date));
            if (!$from_date || $from_date === '1970-01-01') {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FROM_DATE']));
            }
        }

        // Validate to_date if provided
        if (!empty($to_date)) {
            $to_date = date('Y-m-d', strtotime($to_date));
            if (!$to_date || $to_date === '1970-01-01') {
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TO_DATE']));
            }
        }

        // Ensure from_date is not after to_date if both are provided
        if (!empty($from_date) && !empty($to_date) && strtotime($from_date) > strtotime($to_date)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'FROM_DATE_AFTER_TO_DATE']));
        }

        $this->db->select('at.id, at.task, at.task_date, at.activity_id, at.timesheet_id, at.location, at.priority, at.status_update, at.status, at.project_code, at.created_at, at.updated_at, a.code as activity_code, a.name as activity_name, q.quarter as activity_quarter, udw.days_worked');
        $this->db->from('aim_tasks at');
        $this->db->join('timesheets t', 'at.timesheet_id = t.id', 'left');
        $this->db->join('activities a', 'at.activity_id = a.id', 'left');
        $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
        $this->db->join('user_days_worked udw', 'at.timesheet_id = udw.timesheet_id AND at.task_date = udw.date AND udw.is_active = 1', 'left');
        $this->db->where('at.is_active', 1);
        $this->db->where('t.user_id', $user_id);

        // Apply date range filters if provided
        if (!empty($from_date)) {
            $this->db->where('at.task_date >=', $from_date);
        }
        if (!empty($to_date)) {
            $this->db->where('at.task_date <=', $to_date);
        }

        $this->db->order_by('at.task_date', 'DESC');
        $tasks = $this->db->get()->result_array();

        $tasks_data = array_map(function ($task) {
            return [
                'id' => (string)$task['id'],
                'task' => $task['task'],
                'task_date' => $task['task_date'],
                'activity' => $task['activity_id'] ? [
                    'id' => (string)$task['activity_id'],
                    'code' => $task['activity_code'],
                    'name' => $task['activity_name'],
                    'quarter' => $task['activity_quarter']
                ] : null,
                'timesheet' => $this->get_timesheet_details_($task['timesheet_id']),
                'location' => $task['location'],
                'priority' => $task['priority'],
                'status_update' => $task['status_update'],
                'status' => $task['status'],
                'comments' => $this->get_comments('task', $task['id']),
                'project_code' => $task['project_code'],
                'created_at' => $task['created_at'],
                'updated_at' => $task['updated_at'],
                'days_worked' => $task['days_worked'] !== null ? (float)$task['days_worked'] : 0.0
            ];
        }, $tasks);

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TASKS_RETRIEVED_SUCCESSFULLY', 'data' => $tasks_data]));
    }
//     public function get_users_no_done_tasks()
// {
//     $from_date = $this->input->get('start_date');
//     $to_date = $this->input->get('end_date');

//     // Validate from_date
//     if (empty($from_date)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'MISSING_FROM_DATE']));
//     }
//     $from_date = date('Y-m-d', strtotime($from_date));
//     if (!$from_date || $from_date === '1970-01-01') {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FROM_DATE']));
//     }

//     // Validate to_date
//     if (empty($to_date)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'MISSING_TO_DATE']));
//     }
//     $to_date = date('Y-m-d', strtotime($to_date));
//     if (!$to_date || $to_date === '1970-01-01') {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TO_DATE']));
//     }

//     // Ensure from_date is not after to_date
//     if (strtotime($from_date) > strtotime($to_date)) {
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(400)
//             ->set_output(json_encode(['success' => false, 'message' => 'FROM_DATE_AFTER_TO_DATE']));
//     }

//     // Get all active users
//     $this->db->select('id, first_name,last_name, image, email, country_id, isShortTermExpert, last_login_at,role,main_office,onLeave');
//     $this->db->where('is_active', 1);
//     $this->db->where('country_id', '6');
//     $this->db->where('role NOT LIKE', '%finance%');
//     $this->db->where('role NOT LIKE', '%human%');
//     $users = $this->db->get('users')->result_array();

//     // Initialize response array
//     $response_data = [];
//     $current_date = $from_date;
    
//     // Iterate through each date in the range
//     while (strtotime($current_date) <= strtotime($to_date)) {
//         $response_data[$current_date] = [];
        
//         // Check each user for tasks with status 'DONE' on the current date
//         foreach ($users as $user) {
//             $this->db->select('at.id');
//             $this->db->from('aim_tasks at');
//             $this->db->join('timesheets t', 'at.timesheet_id = t.id', 'left');
//             $this->db->where('at.is_active', 1);
//             $this->db->where('t.user_id', $user['id']);
//             $this->db->where('at.task_date', $current_date);
//             $this->db->where('at.status', 'DONE');
//             $has_done_task = $this->db->get()->num_rows() > 0;

//             // If user has no DONE tasks, add to response
//             if (!$has_done_task) {
//                 $response_data[$current_date][] = [
//                     'user_id' => (string)$user['id'],
//                     'first_name' => $user['first_name'],
//                     'last_name' => $user['last_name'],
//                     'role'=>$user['role'],
//                     'image' => $user['image'],
//                     'email' => $user['email'],
//                     'isShortTermExpert'=>(bool)$user['isShortTermExpert'],
//                     'last_login_at'=>$user['last_login_at'],
//                     'main_office'=>$user['main_office'],
//                     'onLeave'=>(bool)$user['onLeave'],
//                 ];
//             }
//         }
        
//         // Move to next date
//         $current_date = date('Y-m-d', strtotime($current_date . ' +1 day'));
//     }

//     return $this->output
//         ->set_content_type('application/json')
//         ->set_status_header(200)
//         ->set_output(json_encode([
//             'success' => true,
//             'message' => 'USERS_NO_DONE_TASKS_RETRIEVED_SUCCESSFULLY',
//             'data' => $response_data
//         ]));
// }

public function get_users_no_done_tasks()
{
    $from_date = $this->input->get('start_date');
    $to_date = $this->input->get('end_date');

    // Validate from_date
    if (empty($from_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_FROM_DATE']));
    }
    $from_date = date('Y-m-d', strtotime($from_date));
    if (!$from_date || $from_date === '1970-01-01') {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FROM_DATE']));
    }

    // Validate to_date
    if (empty($to_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_TO_DATE']));
    }
    $to_date = date('Y-m-d', strtotime($to_date));
    if (!$to_date || $to_date === '1970-01-01') {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_TO_DATE']));
    }

    // Ensure from_date is not after to_date
    if (strtotime($from_date) > strtotime($to_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'FROM_DATE_AFTER_TO_DATE']));
    }

    // Get all active users
    $this->db->select('id, first_name,last_name, image, email, country_id, isShortTermExpert, last_login_at,role,main_office,onLeave');
    $this->db->where('is_active', 1);
    $this->db->where('country_id', '6');
    $this->db->where('role NOT LIKE', '%finance%');
    $this->db->where('role NOT LIKE', '%human%');
    $users = $this->db->get('users')->result_array();

    // Initialize response array
    $response_data = [];
    $current_date = $from_date;
    
    // Iterate through each date in the range
    while (strtotime($current_date) <= strtotime($to_date)) {
        $response_data[$current_date] = [];
        
        // Check each user for tasks with status 'DONE' on the current date
        foreach ($users as $user) {
            $this->db->select('at.id');
            $this->db->from('aim_tasks at');
            $this->db->join('timesheets t', 'at.timesheet_id = t.id', 'left');
            $this->db->where('at.is_active', 1);
            $this->db->where('t.user_id', $user['id']);
            $this->db->where('at.task_date', $current_date);
            $this->db->where('at.status', 'DONE');
            $has_done_task = $this->db->get()->num_rows() > 0;

            // If user has no DONE tasks, add to response
            if (!$has_done_task) {
                // Get status update for this user on this date
                $this->db->select('hsu.status_update, hsu.created_at, hsu.updated_at, u.first_name as created_by_first_name, u.last_name as created_by_last_name');
                $this->db->from('hr_status_updates hsu');
                $this->db->join('users u', 'hsu.created_by = u.id', 'left');
                $this->db->where('hsu.user_id', $user['id']);
                $this->db->where('hsu.update_date', $current_date);
                $this->db->where('hsu.is_active', 1);
                $status_update_query = $this->db->get();
                $status_update = $status_update_query->row_array();

                $response_data[$current_date][] = [
                    'user_id' => (string)$user['id'],
                    'first_name' => $user['first_name'],
                    'last_name' => $user['last_name'],
                    'role'=>$user['role'],
                    'image' => $user['image'],
                    'email' => $user['email'],
                    'isShortTermExpert'=>(bool)$user['isShortTermExpert'],
                    'last_login_at'=>$user['last_login_at'],
                    'main_office'=>$user['main_office'],
                    'onLeave'=>(bool)$user['onLeave'],
                    'status_update' => $status_update ? [
                        'update_text' => $status_update['status_update'],
                        'created_at' => $status_update['created_at'],
                        'updated_at' => $status_update['updated_at'],
                        'created_by' => $status_update['created_by_first_name'] . ' ' . $status_update['created_by_last_name']
                    ] : null
                ];
            }
        }
        
        // // Move to next date
        $current_date = date('Y-m-d', strtotime($current_date . ' +1 day'));
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode([
            'success' => true,
            'message' => 'USERS_NO_DONE_TASKS_WITH_UPDATES_RETRIEVED_SUCCESSFULLY',
            'data' => $response_data
        ]));
}

public function add_hr_status_update()
{
    // Get POST data
    
     $json_data = json_decode(@file_get_contents('php://input'), true);
    $user_id = $json_data['user_id'];
    $update_date = $json_data['update_date'];
    $status_update = $json_data['status_update'];
    $created_by = $json_data['created_by']; // Assuming user ID is stored in session

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_USER_ID']));
    }

    if (empty($update_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_UPDATE_DATE']));
    }

    if (empty($status_update)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_STATUS_UPDATE']));
    }

    if (empty($created_by)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(401)
            ->set_output(json_encode(['success' => false, 'message' => 'UNAUTHORIZED_USER']));
    }

    // Validate date format
    $update_date = date('Y-m-d', strtotime($update_date));
    if (!$update_date || $update_date === '1970-01-01') {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_UPDATE_DATE']));
    }

    // Check if user exists
    $this->db->where('id', $user_id);
    $this->db->where('is_active', 1);
    $user_exists = $this->db->get('users')->num_rows() > 0;
    
    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(404)
            ->set_output(json_encode(['success' => false, 'message' => 'USER_NOT_FOUND']));
    }

    // Check if status update already exists for this user and date
    $this->db->where('user_id', $user_id);
    $this->db->where('update_date', $update_date);
    $this->db->where('is_active', 1);
    $existing_update = $this->db->get('hr_status_updates')->row_array();

    if ($existing_update) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(409)
            ->set_output(json_encode([
                'success' => false, 
                'message' => 'STATUS_UPDATE_ALREADY_EXISTS',
                'existing_update' => $existing_update
            ]));
    }

    // Prepare data for insertion
    $insert_data = [
        'user_id' => $user_id,
        'update_date' => $update_date,
        'status_update' => trim($status_update),
        'created_by' => $created_by,
        'created_at' => date('Y-m-d H:i:s'),
        'updated_at' => date('Y-m-d H:i:s'),
        'is_active' => 1
    ];

    // Insert the status update
    if ($this->db->insert('hr_status_updates', $insert_data)) {
        $insert_id = $this->db->insert_id();
        
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(201)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'STATUS_UPDATE_ADDED_SUCCESSFULLY',
                'data' => [
                    'id' => $insert_id,
                    'user_id' => $user_id,
                    'update_date' => $update_date,
                    'status_update' => trim($status_update),
                    'created_by' => $created_by,
                    'created_at' => $insert_data['created_at']
                ]
            ]));
    } else {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode(['success' => false, 'message' => 'FAILED_TO_ADD_STATUS_UPDATE']));
    }
}

// ===== FUNCTION TO EDIT STATUS UPDATE =====

public function edit_hr_status_update()
{
    // Get POST data
     $json_data = json_decode(@file_get_contents('php://input'), true);
    $user_id = $json_data['user_id'];
    $update_date = $json_data['update_date'];
    $status_update = $json_data['status_update'];
    $updated_by = $json_data['updated_by']; // Assuming user ID i // Assuming user ID is stored in session

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_USER_ID']));
    }

    if (empty($update_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_UPDATE_DATE']));
    }

    if (empty($status_update)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_STATUS_UPDATE']));
    }

    if (empty($updated_by)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(401)
            ->set_output(json_encode(['success' => false, 'message' => 'UNAUTHORIZED_USER']));
    }

    // Validate date format
    $update_date = date('Y-m-d', strtotime($update_date));
    if (!$update_date || $update_date === '1970-01-01') {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_UPDATE_DATE']));
    }

    // Check if status update exists for this user and date
    $this->db->where('user_id', $user_id);
    $this->db->where('update_date', $update_date);
    $this->db->where('is_active', 1);
    $existing_update = $this->db->get('hr_status_updates')->row_array();

    if (!$existing_update) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(404)
            ->set_output(json_encode(['success' => false, 'message' => 'STATUS_UPDATE_NOT_FOUND']));
    }

    // Prepare data for update
    $update_data = [
        'status_update' => trim($status_update),
        'updated_at' => date('Y-m-d H:i:s')
    ];

    // Update the status update
    $this->db->where('user_id', $user_id);
    $this->db->where('update_date', $update_date);
    $this->db->where('is_active', 1);
    
    if ($this->db->update('hr_status_updates', $update_data)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'STATUS_UPDATE_EDITED_SUCCESSFULLY',
                'data' => [
                    'user_id' => $user_id,
                    'update_date' => $update_date,
                    'status_update' => trim($status_update),
                    'updated_by' => $updated_by,
                    'updated_at' => $update_data['updated_at']
                ]
            ]));
    } else {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode(['success' => false, 'message' => 'FAILED_TO_EDIT_STATUS_UPDATE']));
    }
}

// ===== FUNCTION TO DELETE STATUS UPDATE =====

public function delete_hr_status_update()
{
    // Get POST data
     $json_data = json_decode(@file_get_contents('php://input'), true);
    $user_id = $json_data['user_id'];
    $update_date = $json_data['update_date'];
    
    $deleted_by = $json_data['deleted_by']; // Assuming user ID itored in session

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_USER_ID']));
    }

    if (empty($update_date)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'MISSING_UPDATE_DATE']));
    }

    if (empty($deleted_by)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(401)
            ->set_output(json_encode(['success' => false, 'message' => 'UNAUTHORIZED_USER']));
    }

    // Validate date format
    $update_date = date('Y-m-d', strtotime($update_date));
    if (!$update_date || $update_date === '1970-01-01') {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_UPDATE_DATE']));
    }

    // Check if status update exists for this user and date
    $this->db->where('user_id', $user_id);
    $this->db->where('update_date', $update_date);
    $this->db->where('is_active', 1);
    $existing_update = $this->db->get('hr_status_updates')->row_array();

    if (!$existing_update) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(404)
            ->set_output(json_encode(['success' => false, 'message' => 'STATUS_UPDATE_NOT_FOUND']));
    }

    // Soft delete the status update by setting is_active to 0
    $update_data = [
        'is_active' => 0,
        'updated_at' => date('Y-m-d H:i:s')
    ];

    $this->db->where('user_id', $user_id);
    $this->db->where('update_date', $update_date);
    $this->db->where('is_active', 1);
    
    if ($this->db->update('hr_status_updates', $update_data)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'STATUS_UPDATE_DELETED_SUCCESSFULLY',
                'data' => [
                    'user_id' => $user_id,
                    'update_date' => $update_date,
                    'deleted_by' => $deleted_by,
                    'deleted_at' => $update_data['updated_at']
                ]
            ]));
    } else {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode(['success' => false, 'message' => 'FAILED_TO_DELETE_STATUS_UPDATE']));
    }
}

 
    // Helper: Fetch AIM task details
    private function get_aim_task_details($task_id)
    {
        $this->db->select('at.id, at.task, at.task_date, at.activity_id, at.timesheet_id, at.location, at.priority, at.status_update, at.status, at.project_code, 
        at.created_at, at.updated_at, a.code as activity_code, a.name as activity_name, q.quarter as activity_quarter, t.month, t.year');
        $this->db->from('aim_tasks at');
        $this->db->join('activities a', 'at.activity_id = a.id', 'left');
        $this->db->join('outcomes o', 'a.outcome_id = o.id', 'left');
        $this->db->join('quarters q', 'o.quarter_id = q.id', 'left');
        $this->db->join('timesheets t', 'at.timesheet_id = t.id', 'left');
        $this->db->where('at.id', $task_id);
        $this->db->where('at.is_active', 1);
        $task = $this->db->get()->row_array();

        if ($task) {
            return [
                'id' => (string)$task['id'],
                'task' => $task['task'],
                'task_date' => $task['task_date'],
                'activity' => $task['activity_id'] ? [
                    'id' => (string)$task['activity_id'],
                    'code' => $task['activity_code'],
                    'name' => $task['activity_name'],
                    'quarter' => $task['activity_quarter']
                ] : null,
                'timesheet_id' => (string)$task['timesheet_id'],
                'timesheet_month' => $task['month'],
                'timesheet_year' => (string)$task['year'],
                'location' => $task['location'],
                'priority' => $task['priority'],
                'status_update' => $task['status_update'],
                'status' => $task['status'],
                'project_code' => $task['project_code'],
                'created_at' => $task['created_at'],
                'updated_at' => $task['updated_at']
            ];
        }
        return null;
    }

    // AIM Tasks: Delete a task (soft delete)
    public function delete_aim_task($task_id)
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $task_id);
        $this->db->where('is_active', 1);
        $task = $this->db->get('aim_tasks')->row_array();
        if (!$task) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TASK_NOT_FOUND']));
        }

        $this->db->trans_start();
        $this->db->where('id', $task_id);
        $this->db->update('aim_tasks', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'DELETE_FAILED']));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TASK_DELETED']));
    }

    // Timesheets: Get a single timesheet
    public function get_timesheet($timesheet_id)
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $timesheet_details = $this->get_timesheet_details($timesheet_id);
        if (!$timesheet_details) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_RETRIEVED_SUCCESSFULLY', 'data' => $timesheet_details]));
    }

    // Timesheets: Get all timesheets for a user
    public function get_timesheets()
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->select('id, month, year, user_id, created_by, total_days_worked, status, updated_by, created_at, updated_at');
        $this->db->where('user_id', $user_id);
        $this->db->where('is_active', 1);
        $this->db->order_by('year', 'DESC');
        $this->db->order_by('FIELD(month, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")');
        $timesheets = $this->db->get('timesheets')->result_array();

        $timesheets_data = array_map(function ($timesheet) {
            return [
                'id' => (string)$timesheet['id'],
                'month' => $timesheet['month'],
                'year' => (string)$timesheet['year'],
                'user_id' => (string)$timesheet['user_id'],
                'created_by' => (string)$timesheet['created_by'],
                'total_days_worked' => (int)$timesheet['total_days_worked'],
                'status' => $timesheet['status'],
                'updated_by' => (string)$timesheet['updated_by'],
                'created_at' => $timesheet['created_at'],
                'updated_at' => $timesheet['updated_at'],
                'tasks' => $this->get_tasks_for_timesheet($timesheet['id'])
            ];
        }, $timesheets);

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEETS_RETRIEVED_SUCCESSFULLY', 'data' => $timesheets_data]));
    }
    
     // Timesheets: Get all timesheets for all users
     public function get_all_timesheets()
    {
        $month = $this->input->get('month');
        $year = $this->input->get('year') ?? date('Y'); // Default to current year if not provided

        // Validate month
        if (!empty($month) && !in_array($month, ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_MONTH']));
        }

        // Validate year
        if (!is_numeric($year) || $year < 1900 || $year > 2100) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_YEAR']));
        }

        // Fetch users and their timesheets for the specified month and year
        $this->db->select('u.id as user_id, u.first_name as first_name, u.last_name as last_name, u.esignature as esignature, u.role as role, u.image as avatar, u.annual_contract_days as acd,  u.contract_days_worked_sofar as cdws,  u.isShortTermExpert as isShortTermExpert, t.id as timesheet_id, t.month,
        t.year, t.created_by, t.total_days_worked, t.status, t.updated_by, t.created_at, t.updated_at, t.submitted_at, t.approved_at');
        $this->db->from('users u');
        if(!empty($month)){
        $this->db->join('timesheets t', 'u.id = t.user_id AND t.month = "' . $month . '" AND t.year = "' . $year . '" AND t.is_active = 1', 'left');
        }else{
          $this->db->join('timesheets t', 'u.id = t.user_id AND t.year = "' . $year . '" AND t.is_active = 1', 'left');  
        }
        $this->db->where('u.is_active', 1); // Assuming users have an is_active flag
        $this->db->where('t.status !=', 'PENDING'); // fetches all timesheets whose status is not PENDING
        $this->db->order_by('t.submitted_at', 'DESC'); // order by latest updated timesheet
        $results = $this->db->get()->result_array();

        $timesheets_data = array_map(function ($row) {
            $user = [
                'id' => (string)$row['user_id'],
                'first_name' => $row['first_name'],
                'last_name' => $row['last_name'],
                 'esignature' => $row['esignature'],
                'role' => $row['role'],
                'annual_contract_days' => $row['acd'],
                'contract_days_worked_sofar' => $row['cdws'],
                'avatar' => $row['avatar'],
                'isShortTermExpert' =>(bool) $row['isShortTermExpert'],
            ];

            $timesheet = $row['timesheet_id'] ? [
                'id' => (string)$row['timesheet_id'],
                'month' => $row['month'],
                'year' => (string)$row['year'],
                'user_id' => (string)$row['user_id'],
                'created_by' => (string)$row['created_by'],
                'total_days_worked' => (int)$row['total_days_worked'],
                'status' => $row['status'],
                'updated_by' => (string)$row['updated_by'],
                'created_at' => $row['created_at'],
                'updated_at' => $row['updated_at'],
                'submitted_at' => $row['submitted_at'],
                'approved_at' => $row['approved_at'],
                // 'tasks' => $this->get_tasks_for_timesheet($row['timesheet_id'])
            ] : null;

            return [
                'user' => $user,
                'timesheet' => $timesheet
            ];
        }, $results);

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEETS_RETRIEVED_SUCCESSFULLY', 'data' => $timesheets_data]));
    }

    // Timesheets: Edit timesheet status
    // public function edit_timesheet($timesheet_id)
    // {
    //     $json_data = json_decode(@file_get_contents('php://input'), true);
    //     $status = $json_data['status'] ?? null;
    //     $user_id = $json_data['user_id'] ?? null;

    //     if (empty($user_id) || empty($status)) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
    //     }

    //     $this->db->where('id', $user_id);
    //     $user_exists = $this->db->get('users')->num_rows() > 0;
    //     if (!$user_exists) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
    //     }

    //     if (!in_array($status, ['SUBMITTED', 'APPROVED', 'IN_REVIEW', 'DECLINED'])) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
    //     }

    //     $this->db->where('id', $timesheet_id);
    //     $this->db->where('is_active', 1);
    //     $timesheet = $this->db->get('timesheets')->row_array();
    //     if (!$timesheet) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
    //     }

    //     $this->db->trans_start();
    //     $this->db->where('id', $timesheet_id);
    //     $this->db->update('timesheets', [
    //         'status' => $status,
    //         'updated_by' => $user_id,
    //         'updated_at' => date('Y-m-d H:i:s')
    //     ]);
        
    //       if ($status === 'SUBMITTED') {
    //         $update_data['submitted_at'] = date('Y-m-d H:i:s');
    //     } elseif ($status === 'IN_REVIEW') {
    //         $update_data['reviewed_at'] = date('Y-m-d H:i:s');
    //     } elseif ($status === 'APPROVED') {
    //         $update_data['approved_at'] = date('Y-m-d H:i:s');
    //     }

    //     $this->db->trans_complete();
    //     if ($this->db->trans_status() === FALSE) {
    //         return $this->output
    //             ->set_content_type('application/json')
    //             ->set_status_header(400)
    //             ->set_output(json_encode(['success' => false, 'message' => 'UPDATE_FAILED']));
    //     }

    //     $timesheet_details = $this->get_timesheet_details($timesheet_id);
    //     return $this->output
    //         ->set_content_type('application/json')
    //         ->set_status_header(200)
    //         ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_UPDATED_SUCCESSFULLY', 'data' => $timesheet_details]));
    // }


// without notifications
//   public function edit_timesheet($timesheet_id)
//     {
//         $json_data = json_decode(@file_get_contents('php://input'), true);
//         $status = $json_data['status'] ?? null;
//         $user_id = $json_data['user_id'] ?? null;

//         if (empty($user_id) || empty($status)) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//         }

//         $this->db->where('id', $user_id);
//         $user_exists = $this->db->get('users')->num_rows() > 0;
//         if (!$user_exists) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//         }

//         if (!in_array($status, ['SUBMITTED', 'APPROVED', 'IN_REVIEW', 'DECLINED'])) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//         }

//         $this->db->where('id', $timesheet_id);
//         $this->db->where('is_active', 1);
//         $timesheet = $this->db->get('timesheets')->row_array();
//         if (!$timesheet) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
//         }

//         $this->db->trans_start();

//         $update_data = [
//             'status' => $status,
//             'updated_by' => $user_id,
//             'updated_at' => date('Y-m-d H:i:s')
//         ];

//         // Set timestamp fields based on status
//         if ($status === 'SUBMITTED') {
//             $update_data['submitted_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'IN_REVIEW') {
//             $update_data['reviewed_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'APPROVED') {
//             $update_data['approved_at'] = date('Y-m-d H:i:s');
//         }

//         $this->db->where('id', $timesheet_id);
//         $update = $this->db->update('timesheets', $update_data);
//         if (!$update) {
//             $this->db->trans_rollback();
//             log_message('error', "Failed to update timesheet: " . $this->db->error()['message']);
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'UPDATE_FAILED - ' . $this->db->error()['message']]));
//         }

//         $this->db->trans_complete();
//         if ($this->db->trans_status() === FALSE) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//         }

//         $timesheet_details = $this->get_timesheet_details($timesheet_id);
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_UPDATED_SUCCESSFULLY', 'data' => $timesheet_details]));
//     }

// with notifications

//  public function edit_timesheet($timesheet_id)
// {
//         $json_data = json_decode(@file_get_contents('php://input'), true);
//         $status = $json_data['status'] ?? null;
//         $user_id = $json_data['user_id'] ?? null;

//         if (empty($user_id) || empty($status)) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//         }

//         $this->db->where('id', $user_id);
//         $user_exists = $this->db->get('users')->num_rows() > 0;
//         if (!$user_exists) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//         }

//         if (!in_array($status, ['SUBMITTED', 'APPROVED', 'IN_REVIEW', 'DECLINED'])) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//         }

//         $this->db->where('id', $timesheet_id);
//         $this->db->where('is_active', 1);
//         $timesheet = $this->db->get('timesheets')->row_array();
//         if (!$timesheet) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
//         }

//         $this->db->trans_start();

//         $update_data = [
//             'status' => $status,
//             'updated_by' => $user_id,
//             'updated_at' => date('Y-m-d H:i:s')
//         ];

//         // Set timestamp fields based on status
//         if ($status === 'SUBMITTED') {
//             $update_data['submitted_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'IN_REVIEW') {
//             $update_data['reviewed_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'APPROVED') {
//             $update_data['approved_at'] = date('Y-m-d H:i:s');
//         }

//         $this->db->where('id', $timesheet_id);
//         $update = $this->db->update('timesheets', $update_data);
//         if (!$update) {
//             $this->db->trans_rollback();
//             log_message('error', "Failed to update timesheet: " . $this->db->error()['message']);
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'UPDATE_FAILED - ' . $this->db->error()['message']]));
//         }

//         // Notification logic
//         $send_notifications = in_array($status, ['SUBMITTED', 'APPROVED']) && $timesheet['status'] !== $status;
//         if ($send_notifications) {
//             $this->load->library('phpmailer_lib');
//             $mail = $this->phpmailer_lib->load();

//             // SMTP Configuration
//             $mail->isSMTP();
//             $mail->Host = 'smarthub.ovalspace.co';
//             $mail->SMTPAuth = true;
//             $mail->Username = 'notifications@smarthub.ovalspace.co';
//             $mail->Password = 'wgw6.)O7sCTy';
//             $mail->SMTPSecure = 'ssl';
//             $mail->Port = 465;
//             $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//             $mail->isHTML(true);

//             // Fetch reviewer details
//             $this->db->select('first_name');
//             $this->db->where('id', $user_id);
//             $reviewer = $this->db->get('users')->row_array();
//             $reviewer_name = $reviewer['first_name'] ?? 'Unknown';

//             // Common HTML template components
//             $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//                 . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//                 . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//                 . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//                 . '</div>';

//             $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//                 . '&copy; 2025 VNG International | SmartHub<br>'
//                 . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//                 . '</div>';

//             $timesheet_name = "Timesheet for {$timesheet['month']} {$timesheet['year']}";
//             $timesheet_link = "https://smarthub.ovalspace.co/ug/timesheets/{$timesheet_id}";

//             if ($status === 'SUBMITTED') {
//                 // Admin notification (Racheal and Sam)
//                 $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//                 // $admin_emails = ['kimbowaandrew@gmail.com','andrew@ovalspace.co'];
//                 $this->db->select('id, email');
//                 $this->db->where_in('email', $admin_emails);
//                 $admin_users = $this->db->get('users')->result_array();
//                 $admin_user_ids = array_column($admin_users, 'id');

//                 foreach ($admin_emails as $email) {
//                     $mail->addAddress($email);
//                 }

//                 $notification_type = 'TIMESHEET_STATUS_UPDATE';
//                 $notification_title = 'Timesheet Submitted for Review';
//                 $notification_message = "The timesheet for {$timesheet['month']} {$timesheet['year']} has been submitted by {$reviewer_name} for review.";
//                 $email_subject = 'Timesheet Submitted for Review/Approval';
//                 $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//                     . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//                     . "<tr><td>$header</td></tr>"
//                     . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//                     . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Submitted for Review/Approval</h2>"
//                     . "<p style='margin: 0 0 15px;'>Dear Sam and Racheal,</p>"
//                     . "<p style='margin: 0 0 15px;'>The timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
//                     . "has been submitted by <strong>" . htmlspecialchars($reviewer_name) . "</strong> for review."
//                     . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//                     . "</td></tr>"
//                     . "<tr><td align='center'>$footer</td></tr>"
//                     . "</table></body></html>";
//                 $email_alt_body = "Dear Sam and Racheal,\n\nThe timesheet, \"{$timesheet_name}\", has been submitted by {$reviewer_name} for review.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

//                 // Store notification for each admin
//                 foreach ($admin_user_ids as $admin_user_id) {
//                     $this->db->insert('notifications', [
//                         'user_id' => $admin_user_id,
//                         'type' => $notification_type,
//                         'title' => $notification_title,
//                         'message' => $notification_message,
//                         'link' => $timesheet_link,
//                         'is_read' => 0,
//                         'created_by' => $user_id
//                     ]);
//                 }

//                 // Send email to admins
//                 $mail->Subject = $email_subject;
//                 $mail->Body = $email_body;
//                 $mail->AltBody = $email_alt_body;
//                 if (!$mail->send()) {
//                     log_message('error', 'Failed to send email to admins: ' . $mail->ErrorInfo);
//                 }
//                 $mail->clearAddresses();
//             } elseif ($status === 'APPROVED') {
//                 // Notification to timesheet owner
//                 $this->db->select('id, email, first_name');
//                 $this->db->where('id', $timesheet['user_id']);
//                 $owner = $this->db->get('users')->row_array();
//                 if ($owner) {
//                     $mail->addAddress($owner['email']);
//                     // $mail->addAddress('andrewkimbowa2017@gmail.com');
//                     $owner_name = $owner['first_name'] ?? 'User';

//                     $notification_type = 'TIMESHEET_STATUS_UPDATE';
//                     $notification_title = 'Timesheet Approved';
//                     $notification_message = "Your timesheet for {$timesheet['month']} {$timesheet['year']} has been approved by {$reviewer_name}.";
//                     $email_subject = 'Your Timesheet Has Been Approved';
//                     $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//                         . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//                         . "<tr><td>$header</td></tr>"
//                         . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//                         . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Approved</h2>"
//                         . "<p style='margin: 0 0 15px;'>Dear " . htmlspecialchars($owner_name) . ",</p>"
//                         . "<p style='margin: 0 0 15px;'>Your timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
//                         . "has been approved by <strong>" . htmlspecialchars($reviewer_name) . "</strong>."
                       
//                         . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//                         . "</td></tr>"
//                         . "<tr><td align='center'>$footer</td></tr>"
//                         . "</table></body></html>";
//                     $email_alt_body = "Dear {$owner_name},\n\nYour timesheet, \"{$timesheet_name}\", has been approved by {$reviewer_name}.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

//                     // Store notification for the owner
//                     $this->db->insert('notifications', [
//                         'user_id' => $timesheet['user_id'],
//                         'type' => $notification_type,
//                         'title' => $notification_title,
//                         'message' => $notification_message,
//                         'link' => $timesheet_link,
//                         'is_read' => 0,
//                         'created_by' => $user_id
//                     ]);

//                     // Send email to owner
//                     $mail->Subject = $email_subject;
//                     $mail->Body = $email_body;
//                     $mail->AltBody = $email_alt_body;
//                     if (!$mail->send()) {
//                         log_message('error', 'Failed to send email to timesheet owner: ' . $mail->ErrorInfo);
//                     }
//                     $mail->clearAddresses();
//                 }
//             }
//         }

//         $this->db->trans_complete();
//         if ($this->db->trans_status() === FALSE) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//         }

//         $timesheet_details = $this->get_timesheet_details($timesheet_id);
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_UPDATED_SUCCESSFULLY', 'data' => $timesheet_details]));
//     }
    
    
// with new changes for updating user worked days:

//  public function edit_timesheet($timesheet_id)
// {
    
    
//         $json_data = json_decode(@file_get_contents('php://input'), true);
//         $status = $json_data['status'] ?? null;
//         $user_id = $json_data['user_id'] ?? null;
        
//          $days_remaining_end_of_month = $json_data['days_remaining_end_of_month'] ?? null;
//          $total_days_worked = $json_data['total_days_worked'] ?? null;
//          $total_days_remaining = $json_data['total_days_remaining'] ?? null; //before submitting / approving
         
       
         
//         $user_id = $json_data['user_id'] ?? null;

//         if (empty($user_id) || empty($status)) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
//         }

//         $this->db->where('id', $user_id);
//         $user_exists = $this->db->get('users')->num_rows() > 0;
//         if (!$user_exists) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
//         }

//         if (!in_array($status, ['SUBMITTED', 'APPROVED', 'IN_REVIEW', 'DECLINED'])) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
//         }

//         $this->db->where('id', $timesheet_id);
//         $this->db->where('is_active', 1);
//         $timesheet = $this->db->get('timesheets')->row_array();
//         if (!$timesheet) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
//         }

//         $this->db->trans_start();

//         $update_data = [
//             'status' => $status,
//             'total_days_worked'=> $total_days_worked,
//             'days_remaining_end_of_month'=>$days_remaining_end_of_month,
//             'total_days_remaining'=>$total_days_remaining, // before approving / submitting
//             'updated_by' => $user_id,
//             'updated_at' => date('Y-m-d H:i:s')
//         ];

//         // Set timestamp fields based on status
//         if ($status === 'SUBMITTED') {
//             $update_data['submitted_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'IN_REVIEW') {
//             $update_data['reviewed_at'] = date('Y-m-d H:i:s');
//         } elseif ($status === 'APPROVED') {
//             $update_data['approved_at'] = date('Y-m-d H:i:s');
//         }

//         $this->db->where('id', $timesheet_id);
//         $update = $this->db->update('timesheets', $update_data);
//         if (!$update) {
//             $this->db->trans_rollback();
//             log_message('error', "Failed to update timesheet: " . $this->db->error()['message']);
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'UPDATE_FAILED - ' . $this->db->error()['message']]));
//         }

//         // Notification logic
//         $send_notifications = in_array($status, ['SUBMITTED', 'APPROVED']) && $timesheet['status'] !== $status;
//         if ($send_notifications) {
//             $this->load->library('phpmailer_lib');
//             $mail = $this->phpmailer_lib->load();

//             // SMTP Configuration
//             $mail->isSMTP();
//             $mail->Host = 'smarthub.ovalspace.co';
//             $mail->SMTPAuth = true;
//             $mail->Username = 'notifications@smarthub.ovalspace.co';
//             $mail->Password = 'wgw6.)O7sCTy';
//             $mail->SMTPSecure = 'ssl';
//             $mail->Port = 465;
//             $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
//             $mail->isHTML(true);

//             // Fetch reviewer details
//             $this->db->select('first_name');
//             $this->db->where('id', $user_id);
//             $reviewer = $this->db->get('users')->row_array();
//             $reviewer_name = $reviewer['first_name'] ?? 'Unknown';

//             // Common HTML template components
//             $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
//                 . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
//                 . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
//                 . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
//                 . '</div>';

//             $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
//                 . '&copy; 2025 VNG International | SmartHub<br>'
//                 . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
//                 . '</div>';

//             $timesheet_name = "Timesheet for {$timesheet['month']} {$timesheet['year']}";
//             $timesheet_link = "https://smarthub.ovalspace.co/ug/timesheets/{$timesheet_id}";

//             if ($status === 'SUBMITTED') {
//                 // Admin notification (Racheal and Sam)
//                 $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
//                 // $admin_emails = ['kimbowaandrew@gmail.com','andrew@ovalspace.co'];
//                 $this->db->select('id, email');
//                 $this->db->where_in('email', $admin_emails);
//                 $admin_users = $this->db->get('users')->result_array();
//                 $admin_user_ids = array_column($admin_users, 'id');

//                 foreach ($admin_emails as $email) {
//                     $mail->addAddress($email);
//                 }

//                 $notification_type = 'TIMESHEET_STATUS_UPDATE';
//                 $notification_title = 'Timesheet Submitted for Review';
//                 $notification_message = "The timesheet for {$timesheet['month']} {$timesheet['year']} has been submitted by {$reviewer_name} for review.";
//                 $email_subject = 'Timesheet Submitted for Review/Approval';
//                 $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//                     . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//                     . "<tr><td>$header</td></tr>"
//                     . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//                     . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Submitted for Review/Approval</h2>"
//                     . "<p style='margin: 0 0 15px;'>Dear Sam and Racheal,</p>"
//                     . "<p style='margin: 0 0 15px;'>The timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
//                     . "has been submitted by <strong>" . htmlspecialchars($reviewer_name) . "</strong> for review."
//                     . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//                     . "</td></tr>"
//                     . "<tr><td align='center'>$footer</td></tr>"
//                     . "</table></body></html>";
//                 $email_alt_body = "Dear Sam and Racheal,\n\nThe timesheet, \"{$timesheet_name}\", has been submitted by {$reviewer_name} for review.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

//                 // Store notification for each admin
//                 foreach ($admin_user_ids as $admin_user_id) {
//                     $this->db->insert('notifications', [
//                         'user_id' => $admin_user_id,
//                         'type' => $notification_type,
//                         'title' => $notification_title,
//                         'message' => $notification_message,
//                         'link' => $timesheet_link,
//                         'is_read' => 0,
//                         'created_by' => $user_id
//                     ]);
//                 }

//                 // Send email to admins
//                 $mail->Subject = $email_subject;
//                 $mail->Body = $email_body;
//                 $mail->AltBody = $email_alt_body;
//                 if (!$mail->send()) {
//                     log_message('error', 'Failed to send email to admins: ' . $mail->ErrorInfo);
//                 }
//                 $mail->clearAddresses();
//             } elseif ($status === 'APPROVED') {
//                 // Notification to timesheet owner
//                 $this->db->select('id, email, first_name');
//                 $this->db->where('id', $timesheet['user_id']);
//                 $owner = $this->db->get('users')->row_array();
//                 if ($owner) {
//                     $mail->addAddress($owner['email']);
//                     // $mail->addAddress('andrewkimbowa2017@gmail.com');
//                     $owner_name = $owner['first_name'] ?? 'User';

//                     $notification_type = 'TIMESHEET_STATUS_UPDATE';
//                     $notification_title = 'Timesheet Approved';
//                     $notification_message = "Your timesheet for {$timesheet['month']} {$timesheet['year']} has been approved by {$reviewer_name}.";
//                     $email_subject = 'Your Timesheet Has Been Approved';
//                     $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
//                         . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
//                         . "<tr><td>$header</td></tr>"
//                         . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
//                         . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Approved</h2>"
//                         . "<p style='margin: 0 0 15px;'>Dear " . htmlspecialchars($owner_name) . ",</p>"
//                         . "<p style='margin: 0 0 15px;'>Your timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
//                         . "has been approved by <strong>" . htmlspecialchars($reviewer_name) . "</strong>."
                       
//                         . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
//                         . "</td></tr>"
//                         . "<tr><td align='center'>$footer</td></tr>"
//                         . "</table></body></html>";
//                     $email_alt_body = "Dear {$owner_name},\n\nYour timesheet, \"{$timesheet_name}\", has been approved by {$reviewer_name}.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

//                     // Store notification for the owner
//                     $this->db->insert('notifications', [
//                         'user_id' => $timesheet['user_id'],
//                         'type' => $notification_type,
//                         'title' => $notification_title,
//                         'message' => $notification_message,
//                         'link' => $timesheet_link,
//                         'is_read' => 0,
//                         'created_by' => $user_id
//                     ]);

//                     // Send email to owner
//                     $mail->Subject = $email_subject;
//                     $mail->Body = $email_body;
//                     $mail->AltBody = $email_alt_body;
//                     if (!$mail->send()) {
//                         log_message('error', 'Failed to send email to timesheet owner: ' . $mail->ErrorInfo);
//                     }
//                     $mail->clearAddresses();
//                 }
//             }
//         }
        
//         // also update the contract_days_worked_sofar for the user
//           $this->db->select('contract_days_worked_sofar');
//           $this->db->where('id',$user_id);
//           $user = $this->db->get('users')->row();
          
          
//           $computed_annual_contract_days = $user->contract_days_worked_sofar + $days_remaining_end_of_month;
          
//         if($user->id === $timesheet['user_id'] && $status != 'APPROVED') {
          
//           if($computed_annual_contract_days != $user->annual_contract_days){
//               // only update the contract_days_worked_sofar if the summation is not equal to the annual contract days
//               // when these are equal it means the contract days worked sofar are already updated
//           $udpated_days_worked = $user->contract_days_worked_sofar +  $total_days_worked;
          
//           $this->db->where('id',$user_id);
//           $this->db->set('contract_days_worked_sofar',$udpated_days_worked);
//           $this->db->update('users');
//           }
//           }
        

//         $this->db->trans_complete();
//         if ($this->db->trans_status() === FALSE) {
//             return $this->output
//                 ->set_content_type('application/json')
//                 ->set_status_header(400)
//                 ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
//         }

//         $timesheet_details = $this->get_timesheet_details($timesheet_id);
//         return $this->output
//             ->set_content_type('application/json')
//             ->set_status_header(200)
//             ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_UPDATED_SUCCESSFULLY', 'data' => $timesheet_details]));
//     }
    
    
    public function edit_timesheet($timesheet_id)
{
    
    
        $json_data = json_decode(@file_get_contents('php://input'), true);
        $status = $json_data['status'] ?? null;
        $user_id = $json_data['user_id'] ?? null;
        
         $days_remaining_end_of_month = $json_data['days_remaining_end_of_month'] ?? null;
         $total_days_worked = $json_data['total_days_worked'] ?? null;
         $total_days_remaining = $json_data['total_days_remaining'] ?? null; //before submitting / approving
         
       
         
        $user_id = $json_data['user_id'] ?? null;

        if (empty($user_id) || empty($status)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_INPUT']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        if (!in_array($status, ['SUBMITTED', 'APPROVED', 'IN_REVIEW', 'DECLINED'])) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
        }

        $this->db->where('id', $timesheet_id);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();
        if (!$timesheet) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
        }

        $this->db->trans_start();

        $update_data = [
            'status' => $status,
            'total_days_worked'=> $total_days_worked,
            'days_remaining_end_of_month'=>$total_days_remaining - $total_days_worked,
            'total_days_remaining'=>$total_days_remaining, // before approving / submitting
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ];

        // Set timestamp fields based on status
        if ($status === 'SUBMITTED') {
            $update_data['submitted_at'] = date('Y-m-d H:i:s');
        } elseif ($status === 'IN_REVIEW') {
            $update_data['reviewed_at'] = date('Y-m-d H:i:s');
        } elseif ($status === 'APPROVED') {
            $update_data['approved_at'] = date('Y-m-d H:i:s');
        }

        $this->db->where('id', $timesheet_id);
        $update = $this->db->update('timesheets', $update_data);
        if (!$update) {
            $this->db->trans_rollback();
            log_message('error', "Failed to update timesheet: " . $this->db->error()['message']);
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'UPDATE_FAILED - ' . $this->db->error()['message']]));
        }

        // Notification logic
        $send_notifications = in_array($status, ['SUBMITTED', 'APPROVED']) && $timesheet['status'] !== $status;
        if ($send_notifications) {
            $this->load->library('phpmailer_lib');
            $mail = $this->phpmailer_lib->load();

            // SMTP Configuration
            $mail->isSMTP();
            $mail->Host = 'smarthub.ovalspace.co';
            $mail->SMTPAuth = true;
            $mail->Username = 'notifications@smarthub.ovalspace.co';
            $mail->Password = 'wgw6.)O7sCTy';
            $mail->SMTPSecure = 'ssl';
            $mail->Port = 465;
            $mail->setFrom('notifications@smarthub.ovalspace.co', 'SmartHub Notification');
            $mail->isHTML(true);

            // Fetch reviewer details
            $this->db->select('first_name');
            $this->db->where('id', $user_id);
            $reviewer = $this->db->get('users')->row_array();
            $reviewer_name = $reviewer['first_name'] ?? 'Unknown';

            // Common HTML template components
            $header = '<div style="background-color: #00A1E5; height: 15px; width: 100%;"></div>'
                . '<div style="background-color: #FDB913; height: 5px; width: 100%;"></div>'
                . '<div style="background-color: #ffffff; text-align: center; padding: 10px 0;">'
                . '<img src="https://api.smarthub.ovalspace.co/files/smart-hub.png" style="height: 150px; width: auto;" alt="SmartHub Logo" />'
                . '</div>';

            $footer = '<div style="font-size: 10px; color: #666; text-align: center; padding: 10px; background-color: #ffffff;">'
                . '&copy; 2025 VNG International | SmartHub<br>'
                . '<a href="https://smarthub.ovalspace.co" style="color: #00A1E5; text-decoration: underline;">Visit SmartHub</a>'
                . '</div>';

            $timesheet_name = "Timesheet for {$timesheet['month']} {$timesheet['year']}";
            $timesheet_link = "https://smarthub.ovalspace.co/ug/timesheets/{$timesheet_id}";

            if ($status === 'SUBMITTED') {
                // Admin notification (Racheal and Sam)
                $admin_emails = ['sam.ejibua@vng.nl', 'racheal.atukwase@vngi.org'];
                // $admin_emails = ['kimbowaandrew@gmail.com','andrew@ovalspace.co'];
                $this->db->select('id, email');
                $this->db->where_in('email', $admin_emails);
                $admin_users = $this->db->get('users')->result_array();
                $admin_user_ids = array_column($admin_users, 'id');

                foreach ($admin_emails as $email) {
                    $mail->addAddress($email);
                }

                $notification_type = 'TIMESHEET_STATUS_UPDATE';
                $notification_title = 'Timesheet Submitted for Review';
                $notification_message = "The timesheet for {$timesheet['month']} {$timesheet['year']} has been submitted by {$reviewer_name} for review.";
                $email_subject = 'Timesheet Submitted for Review/Approval';
                $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                    . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                    . "<tr><td>$header</td></tr>"
                    . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                    . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Submitted for Review/Approval</h2>"
                    . "<p style='margin: 0 0 15px;'>Dear Sam and Racheal,</p>"
                    . "<p style='margin: 0 0 15px;'>The timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
                    . "has been submitted by <strong>" . htmlspecialchars($reviewer_name) . "</strong> for review."
                    . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                    . "</td></tr>"
                    . "<tr><td align='center'>$footer</td></tr>"
                    . "</table></body></html>";
                $email_alt_body = "Dear Sam and Racheal,\n\nThe timesheet, \"{$timesheet_name}\", has been submitted by {$reviewer_name} for review.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

                // Store notification for each admin
                foreach ($admin_user_ids as $admin_user_id) {
                    $this->db->insert('notifications', [
                        'user_id' => $admin_user_id,
                        'type' => $notification_type,
                        'title' => $notification_title,
                        'message' => $notification_message,
                        'link' => $timesheet_link,
                        'is_read' => 0,
                        'created_by' => $user_id
                    ]);
                }

                // Send email to admins
                $mail->Subject = $email_subject;
                $mail->Body = $email_body;
                $mail->AltBody = $email_alt_body;
                if (!$mail->send()) {
                    log_message('error', 'Failed to send email to admins: ' . $mail->ErrorInfo);
                }
                $mail->clearAddresses();
            } elseif ($status === 'APPROVED') {
                // Notification to timesheet owner
                $this->db->select('id, email, first_name');
                $this->db->where('id', $timesheet['user_id']);
                $owner = $this->db->get('users')->row_array();
                if ($owner) {
                    $mail->addAddress($owner['email']);
                    // $mail->addAddress('andrewkimbowa2017@gmail.com');
                    $owner_name = $owner['first_name'] ?? 'User';

                    $notification_type = 'TIMESHEET_STATUS_UPDATE';
                    $notification_title = 'Timesheet Approved';
                    $notification_message = "Your timesheet for {$timesheet['month']} {$timesheet['year']} has been approved by {$reviewer_name}.";
                    $email_subject = 'Your Timesheet Has Been Approved';
                    $email_body = "<!DOCTYPE html><html><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;'>"
                        . "<table cellpadding='0' cellspacing='0' border='0' width='100%' style='max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);'>"
                        . "<tr><td>$header</td></tr>"
                        . "<tr><td style='padding: 30px; color: #333; line-height: 1.6;'>"
                        . "<h2 style='color: #333; margin: 0 0 20px;'>Timesheet Approved</h2>"
                        . "<p style='margin: 0 0 15px;'>Dear " . htmlspecialchars($owner_name) . ",</p>"
                        . "<p style='margin: 0 0 15px;'>Your timesheet, \"<strong>" . htmlspecialchars($timesheet_name) . "</strong>\", "
                        . "has been approved by <strong>" . htmlspecialchars($reviewer_name) . "</strong>."
                       
                        . "<p style='margin: 0;'>Regards,<br>SmartHub Team</p>"
                        . "</td></tr>"
                        . "<tr><td align='center'>$footer</td></tr>"
                        . "</table></body></html>";
                    $email_alt_body = "Dear {$owner_name},\n\nYour timesheet, \"{$timesheet_name}\", has been approved by {$reviewer_name}.\n\nView Timesheet: {$timesheet_link}\n\nRegards,\nSmartHub";

                    // Store notification for the owner
                    $this->db->insert('notifications', [
                        'user_id' => $timesheet['user_id'],
                        'type' => $notification_type,
                        'title' => $notification_title,
                        'message' => $notification_message,
                        'link' => $timesheet_link,
                        'is_read' => 0,
                        'created_by' => $user_id
                    ]);

                    // Send email to owner
                    $mail->Subject = $email_subject;
                    $mail->Body = $email_body;
                    $mail->AltBody = $email_alt_body;
                    if (!$mail->send()) {
                        log_message('error', 'Failed to send email to timesheet owner: ' . $mail->ErrorInfo);
                    }
                    $mail->clearAddresses();
                }
            }
        }
        
        // Update contract_days_worked_sofar for the TIMESHEET OWNER on SUBMISSION
        // Simplified workflow: Update days when submitted, approval is just for notifications
        // Always use $timesheet['user_id'] (owner) not $user_id (submitter/approver)
        if ($status === 'SUBMITTED' && $timesheet['status'] !== 'SUBMITTED') {
            // Use the timesheet owner's ID for the update
            $owner_id = $timesheet['user_id'];
            
            // Fetch the timesheet OWNER's current contract days
            $this->db->select('contract_days_worked_sofar, annual_contract_days, first_name, last_name');
            $this->db->where('id', $owner_id);
            $owner = $this->db->get('users')->row();
            
            if ($owner) {
                // Use atomic SQL update to prevent race conditions
                $this->db->where('id', $owner_id);
                $this->db->set('contract_days_worked_sofar', 
                    'contract_days_worked_sofar + ' . floatval($total_days_worked), 
                    FALSE); // FALSE = treat as SQL expression
                $this->db->update('users');
                
                // Log the update for audit trail
                log_message('info', 
                    "Timesheet {$timesheet_id} submitted: Updated contract days for " .
                    "{$owner->first_name} {$owner->last_name} (user_id: {$owner_id}) " .
                    "from {$owner->contract_days_worked_sofar} to " . ($owner->contract_days_worked_sofar + $total_days_worked) . " " .
                    "(+{$total_days_worked} days). Submitted by user_id: {$user_id}."
                );
            } else {
                log_message('error', "Could not find timesheet owner (user_id: {$owner_id}) to update contract days for timesheet {$timesheet_id}");
            }
        }
        

        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']]));
        }

        $timesheet_details = $this->get_timesheet_details($timesheet_id);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_UPDATED_SUCCESSFULLY', 'data' => $timesheet_details]));
    }
    
    


    // Timesheets: Delete a timesheet (soft delete)
    public function delete_timesheet($timesheet_id)
    {
        $user_id = $this->input->get('user_id');
        if (empty($user_id)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $user_id);
        $user_exists = $this->db->get('users')->num_rows() > 0;
        if (!$user_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_ID']));
        }

        $this->db->where('id', $timesheet_id);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();
        if (!$timesheet) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'TIMESHEET_NOT_FOUND']));
        }

        $this->db->trans_start();
        $this->db->where('id', $timesheet_id);
        $this->db->update('timesheets', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        // Soft delete associated tasks
        $this->db->where('timesheet_id', $timesheet_id);
        $this->db->where('is_active', 1);
        $this->db->update('aim_tasks', [
            'is_active' => 0,
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'DELETE_FAILED']));
        }

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode(['success' => true, 'message' => 'TIMESHEET_DELETED']));
    }

    // Helper: Fetch timesheet details
    private function get_timesheet_details($timesheet_id)
    {
        $this->db->select('id, month, year, user_id, created_by, total_days_worked, status, updated_by, created_at, updated_at');
        $this->db->where('id', $timesheet_id);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();

        if ($timesheet) {
            return [
                'id' => (string)$timesheet['id'],
                'month' => $timesheet['month'],
                'year' => (string)$timesheet['year'],
                'user_id' => (string)$timesheet['user_id'],
                'created_by' => (string)$timesheet['created_by'],
                'total_days_worked' => (int)$timesheet['total_days_worked'],
                'status' => $timesheet['status'],
                'updated_by' => (string)$timesheet['updated_by'],
                'created_at' => $timesheet['created_at'],
                'updated_at' => $timesheet['updated_at'],
                'tasks' => $this->get_tasks_for_timesheet($timesheet_id)
            ];
        }
        return null;
    }
    // private function get_timesheet_details_($timesheet_id)
    // {
    //     $this->db->select('id, month, year, user_id, created_by, total_days_worked, status, updated_by, created_at, updated_at, submitted_at, approved_at');
    //     $this->db->where('id', $timesheet_id);
    //     $this->db->where('is_active', 1);
    //     $timesheet = $this->db->get('timesheets')->row_array();

    //     if ($timesheet) {
    //         return [
    //             'id' => (string)$timesheet['id'],
    //             'month' => $timesheet['month'],
    //             'year' => (string)$timesheet['year'],
    //             'user_id' => (string)$timesheet['user_id'],
    //             // 'created_by' => (string)$timesheet['created_by'],
    //             // 'total_days_worked' => (int)$timesheet['total_days_worked'],
    //             'status' => $timesheet['status'],
                
    //             'submitted_at' => $timesheet['submitted_at'],
    //             'updated_at' => $timesheet['updated_at'],
    //             'approved_at' => $timesheet['approved_at'],
    //             // 'tasks' => $this->get_tasks_for_timesheet($timesheet_id)
    //         ];
    //     }
    //     return null;
    // }
    
    private function get_timesheet_details_($timesheet_id)
    {
        $this->db->select('id, month, year, user_id, created_by, total_days_worked, days_remaining_end_of_month, total_days_remaining, status, updated_by, created_at, updated_at, submitted_at, approved_at');
        $this->db->where('id', $timesheet_id);
        $this->db->where('is_active', 1);
        $timesheet = $this->db->get('timesheets')->row_array();
        
        $user = $this->db->get_where('users',array('id'=>$timesheet['user_id']))->row();

        if ($timesheet) {
            return [
                'id' => (string)$timesheet['id'],
                'month' => $timesheet['month'],
                'year' => (string)$timesheet['year'],
                'user_id' => (string)$timesheet['user_id'],
                // 'created_by' => (string)$timesheet['created_by'],
                'total_days_worked' => $timesheet['total_days_worked'],
                'days_remaining_end_of_month' => $timesheet['days_remaining_end_of_month'],
                'total_days_remaining' => $timesheet['total_days_remaining'] ?? $user->annual_contract_days-$user->contract_days_worked_sofar,
                'status' => $timesheet['status'],
                
                'submitted_at' => $timesheet['submitted_at'],
                'updated_at' => $timesheet['updated_at'],
                'approved_at' => $timesheet['approved_at'],
                // 'tasks' => $this->get_tasks_for_timesheet($timesheet_id)
            ];
        }
        return null;
    }

    // Helper: Fetch tasks for a timesheet
    private function get_tasks_for_timesheet($timesheet_id)
    {
        $this->db->select('at.id, at.task, at.task_date, at.activity_id, at.timesheet_id, at.location, at.priority, at.status_update, at.status, at.project_code, at.created_at, at.updated_at, a.name as activity_name');
        $this->db->from('aim_tasks at');
        $this->db->join('activities a', 'at.activity_id = a.id', 'left');
        $this->db->where('at.timesheet_id', $timesheet_id);
        $this->db->where('at.is_active', 1);
        $this->db->where('at.status', 'DONE');
        $this->db->order_by('at.task_date', 'ASC');
        $tasks = $this->db->get()->result_array();

        return array_map(function ($task) {
            return [
                'id' => (string)$task['id'],
                'task' => $task['task'],
                'task_date' => $task['task_date'],
                'activity_id' => $task['activity_id'] ? (string)$task['activity_id'] : null,
                'activity_name' => $task['activity_name'] ?? null,
                'timesheet_id' => (string)$task['timesheet_id'],
                'location' => $task['location'],
                'priority' => $task['priority'],
                'status_update' => $task['status_update'],
                'status' => $task['status'],
                'project_code' => $task['project_code'],
                'created_at' => $task['created_at'],
                'updated_at' => $task['updated_at']
            ];
        }, $tasks);
    }


    
    
private function get_pending_activity_products($user_id) {
    $this->db->select('p.id, p.activity_id, p.name, p.type, p.url, p.status, p.isUrgent, p.isRequiredToProceed, p.date_submitted, p.last_updated, p.in_charge_ids, p.prod_type, 
                       a.code, a.name AS activity_name, q.quarter, y.year');
    $this->db->from('products p');
    $this->db->join('activities a', 'p.activity_id = a.id', 'inner');
    $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
    $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
    $this->db->join('years y', 'q.year_id = y.id', 'inner');
    $this->db->where('p.group', 'general');
    $this->db->where('p.isUrgent', $urgency); // Ensure $urgency is defined or passed as a parameter
    $this->db->where('p.is_active', 1);
    $this->db->where_in('p.status', ['Pending']);
    // $this->db->where('p.type !=', 'folder');
    $this->db->where('a.is_active', 1);
    $this->db->where('p.isRequiredToProceed', 1); // Filter for isRequiredToProceed
    // Filter products where user_id is in in_charge_ids JSON array
    $this->db->where("JSON_CONTAINS(p.in_charge_ids, '\"$user_id\"')", NULL, FALSE);
    $products = $this->db->get()->result_array();

    $products_data = [];
    foreach ($products as $product) {
        $product_data = [
            'id' => (string)$product['id'],
            'name' => $product['name'],
            'type' => $product['type'] ?? '',
            'url' => $product['url'] ?? '',
            'inChargeIds' => json_decode($product['in_charge_ids'], true) ?: [], // Return raw in_charge_ids
            'status' => $product['status'] ?? 'Pending',
            'isUrgent' => (bool)$product['isUrgent'] ?? false,
            'isRequiredToProceed' => (bool)$product['isRequiredToProceed'] ?? false,
            'dateSubmitted' => $product['date_submitted'] ?? '',
            'comments' => $this->get_comments('activity_product', $product['id']),
            'lastUpdated' => $product['last_updated'] ?? '',
            'prod_type' => $product['prod_type'] ?? null,
            'activity' => [
                'id' => (string)$product['activity_id'],
                'code' => $product['code'],
                'name' => $product['activity_name'],
                'quarter' => $product['quarter'],
                'year' => $product['year'],
            ]
        ];

        $products_data[] = $product_data;
    }

    return $products_data;
}


private function get_pending_sub_activity_products($user_id) {
    $this->db->select('sp.id, sp.sub_activity_id, sp.name, sp.type, sp.url, sp.status, sp.isUrgent,  sp.date_submitted, sp.last_updated, sp.isRequiredToProceed, sp.in_charge_ids, sp.prod_type, 
                           sa.code AS sub_activity_code, sa.name AS sub_activity_name, 
                           a.id AS activity_id, a.code AS activity_code, a.name AS activity_name, q.quarter, y.year');
        $this->db->from('sub_activity_products sp');
        $this->db->join('sub_activities sa', 'sp.sub_activity_id = sa.id', 'inner');
        $this->db->join('activities a', 'sa.parent_activity_id = a.id', 'inner');
    $this->db->join('outcomes o', 'a.outcome_id = o.id', 'inner');
    $this->db->join('quarters q', 'o.quarter_id = q.id', 'inner');
    $this->db->join('years y', 'q.year_id = y.id', 'inner');
    $this->db->where('sp.group', 'general');
   
    $this->db->where('sp.is_active', 1);
    $this->db->where_in('sp.status', 'Pending');
    $this->db->where('a.is_active', 1);
    $this->db->where('sp.isRequiredToProceed', 1); // Filter for isRequiredToProceed
    // Filter products where user_id is in in_charge_ids JSON array
    $this->db->where("JSON_CONTAINS(sp.in_charge_ids, $user_id)", NULL, FALSE);
    $sub_products = $this->db->get()->result_array();

    $sub_products_data = [];
    foreach ($sub_products as $sub_product) {
        $sub_product_data = [
            'id' => (string)$sub_product['id'],
            'name' => $sub_product['name'],
            'type' => $sub_product['type'] ?? '',
            'url' => $sub_product['url'] ?? '',
            'status' => $sub_product['status'] ?? 'Pending',
            'isUrgent' => (bool)$sub_product['isUrgent'] ?? false,
            'isRequiredToProceed' => (bool)$sub_product['isRequiredToProceed'] ?? false,
            'dateSubmitted' => $sub_product['date_submitted'] ?? '',
            'comments' => $this->get_comments('sub_activity_product', $sub_product['id']),
            'lastUpdated' => $sub_product['last_updated'] ?? '',
            'prod_type' => $sub_product['prod_type'] ?? null,
            'activity' => [
                'id' => (string)$sub_product['activity_id'],
                'code' => $sub_product['activity_code'],
                'name' => $sub_product['activity_name'],
                'quarter' => $sub_product['quarter'],
                'year' => $sub_product['year'],
            ]
        ];

        $sub_products_data[] = $sub_product_data;
    }

    return $sub_products_data;
}



public function get_pending_products(){
    
    $user_id = $this->input->get('user_id');
    
    return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200)
            ->set_output(json_encode([
                'success' => true,
                'message' => 'PRODUCTS_FETCHED_SUCCESSFULLY',
                'data' => [
                    'activity_products' => $this->get_pending_sub_activity_products($user_id),
                    'sub_activity_products' => $this->get_pending_sub_activity_products($user_id)
                    
                ]
            ]));
}


// progress markers

public function add_progress_marker()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $level = $json_data['level'];
    $country_specific_indicators = $json_data['country_specific_indicators'];
    $annual_progress_markers = $json_data['annual_progress_markers'];
    $year = $json_data['year'] ?? '2025';
    $thematic_basket_indicators = $json_data['thematic_basket_indicators'];
    $status = $json_data['status'] ?? 'Not Started';
    $planned = $json_data['planned'] ?? 0;
    $achieved = $json_data['achieved'] ?? 0;
    $user_id = $json_data['user_id'];

    // Validate required fields
    if (empty($user_id) || empty($level) || empty($country_specific_indicators) || empty($thematic_basket_indicators)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_INPUT'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate status
    if (!in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_STATUS'
            )));
    }

    // Validate year format (4 digits)
    if (!preg_match('/^\d{4}$/', $year)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR_FORMAT'
            )));
    }

    // Validate planned and achieved are non-negative integers
    $planned = intval($planned);
    $achieved = intval($achieved);
    
    if ($planned < 0 || $achieved < 0) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PROGRESS_VALUES'
            )));
    }

    // Validate achieved doesn't exceed planned
    if ($achieved > $planned) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACHIEVED_EXCEEDS_PLANNED'
            )));
    }

    // Check if progress marker with same level and year already exists
    $this->db->where('level', $level);
    $this->db->where('year', $year);
    $existing_marker = $this->db->get('progress_markers')->row_array();

    if (!empty($existing_marker)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_EXISTS'
            )));
    }

    // Auto-adjust status based on achievement if not explicitly set to a specific status
    if ($json_data['status'] === null || !isset($json_data['status'])) {
        if ($achieved === 0) {
            $status = 'Not Started';
        } elseif ($achieved >= $planned && $planned > 0) {
            $status = 'Finalised';
        } else {
            $status = 'In Progress';
        }
    }

    // Prepare data for insertion
    $data = [
        'level' => $level,
        'country_specific_indicators' => $country_specific_indicators,
        'annual_progress_markers' => $annual_progress_markers,
        'year' => $year,
        'thematic_basket_indicators' => $thematic_basket_indicators,
        'status' => $status,
        'planned' => $planned,
        'achieved' => $achieved,
        'created_at' => date('Y-m-d H:i:s'),
        'updated_at' => date('Y-m-d H:i:s')
    ];

    // Start a transaction to ensure data consistency
    $this->db->trans_start();

    // Insert the progress marker
    $insert = $this->db->insert('progress_markers', $data);
    if (!$insert) {
        $this->db->trans_rollback();
        log_message('error', "Failed to insert progress marker: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_NOT_CREATED - ' . $this->db->error()['message']
            )));
    }

    $progress_marker_id = $this->db->insert_id();

    // Commit the transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    // Calculate progress percentage
    $progress_percentage = $planned > 0 ? round(($achieved / $planned) * 100, 1) : 0;

    // Prepare response data matching the frontend interface
    $response_data = [
        'id' => (int)$progress_marker_id,
        'level' => $level,
        'countrySpecificIndicators' => $country_specific_indicators,
        'annualProgressMarkers' => $annual_progress_markers,
        'year' => $year,
        'thematicBasketIndicators' => $thematic_basket_indicators,
        'status' => $status,
        'planned' => $planned,
        'achieved' => $achieved,
        'progressPercentage' => $progress_percentage,
        'created_at' => $data['created_at'],
        'updated_at' => $data['updated_at']
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201) // Created
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'PROGRESS_MARKER_CREATED_SUCCESSFULLY',
            'data' => $response_data
        )));
}

public function get_progress_markers()
{
    // Get query parameters
    $user_id = $this->input->get('user_id');
    $year = $this->input->get('year') ?? date('Y'); // Default to current year if not provided

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'USER_ID_REQUIRED'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate year format (4 digits)
    if (!preg_match('/^\d{4}$/', $year)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR_FORMAT'
            )));
    }

    try {
        // Build query
        $this->db->select('*');
        $this->db->from('progress_markers');
        $this->db->where('year', $year);
        $this->db->order_by('id', 'ASC');
        $this->db->order_by('created_at', 'DESC');

        // Execute query
        $query = $this->db->get();
        $progress_markers = $query->result_array();

        // Transform data to match frontend interface
        $formatted_markers = [];
        foreach ($progress_markers as $marker) {
            // Calculate progress percentage
            $progress_percentage = $marker['planned'] > 0 ? round(($marker['achieved'] / $marker['planned']) * 100, 1) : 0;

            $formatted_markers[] = [
                'id' => (int)$marker['id'],
                'level' => $marker['level'],
                'countrySpecificIndicators' => $marker['country_specific_indicators'],
                'annualProgressMarkers' => $marker['annual_progress_markers'],
                'year' => $marker['year'],
                'thematicBasketIndicators' => $marker['thematic_basket_indicators'],
                'status' => $marker['status'],
                'planned' => (int)$marker['planned'],
                'achieved' => (int)$marker['achieved'],
                'cases' => $marker['cases'],
                'progressPercentage' => $progress_percentage,
                'created_at' => $marker['created_at'],
                'updated_at' => $marker['updated_at']
            ];
        }

        // Calculate summary statistics
        $total_markers = count($formatted_markers);
        $completed_markers = count(array_filter($formatted_markers, function($marker) {
            return $marker['status'] === 'Finalised';
        }));
        $in_progress_markers = count(array_filter($formatted_markers, function($marker) {
            return $marker['status'] === 'In Progress';
        }));
        $not_started_markers = count(array_filter($formatted_markers, function($marker) {
            return $marker['status'] === 'Not Started';
        }));

        // Calculate overall progress
        $total_planned = array_sum(array_column($formatted_markers, 'planned'));
        $total_achieved = array_sum(array_column($formatted_markers, 'achieved'));
        $overall_progress = $total_planned > 0 ? round(($total_achieved / $total_planned) * 100, 1) : 0;

        $summary = [
            'totalMarkers' => $total_markers,
            'completedMarkers' => $completed_markers,
            'inProgressMarkers' => $in_progress_markers,
            'notStartedMarkers' => $not_started_markers,
            'totalPlanned' => $total_planned,
            'totalAchieved' => $total_achieved,
            'overallProgress' => $overall_progress,
            'year' => $year
        ];

        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(200) // OK
            ->set_output(json_encode(array(
                'success' => true,
                'message' => 'PROGRESS_MARKERS_RETRIEVED_SUCCESSFULLY',
                'data' => [
                    'markers' => $formatted_markers,
                    'summary' => $summary
                ]
            )));

    } catch (Exception $e) {
        log_message('error', "Failed to retrieve progress markers: " . $e->getMessage());
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500) // Internal Server Error
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'FAILED_TO_RETRIEVE_PROGRESS_MARKERS - ' . $e->getMessage()
            )));
    }
}

public function edit_progress_marker()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $progress_marker_id = $json_data['id'];
    $level = $json_data['level'];
    $country_specific_indicators = $json_data['country_specific_indicators'];
    $annual_progress_markers = $json_data['annual_progress_markers'];
    $year = $json_data['year'];
    $thematic_basket_indicators = $json_data['thematic_basket_indicators'];
    $status = $json_data['status'];
    $planned = $json_data['planned'] ?? 0;
    $achieved = $json_data['achieved'] ?? 0;
    $user_id = $json_data['user_id'];

    // Validate required fields
    if (empty($user_id) || empty($progress_marker_id) || empty($level) || empty($country_specific_indicators) || empty($thematic_basket_indicators)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_INPUT'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate progress marker exists
    $this->db->where('id', $progress_marker_id);
    $existing_marker = $this->db->get('progress_markers')->row_array();

    if (empty($existing_marker)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(404) // Not Found
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_NOT_FOUND'
            )));
    }

    // Validate status
    if (!in_array($status, ['Not Started', 'In Progress', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_STATUS'
            )));
    }

    // Validate year format (4 digits)
    if (!preg_match('/^\d{4}$/', $year)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_YEAR_FORMAT'
            )));
    }

    // Validate planned and achieved are non-negative integers
    $planned = intval($planned);
    $achieved = intval($achieved);
    
    if ($planned < 0 || $achieved < 0) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PROGRESS_VALUES'
            )));
    }

    // Validate achieved doesn't exceed planned
    if ($achieved > $planned) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'ACHIEVED_EXCEEDS_PLANNED'
            )));
    }

    // Check if another progress marker with same level and year already exists (excluding current one)
    $this->db->where('level', $level);
    $this->db->where('year', $year);
    $this->db->where('id !=', $progress_marker_id);
    $duplicate_marker = $this->db->get('progress_markers')->row_array();

    if (!empty($duplicate_marker)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_LEVEL_YEAR_EXISTS'
            )));
    }

    // Auto-adjust status based on achievement if not explicitly set
    if ($json_data['status'] === null || !isset($json_data['status'])) {
        if ($achieved === 0) {
            $status = 'Not Started';
        } elseif ($achieved >= $planned && $planned > 0) {
            $status = 'Finalised';
        } else {
            $status = 'In Progress';
        }
    }

    // Prepare data for update
    $data = [
        'level' => $level,
        'country_specific_indicators' => $country_specific_indicators,
        'annual_progress_markers' => $annual_progress_markers,
        'year' => $year,
        'thematic_basket_indicators' => $thematic_basket_indicators,
        'status' => $status,
        'planned' => $planned,
        'achieved' => $achieved,
        'updated_at' => date('Y-m-d H:i:s')
    ];

    // Start a transaction to ensure data consistency
    $this->db->trans_start();

    // Update the progress marker
    $this->db->where('id', $progress_marker_id);
    $update = $this->db->update('progress_markers', $data);
    
    if (!$update) {
        $this->db->trans_rollback();
        log_message('error', "Failed to update progress marker: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_NOT_UPDATED - ' . $this->db->error()['message']
            )));
    }

    // Commit the transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    // Calculate progress percentage
    $progress_percentage = $planned > 0 ? round(($achieved / $planned) * 100, 1) : 0;

    // Prepare response data matching the frontend interface
    $response_data = [
        'id' => (int)$progress_marker_id,
        'level' => $level,
        'countrySpecificIndicators' => $country_specific_indicators,
        'annualProgressMarkers' => $annual_progress_markers,
        'year' => $year,
        'thematicBasketIndicators' => $thematic_basket_indicators,
        'status' => $status,
        'planned' => $planned,
        'achieved' => $achieved,
        'progressPercentage' => $progress_percentage,
        'created_at' => $existing_marker['created_at'], // Keep original creation date
        'updated_at' => $data['updated_at']
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200) // OK
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'PROGRESS_MARKER_UPDATED_SUCCESSFULLY',
            'data' => $response_data
        )));
}

public function update_progress_marker_cases($id){
    // Validate ID parameter
    if (!$id || !is_numeric($id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'Invalid progress marker ID'
            ]));
    }

    // Parse JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'Invalid JSON input'
            ]));
    }

    // Get cases data
    $cases = isset($json_data['cases']) ? $json_data['cases'] : '';

    try {
        // Check if progress marker exists
        $this->db->where('id', $id);
        $existing_marker = $this->db->get('progress_markers')->row_array();
        
        if (empty($existing_marker)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(404)
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'Progress marker not found'
                ]));
        }

        // Update progress marker cases
        $this->db->where('id', $id);
        $this->db->set([
            'cases' => $cases,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        if ($this->db->update('progress_markers')) {
            // Get updated data for response
            $this->db->where('id', $id);
            $updated_marker = $this->db->get('progress_markers')->row_array();
            
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(200)
                ->set_output(json_encode([
                    'success' => true,
                    'message' => 'Progress marker cases updated successfully',
                    'data' => [
                        'id' => (int)$updated_marker['id'],
                        'cases' => $updated_marker['cases'],
                        'updated_at' => $updated_marker['updated_at']
                    ]
                ]));
        } else {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(500)
                ->set_output(json_encode([
                    'success' => false,
                    'message' => 'Failed to update progress marker cases'
                ]));
        }
    } catch (Exception $e) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(500)
            ->set_output(json_encode([
                'success' => false,
                'message' => 'Database error: ' . $e->getMessage()
            ]));
    }
}

public function delete_progress_marker()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $progress_marker_id = $json_data['id'];
    $user_id = $json_data['user_id'];

    // Validate required fields
    if (empty($user_id) || empty($progress_marker_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_INPUT'
            )));
    }

    // Validate user exists
    $this->db->where('id', $user_id);
    $user_exists = $this->db->get('users')->num_rows() > 0;

    if (!$user_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate progress marker exists
    $this->db->where('id', $progress_marker_id);
    $existing_marker = $this->db->get('progress_markers')->row_array();

    if (empty($existing_marker)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(404) // Not Found
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_NOT_FOUND'
            )));
    }

    // Start a transaction to ensure data consistency
    $this->db->trans_start();

    // Delete the progress marker (hard delete)
    $this->db->where('id', $progress_marker_id);
    $delete = $this->db->delete('progress_markers');
    
    if (!$delete) {
        $this->db->trans_rollback();
        log_message('error', "Failed to delete progress marker: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PROGRESS_MARKER_NOT_DELETED - ' . $this->db->error()['message']
            )));
    }

    // Commit the transaction
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE) {
        log_message('error', "Transaction failed: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200) // OK
        ->set_output(json_encode(array(
            'success' => true,
            'message' => 'PROGRESS_MARKER_DELETED_SUCCESSFULLY',
            'data' => [
                'deleted_id' => (int)$progress_marker_id,
                'deleted_at' => date('Y-m-d H:i:s')
            ]
        )));
}
   
    
   
}