<?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 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'
            )));
    }

    // 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.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'],
                    '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_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();

//     // 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.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
//         $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'],
//                 '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;
//         }

//         $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_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();

//     // Dynamically determine the current month (e.g., "April" on April 04, 2025)
//     $current_month = date('F'); // Full month name, e.g., "April"

//     // 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.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
//         $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., ["April", "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) {
//                 // Only proceed if at least one flag is true
//                 $current_month_in_activity = in_array($current_month, $activity_months);

//                 if ($current_month_in_activity) {
//                     // 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'],
//                 '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' => [],
//                 '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
//         )));
// }

// 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.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
        $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'],
                '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)
{
    $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.activity_id', $activity_id);
    $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',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            '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)
{
    $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
    $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
        ];

        // 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;
}

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');

//     // 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 (if any)
//             $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' => []], // Placeholder
//                     'comments' => [],
//                     'products' => [], // Placeholder
//                     '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' => [],
//                 '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']), // Added months
//                 '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' => [],
//         '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([
//             'success' => true,
//             'message' => 'ACTIVITY_RETRIEVED_SUCCESSFULLY',
//             'data' => $activity_data
//         ]));
// }

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' => [],
                    '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' => [],
                '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_attachments_for_activity($activity_id)
    {
        $this->db->where('activity_id', $activity_id)->where('is_active', 1);
        $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)
{
    $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.sub_activity_id', $sub_activity_id);
    $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',
            'dateSubmitted' => $product['date_submitted'] ?? '',
            '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('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)
{
    $this->db->where('sub_activity_id', $sub_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 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']);
    }, $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)
{
    $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;

    $data = [
        'id' => (string)$attachment['id'],
        'type' => $attachment['type'],
        'title' => $attachment['title'],
        'date' => $attachment['date']
    ];

    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']]));
//         }
//     }

//     // 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]));
// }


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]));
}



// public function edit_year_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'] ?? null;
//     $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);
//     $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) $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 year activity
//     $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)) {
//         $this->db->select('month');
//         $this->db->where('year_activity_id', $id);
//         $this->db->where('is_active', 1);
//         $existing_active_months = $this->db->get('year_activity_months')->result_array();
//         $existing_active_months = array_column($existing_active_months, 'month');

//         $new_months = array_diff($months, $existing_active_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
//                 ];
//             }, $new_months);
//             $this->db->insert_batch('year_activity_months', $month_data);
//         }

//         $months_to_delete = array_diff($existing_active_months, $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]);
//         }
//     }

//     // 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($inCharges_array);
//     $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' => [], // Placeholder
//         '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)
{
    // 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]));
}
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'],
                '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]));
}

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;">'
        . '© 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
        ]));
}


 
    // // Add a comment to any entity
    // 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'];
    //     $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 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']));
    //     }

    //     // Validate entity exists based on entity_type
    //     $valid_entity = $this->validate_entity($entity_type, $entity_id);
    //     if (!$valid_entity) {
    //         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 (database will enforce ENUM constraint)
    //     $data = [
    //         'entity_type' => $entity_type,
    //         'entity_id' => $entity_id,
    //         'body' => $body,
    //         'created_by' => $user_id,
    //         'updated_by' => $user_id,
    //         'is_active' => 1
    //     ];
    //     $this->db->trans_start();
    //     // $this->db->query("SET time_zone = '+03:00'");
    //     $this->db->insert('comments', $data);
    //     $comment_id = $this->db->insert_id();

    //     // Update comments_count for supported entities (e.g., activity)
    //     if ($entity_type === 'activity') {
    //         $this->db->set('comments_count', 'comments_count + 1', FALSE);
    //         $this->db->where('id', $entity_id);
    //         $this->db->update('activities');
    //     } // Add similar logic for other entities with comments_count if needed

    //     $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]));
    // }

    // // Edit a comment
    // 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]));
    // }

    // // 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') {
    //         $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('activities');
    //     } // Add similar logic for other entities if they track comments_count

    //     $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 validate entity existence
    // private function validate_entity($entity_type, $entity_id)
    // {
    //     $entity_tables = [
    //         'activity' => 'activities',
    //         'outputs' => 'activity_outputs', // Adjust if table name differs
    //         'sub_activity' => 'sub_activities', // Adjust if table name differs
    //         'followup_activity' => 'followup_activities', // Adjust if table name differs
    //         'sub_activity_followup_activity' => 'sub_activity_followup_activities', // Adjust if table name differs
    //         'activity_product' => 'products',
    //         'sub_activity_product' => 'sub_activity_products', // Adjust if table name differs
    //         'followup_activity_product' => 'followup_activity_products', // Adjust if table name differs
    //         'sub_activity_followup_activity_product' => 'sub_activity_followup_activity_products', // Adjust if table name differs
    //         'attachment' => 'attachments', // Adjust if table name differs
    //         'sub_activity_attachment' => 'sub_activity_attachments', // Adjust if table name differs
    //         'followup_activity_attachment' => 'followup_activity_attachments', // Adjust if table name differs
    //         'sub_activity_followup_activity_attachment' => 'sub_activity_followup_activity_attachments' // Adjust if table name differs
    //     ];

    //     // Since entity_type is an ENUM, we know it's valid; just check the table
    //     $table = $entity_tables[$entity_type];
    //     $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, 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'],
    //             '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
    // public function get_comments($entity_type, $entity_id)
    // {
      
    //     $this->db->select('c.id, c.body, c.created_at, c.updated_at, 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_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'],
    //             'user' => [
    //                 'id' => (string)$comment['user_id'],
    //                 'first_name' => $comment['first_name'],
    //                 'last_name' => $comment['last_name'],
    //                 'avatar' => $comment['avatar'] ? $comment['avatar'] : ''
    //             ]
    //         ];
    //     }, $comments);
    // }


//incorporating quarterly and yearly: 

// Add a comment to any entity
    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]));
    }

    // Edit a comment
    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]));
    }

    // 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' => 'outputs',
            'sub_activity' => 'sub_activities',
            'followup_activity' => 'follow_up_activities',
            'sub_activity_followup_activity' => 'sub_activity_follow_up_activities',
            'activity_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', // not exisiting
            'attachment' => 'attachments',
            'sub_activity_attachment' => 'attachments',
            'followup_activity_attachment' => 'attachments',
            'sub_activity_followup_activity_attachment' => 'attachments' // not exisiting
        ];

        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);
    }

    
   
}