<?php
defined('BASEPATH') or exit('No direct script access allowed');
class FollowupActivities 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');
    }
    
    /**
 * Create a new follow-up activity.
 * @return JSON response
 */
public function add_follow_up_activity()
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $parent_activity_id = $json_data['parent_activity_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'];
    $inCharges = $json_data['inCharges'] ?? null; // List of user IDs (array or string)
    $user_id = $json_data['user_id'];
    $due_date = $json_data['due_date'];
    
    $months = $json_data['months'] ?? []; // Array of month names
    $team_id = $json_data['team_id'] ?? null; // Optional team ID

    // Validate required fields
    if (empty($user_id) || empty($parent_activity_id) || empty($name)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->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)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

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

    // 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(array(
                'success' => false,
                'message' => 'INVALID_STATUS'
            )));
    }

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

    // Validate team_id if provided
    if ($team_id) {
        $this->db->where('id', $team_id);
        $this->db->where('is_active', 1);
        $team_exists = $this->db->get('teams')->num_rows() > 0;
        if (!$team_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(array(
                    'success' => false,
                    'message' => 'INVALID_TEAM_ID'
                )));
        }
    }

    // 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(array(
                        '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);
    });
    if (empty($months)) {
        $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 = [
        'parent_activity_id' => $parent_activity_id,
        'code' => $code,
        'name' => $name,
        'status' => $status,
         'due_date' => $due_date,
        'location' => $location,
        'team_id' => $team_id,
        '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 follow-up activity
    $insert = $this->db->insert('follow_up_activities', $data);
    if (!$insert) {
        $this->db->trans_rollback();
        log_message('error', "Failed to insert follow-up activity: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'FOLLOW_UP_ACTIVITY_NOT_CREATED - ' . $this->db->error()['message']
            )));
    }

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

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

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

    // 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(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    // Prepare inCharges details for 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);
        $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' => $team_id ? $this->db->where('id', $team_id)->get('teams')->row()->name : 'Follow-Up Activity Team',
        'members' => $inCharges_details
    ];

    $response_data = [
        'id' => (string)$follow_up_activity_id,
        'progress' => '0',
        'name' => $name,
        'code' => $code,
        'months' => $months,
        'team' => $team_response,
        'status' => $status,
        'created_at' => $created_at,
        'location' => $location,
        '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(array(
            'success' => true,
            'message' => 'FOLLOW_UP_ACTIVITY_CREATED_SUCCESSFULLY',
            'data' => $response_data
        )));
}
    
    
    /**
 * Update an existing follow-up activity.
 * @param int $id
 * @return JSON response
 */
public function edit_follow_up_activity($id)
{
    // Get form data from JSON input
    $json_data = json_decode(@file_get_contents('php://input'), true);
    $parent_activity_id = $json_data['parent_activity_id'];
    $name = $json_data['name'];
    $code = $json_data['code'];
    $progress = $json_data['progress'] ?? 0;
    $status = $json_data['status'];
    $location = $json_data['location'];
    $inCharges = $json_data['inCharges'] ?? null;
    $user_id = $json_data['user_id'];
    $months = $json_data['months'] ?? [];
    $team_id = $json_data['team_id'] ?? null;
    $due_date = $json_data['due_date'];

    // Validate required fields
    if (empty($user_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->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)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

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

    // Validate parent activity if provided
    if ($parent_activity_id) {
        $this->db->where('id', $parent_activity_id);
        $this->db->where('is_active', 1);
        $parent_activity = $this->db->get('activities')->row_array();
        if (empty($parent_activity)) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(array(
                    'success' => false,
                    'message' => 'INVALID_PARENT_ACTIVITY'
                )));
        }
    } else {
        $parent_activity_id = $follow_up_activity['parent_activity_id'];
    }

    // Validate status
    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(array(
                'success' => false,
                'message' => 'INVALID_STATUS'
            )));
    }

    // Validate code
    $code = $code !== null ? floatval($code) : $follow_up_activity['code'];

    // Validate progress
    $progress = $progress !== null && is_numeric($progress) ? (string)$progress : $follow_up_activity['progress'];

    // Validate team_id
    if ($team_id) {
        $this->db->where('id', $team_id);
        $this->db->where('is_active', 1);
        $team_exists = $this->db->get('teams')->num_rows() > 0;
        if (!$team_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(array(
                    'success' => false,
                    'message' => 'INVALID_TEAM_ID'
                )));
        }
    }

    // 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(array(
                        'success' => false,
                        'message' => 'INVALID_INCHARGE_IDS'
                    )));
            }
        }
    } else {
        $existing_inCharges = json_decode($follow_up_activity['inCharges'], true) ?: [];
        $inCharges_array = array_filter(array_map('intval', $existing_inCharges));
    }

    // 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('follow_up_activity_id', $id);
        $this->db->where('is_active', 1);
        $existing_months = $this->db->get('follow_up_activity_months')->result_array();
        $months = array_column($existing_months, 'month');
    }

    // Prepare data for update
    $data = [];
    if ($name) $data['name'] = $name;
     if ($due_date) $data['due_date'] = $due_date;
    if ($code !== null) $data['code'] = $code;
    if ($progress !== null) $data['progress'] = $progress;
    if ($status) $data['status'] = $status;
    if ($location) $data['location'] = $location;
    if ($parent_activity_id) $data['parent_activity_id'] = $parent_activity_id;
    if ($team_id !== null) $data['team_id'] = $team_id;
    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 follow-up activity
    $this->db->where('id', $id);
    $update = $this->db->update('follow_up_activities', $data);
    if (!$update) {
        $this->db->trans_rollback();
        log_message('error', "Failed to update follow-up activity: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'FOLLOW_UP_ACTIVITY_NOT_UPDATED - ' . $this->db->error()['message']
            )));
    }

    // Handle follow-up activity months
    if (!empty($months)) {
        $this->db->select('month');
        $this->db->where('follow_up_activity_id', $id);
        $this->db->where('is_active', 1);
        $existing_active_months = $this->db->get('follow_up_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 [
                    'follow_up_activity_id' => $id,
                    'month' => $month,
                    'created_by' => $user_id,
                    'updated_by' => $user_id
                ];
            }, $new_months);
            $this->db->insert_batch('follow_up_activity_months', $month_data);
            if ($this->db->affected_rows() === FALSE) {
                $this->db->trans_rollback();
                log_message('error', "Failed to insert follow-up activity months: " . $this->db->error()['message']);
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(array(
                        'success' => false,
                        'message' => 'FOLLOW_UP_ACTIVITY_MONTHS_NOT_UPDATED - ' . $this->db->error()['message']
                    )));
            }
        }

        $months_to_delete = array_diff($existing_active_months, $months);
        if (!empty($months_to_delete)) {
            $this->db->where('follow_up_activity_id', $id);
            $this->db->where_in('month', $months_to_delete);
            $this->db->set('is_active', 0);
            $this->db->set('deleted_at', date('Y-m-d H:i:s'));
            $this->db->set('updated_by', $user_id);
            $this->db->set('updated_at', date('Y-m-d H:i:s'));
            $this->db->update('follow_up_activity_months');
        }

        $soft_deleted_months = array_intersect($months, array_column($this->db->where('follow_up_activity_id', $id)->where('is_active', 0)->get('follow_up_activity_months')->result_array(), 'month'));
        if (!empty($soft_deleted_months)) {
            $this->db->where('follow_up_activity_id', $id);
            $this->db->where_in('month', $soft_deleted_months);
            $this->db->set('is_active', 1);
            $this->db->set('deleted_at', NULL);
            $this->db->set('updated_by', $user_id);
            $this->db->set('updated_at', date('Y-m-d H:i:s'));
            $this->db->update('follow_up_activity_months');
        }
    } else {
        $this->db->where('follow_up_activity_id', $id);
        $this->db->where('is_active', 1);
        $this->db->set('is_active', 0);
        $this->db->set('deleted_at', date('Y-m-d H:i:s'));
        $this->db->set('updated_by', $user_id);
        $this->db->set('updated_at', date('Y-m-d H:i:s'));
        $this->db->update('follow_up_activity_months');
    }

    // 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(array(
                'success' => false,
                'message' => 'TRANSACTION_FAILED - ' . $this->db->error()['message']
            )));
    }

    // Fetch updated follow-up activity
    $this->db->where('id', $id);
    $updated_follow_up_activity = $this->db->get('follow_up_activities')->row_array();

    $this->db->select('month');
    $this->db->where('follow_up_activity_id', $id);
    $this->db->where('is_active', 1);
    $current_months = $this->db->get('follow_up_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' => $team_id ? $this->db->where('id', $team_id)->get('teams')->row()->name : 'Follow-Up Activity Team',
        'members' => $inCharges_details
    ];

    $response_data = [
        'id' => (string)$updated_follow_up_activity['id'],
        'progress' => (string)$updated_follow_up_activity['progress'],
        'name' => $updated_follow_up_activity['name'],
        'code' => floatval($updated_follow_up_activity['code']),
        'months' => $months,
        'due_date'=>$due_date,
        'team' => $team_response,
        'status' => $updated_follow_up_activity['status'],
        'created_at' => $updated_follow_up_activity['created_at'],
        'location' => $updated_follow_up_activity['location'],
        'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []], // Placeholder
        'comments' => [],
        'comments_count' => (string)$updated_follow_up_activity['comments_count'],
        'products' => [], // To be implemented with get_follow_up_activity_products
        'outputProducts' => [], // To be implemented with get_follow_up_activity_output_products
        'attachments' => [] // To be implemented with get_attachments_for_follow_up_activity
    ];

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

/**
 * Get all follow-up activities for a given activity.
 * @return JSON response
 */
public function get_all_follow_up_activities($activity_id)
{
    // Validate user_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(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)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Validate parent activity exists
    $this->db->where('id', $activity_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(array(
                'success' => false,
                'message' => 'ACTIVITY_NOT_FOUND'
            )));
    }

    // Get all follow-up activities
    $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, team_id, inCharges, comments_count, created_by, updated_by, updated_at, is_active, deleted_at');
    $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();

    $response_data = [
        'activity_id' => (string)$activity_id,
        'follow_up_activities' => []
    ];

    foreach ($follow_up_activities as $follow_up_activity) {
        $inCharges_array = json_decode($follow_up_activity['inCharges'], true) ?: [];
        $inCharges_array = array_filter(array_map('intval', $inCharges_array));

        $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' => $follow_up_activity['team_id'] ? $this->db->where('id', $follow_up_activity['team_id'])->get('teams')->row()->name : 'Follow-Up Activity Team',
            'members' => $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']),
            'team' => $team_response,
            'status' => $follow_up_activity['status'],
            'created_at' => $follow_up_activity['created_at'],
            'location' => $follow_up_activity['location'],
            'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []], // Placeholder
            'comments' => [],
            'comments_count' => (string)$follow_up_activity['comments_count'],
            'products' => [], // To be implemented
            'outputProducts' => [], // To be implemented
            'attachments' => [] // To be implemented
        ];
        $response_data['follow_up_activities'][] = $follow_up_activity_data;
    }

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


/**
 * Get details of a single follow-up activity.
 * @param int $id
 * @return JSON response
 */
public function get_follow_up_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(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)
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_USER_ID'
            )));
    }

    // Get the follow-up activity
    $this->db->select('id, parent_activity_id, code, name, progress, status, created_at, location, team_id, inCharges, comments_count, created_by, updated_by, updated_at, is_active, deleted_at');
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $follow_up_activity = $this->db->get('follow_up_activities')->row_array();

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

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

    $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' => $follow_up_activity['team_id'] ? $this->db->where('id', $follow_up_activity['team_id'])->get('teams')->row()->name : 'Follow-Up Activity Team',
        'members' => $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']),
        'team' => $team_response,
        'status' => $follow_up_activity['status'],
        'created_at' => $follow_up_activity['created_at'],
        'location' => $follow_up_activity['location'],
        'outputs' => ['status' => 'Not Started', 'comments' => [], 'planned' => 0, 'achieved' => 0, 'list' => []], // Placeholder
        'comments' => [],
        'comments_count' => (string)$follow_up_activity['comments_count'],
        'products' => [], // To be implemented
        'outputProducts' => [], // To be implemented
        'attachments' => [] // To be implemented
    ];

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

/**
 * Helper function to get months for a follow-up activity
 * @param int $follow_up_activity_id
 * @return array
 */
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);
    $this->db->where('is_active', 1);
    $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;
}

/**
 * Helper function to get outputs for a follow-up activity
 * @param int $follow_up_activity_id
 * @return array
 */
private function get_follow_up_activity_outputs($follow_up_activity_id)
{
    $this->db->select('status, comments, planned, achieved');
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->where('is_active', 1);
    $output = $this->db->get('follow_up_activity_outputs')->row_array();

    if (empty($output)) {
        return [
            'status' => 'Not Started',
            'comments' => [],
            'planned' => 0,
            'achieved' => 0,
            'list' => []
        ];
    }

    $comments = json_decode($output['comments'], true) ?: [];

    return [
        'status' => $output['status'] ?? 'Not Started',
        'comments' => is_array($comments) ? $comments : [],
        'planned' => (int)($output['planned'] ?? 0),
        'achieved' => (int)($output['achieved'] ?? 0),
        'list' => [] // Placeholder for detailed output list if needed
    ];
}

//PRODUCTS

public function create_follow_up_activity_product()
{
    // Get form data
    $follow_up_activity_id = $this->input->post('follow_up_activity_id');
    $name = $this->input->post('name');
    $prod_type = $this->input->post('prod_type');
    $status = $this->input->post('status');
    $date_submitted = $this->input->post('date_submitted');
    $last_updated = $this->input->post('last_updated');
    $in_charge_ids = $this->input->post('in_charge_ids');
    $user_id = $this->input->post('user_id');
    $group = $this->input->post('group') ?? 'general';
    $output_id = $this->input->post('output_id');
     $is_urgent = $this->input->post('isUrgent'); // Optional, defaults to existing value

    // Validate required fields
    if (empty($follow_up_activity_id) || empty($prod_type) || 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 group
    if (!in_array($group, ['general', 'output'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_GROUP']));
    }

    // Validate output_id if group is 'output'
    if ($group === 'output' && empty($output_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'OUTPUT_ID_REQUIRED_FOR_OUTPUT_PRODUCT']));
    }

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

    // Validate prod_type
    $this->db->where('id', $prod_type);
    $product_type = $this->db->get('product_types')->row_array();
    $name = empty($name) ? $product_type['name'] : $name;

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

    // Determine type
    $type = ($product_type['category'] === 'folder') ? 'folder' : 'docx';

    // Parse in_charge_ids
    $in_charge_ids_array = $this->parse_in_charge_ids($in_charge_ids);

    // Prepare data
    $data = [
        'follow_up_activity_id' => $follow_up_activity_id,
        'name' => $name,
        'type' => $type,
        'url' => '',
        'status' => $status ? $status : 'Pending',
        'date_submitted' => $date_submitted ? date('Y-m-d', strtotime($date_submitted)) : date('Y-m-d'),
        'last_updated' => $last_updated ? date('Y-m-d', strtotime($last_updated)) : date('Y-m-d'),
        'in_charge_ids' => !empty($in_charge_ids_array) ? json_encode($in_charge_ids_array) : json_encode([]),
        'created_by' => $user_id,
        'updated_by' => $user_id,
        'prod_type' => $prod_type,
        'group' => $group,
        'output_id' => $group === 'output' ? $output_id : NULL,
        'is_active' => 1,
        'isUrgent'=>$is_urgent
    ];

    // Check file upload and adjust status
    $has_file_upload = !empty($_FILES['file']['name']) || (!empty($_FILES['files']) && !empty($_FILES['files']['name'][0]));
    if ($has_file_upload && (!isset($status) || $status === 'Pending')) {
        $data['status'] = 'Submitted';
    }

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

    // Validate follow_up_activity_id
    $this->db->where('id', $follow_up_activity_id);
    $activity_exists = $this->db->get('follow_up_activities')->num_rows() > 0;
    if (!$activity_exists) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FOLLOW_UP_ACTIVITY_ID']));
    }

    // Validate in_charge_ids
    if (!empty($in_charge_ids_array) && !$this->validate_users_exist($in_charge_ids_array)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_IDS_IN_IN_CHARGE']));
    }

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

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

    // Insert product
    $this->db->insert('follow_up_activity_products', $data);
    $product_id = $this->db->insert_id();

    // Handle file uploads
    $files = [];
    $directory = "follow_up_activity_products";
    if (!file_exists($directory)) {
        mkdir($directory, 0777, true);
    }

    if ($product_type['category'] === 'folder') {
        $result = $this->handle_multiple_file_uploads_for_follow_up_activity($product_id, 'files', $directory, $user_id);
        if ($result['success'] === false) {
            $this->db->trans_rollback();
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => $result['message']]));
        }
        $files = $result['files'];
    } else {
        if (!empty($_FILES['file']['name'])) {
            $result = $this->handle_single_file_upload_for_follow_up_activity('file', $directory);
            if ($result['success'] === false) {
                $this->db->trans_rollback();
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => $result['message']]));
            }
            $data['url'] = $result['file_url'];
            $data['type'] = $result['file_extension'];
            $this->db->where('id', $product_id);
            $this->db->update('follow_up_activity_products', [
                'url' => $data['url'],
                'type' => $data['type'],
                'updated_by' => $user_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }
    }

    // Update follow_up_activity status
    if ($has_file_upload) {
        $this->update_activity_status($follow_up_activity_id, 'follow_up_activities', $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']));
    }

    // Prepare response
    $in_charge_details = $this->get_in_charge_details($in_charge_ids_array);
    $product_files = $this->get_product_files($product_id, $product_type['category']);

    $response_data = [
        'success' => true,
        'message' => 'PRODUCT_ADDED_SUCCESSFULLY',
        'data' => [
            'id' => $product_id,
            'type' => $data['type'],
            'name' => $data['name'],
            'url' => $data['url'],
            'inCharge' => $in_charge_details,
            'status' => $data['status'],
            'dateSubmitted' => $data['date_submitted'],
            'lastUpdated' => $data['last_updated'],
            'group' => $data['group'],
            'output_id' => $data['output_id'],
            'prod_type' => $data['prod_type']
        ]
    ];
    if ($product_type['category'] === 'folder') {
        $response_data['data']['files'] = $product_files;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201)
        ->set_output(json_encode($response_data));
}


public function edit_follow_up_activity_product($id)
{
    // Get form data
    $follow_up_activity_id = $this->input->post('follow_up_activity_id');
    $name = $this->input->post('name');
    $prod_type = $this->input->post('prod_type');
    $status = $this->input->post('status');
    $date_submitted = $this->input->post('date_submitted');
    $last_updated = $this->input->post('last_updated');
    $in_charge_ids = $this->input->post('in_charge_ids');
    $user_id = $this->input->post('user_id');
    $group = $this->input->post('group');
    $output_id = $this->input->post('output_id');

    // 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 product exists
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $product = $this->db->get('follow_up_activity_products')->row_array();
    if (empty($product)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'PRODUCT_NOT_FOUND_OR_ALREADY_DELETED']));
    }

    // Validate prod_type if provided
    $product_type = $this->get_product_type($prod_type ?? $product['prod_type']);
    if (!$product_type) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_PROD_TYPE']));
    }

    // Determine type
    $type = $prod_type && $product_type['category'] === 'folder' ? 'folder' : ($product['type'] ?? 'docx');

    // Parse in_charge_ids
    $in_charge_ids_array = $this->parse_in_charge_ids($in_charge_ids);

    // Prepare data
    $data = [];
    if (isset($follow_up_activity_id)) $data['follow_up_activity_id'] = $follow_up_activity_id;
    if (isset($name)) $data['name'] = $name;
    if (isset($prod_type)) {
        $data['type'] = $type;
        $data['prod_type'] = $prod_type;
    }
    if (isset($status)) $data['status'] = $status;
    if (isset($date_submitted)) $data['date_submitted'] = date('Y-m-d', strtotime($date_submitted));
    if (isset($last_updated)) $data['last_updated'] = date('Y-m-d', strtotime($last_updated));
    if (!empty($in_charge_ids_array)) $data['in_charge_ids'] = json_encode($in_charge_ids_array);
    if (isset($group)) {
        if (!in_array($group, ['general', 'output'])) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_GROUP']));
        }
        $data['group'] = $group;
        $data['output_id'] = ($group === 'output' && isset($output_id)) ? $output_id : NULL;
    }
    if (isset($output_id) && $group === 'output') {
        $this->db->where('id', $output_id);
        $output_exists = $this->db->get('follow_up_activity_outputs')->num_rows() > 0;
        if (!$output_exists) {
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => 'INVALID_OUTPUT_ID']));
        }
        $data['output_id'] = $output_id;
    }
    $data['updated_by'] = $user_id;
    $data['updated_at'] = date('Y-m-d H:i:s');

    // Handle file uploads
    $has_file_upload = !empty($_FILES['file']['name']) || (!empty($_FILES['files']) && !empty($_FILES['files']['name'][0]));
    if ($has_file_upload && (!isset($status) || $status === 'Pending') && $product['status'] === 'Pending') {
        $data['status'] = 'Submitted';
    }

    // Validate status
    if (isset($data['status']) && !in_array($data['status'], ['Pending', 'Submitted', 'In Review', 'Rejected', 'Finalised'])) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_STATUS']));
    }

    // Validate follow_up_activity_id if provided
    if (isset($data['follow_up_activity_id']) && !$this->validate_activity_id($data['follow_up_activity_id'], 'follow_up_activities')) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FOLLOW_UP_ACTIVITY_ID']));
    }

    // Validate in_charge_ids
    if (!empty($in_charge_ids_array) && !$this->validate_users_exist($in_charge_ids_array)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_USER_IDS_IN_IN_CHARGE']));
    }

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

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

    // Handle file uploads
    $files = [];
    $directory = "follow_up_activity_products";
    if (!file_exists($directory)) {
        mkdir($directory, 0777, true);
    }

    if ($product_type['category'] === 'folder') {
        $result = $this->handle_multiple_file_uploads_for_follow_up_activity($id, 'files', $directory, $user_id);
        if ($result['success'] === false) {
            $this->db->trans_rollback();
            return $this->output
                ->set_content_type('application/json')
                ->set_status_header(400)
                ->set_output(json_encode(['success' => false, 'message' => $result['message']]));
        }
        $files = $result['files'];
    } else {
        if (!empty($_FILES['file']['name'])) {
            $result = $this->handle_single_file_upload_for_follow_up_activity('file', $directory);
            if ($result['success'] === false) {
                $this->db->trans_rollback();
                return $this->output
                    ->set_content_type('application/json')
                    ->set_status_header(400)
                    ->set_output(json_encode(['success' => false, 'message' => $result['message']]));
            }
            $data['url'] = $result['file_url'];
            $data['type'] = $result['file_extension'];
        }
    }

    // Update activity status
    $activity_id = $data['follow_up_activity_id'] ?? $product['follow_up_activity_id'];
    if ($has_file_upload) {
        $this->update_activity_status($activity_id, 'follow_up_activities', $user_id);
    }

    // Update product
    $this->db->where('id', $id);
    $this->db->update('follow_up_activity_products', $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']));
    }

    // Prepare response
    $this->db->where('id', $id);
    $updated_product = $this->db->get('follow_up_activity_products')->row_array();
    $in_charge_details = $this->get_in_charge_details(json_decode($updated_product['in_charge_ids'], true));
    $product_files = $this->get_product_files($id, $product_type['category']);

    $response_data = [
        'success' => true,
        'message' => 'PRODUCT_UPDATED_SUCCESSFULLY',
        'data' => [
            'id' => $updated_product['id'],
            'type' => $updated_product['type'],
            'name' => $updated_product['name'],
            'url' => $updated_product['url'],
            'inCharge' => $in_charge_details,
            'status' => $updated_product['status'],
            'dateSubmitted' => $updated_product['date_submitted'],
            'lastUpdated' => $updated_product['last_updated'],
            'group' => $updated_product['group'],
            'output_id' => $updated_product['output_id'],
            'prod_type' => $updated_product['prod_type']
        ]
    ];
    if ($product_type['category'] === 'folder') {
        $response_data['data']['files'] = $product_files;
    }

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode($response_data));
}

public function delete_follow_up_activity_product()
{
    $user_id = $this->input->get('user_id');
    $product_id = $this->input->get('product_id');
    $delete_type = $this->input->get('delete_type') ?? 'soft';

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

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

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

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

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

    if ($delete_type === 'soft') {
        $this->db->where('id', $product_id);
        $this->db->update('follow_up_activity_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')
        ]);
        $this->handle_soft_delete_follow_up_activity_product_files($product_id, $user_id);
    } else {
        $this->handle_hard_delete_follow_up_activity_product($product_id);
    }

    // Commit transaction
    $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' => 'DELETE_FAILED']));
    }

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


public function delete_followup_activity_product()
{
    // 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 product_id from input (required)
    $product_id = $this->input->get('product_id');
    if (empty($product_id) || !is_numeric($product_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'INVALID_PRODUCT_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 product exists and is active
    $this->db->where('id', $product_id);
    $this->db->where('is_active', 1); // Ensure the product is active before deleting
    $product = $this->db->get('products')->row_array();

    if (empty($product)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400) // Bad Request
            ->set_output(json_encode(array(
                'success' => false,
                'message' => 'PRODUCT_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', $product_id);
        $this->db->update('products', $data);

        // Soft delete related product_files
        $this->handle_soft_delete_product_files($product_id, $user_id);
    } else {
        // Perform hard delete: delete product and related product_files
        $this->handle_hard_delete_product($product_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' ? 'PRODUCT_SOFT_DELETED_SUCCESSFULLY' : 'PRODUCT_HARD_DELETED_SUCCESSFULLY'),
            'data' => [
                'product_id' => $product_id,
                'delete_type' => $delete_type
            ]
        )));
}


/// interim functions to delete these files
private function handle_soft_delete_product_files($product_id, $user_id)
{
    $this->db->where('product_id', $product_id);
    $this->db->where('is_active', 1); // Only soft delete active files
    $this->db->update('product_files', [
        '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')
    ]);
}

private function handle_hard_delete_product($product_id)
{
    // Delete related product_files
    $this->db->where('product_id', $product_id);
    $this->db->delete('product_files');

    // Delete the product
    $this->db->where('id', $product_id);
    $this->db->delete('products');
}





private function handle_single_file_upload_for_follow_up_activity($field_name, $directory)
{
    if (empty($_FILES[$field_name]['name'])) {
        return ['success' => true, 'file_url' => '', 'file_extension' => ''];
    }

    $file_name = $_FILES[$field_name]['name'];
    $file_url = $this->upload_file_for_follow_up_activity($file_name, $field_name, $directory);
    if (!$file_url) {
        return ['success' => false, 'message' => 'FILE_UPLOAD_FAILED: ' . $file_name];
    }

    $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
    return ['success' => true, 'file_url' => $file_url, 'file_extension' => $file_extension];
}

private function handle_multiple_file_uploads_for_follow_up_activity($product_id, $field_name, $directory, $user_id)
{
    $files = [];
    if (empty($_FILES[$field_name]) || !is_array($_FILES[$field_name]['name'])) {
        return ['success' => true, 'files' => $files];
    }

    foreach ($_FILES[$field_name]['name'] as $index => $file_name) {
        if (!empty($file_name)) {
            $file_error = $_FILES[$field_name]['error'][$index];
            $file_size = $_FILES[$field_name]['size'][$index];

            if ($file_error === UPLOAD_ERR_OK) {
                $file_url = $this->upload_files_for_follow_up_activity($file_name, $field_name, $directory, $index);
                if ($file_url) {
                    $file_data = [
                        'product_id' => $product_id,
                        'name' => pathinfo($file_name, PATHINFO_FILENAME),
                        'type' => pathinfo($file_name, PATHINFO_EXTENSION),
                        'url' => $file_url,
                        'date' => date('Y-m-d'),
                        'size' => $file_size / 1024 / 1024 . ' MB',
                        'created_by' => $user_id,
                        'updated_by' => $user_id,
                        'is_active' => 1
                    ];
                    $this->db->insert('follow_up_activity_product_files', $file_data);
                    $file_id = $this->db->insert_id();
                    $files[] = array_merge($file_data, ['id' => $file_id]);
                } else {
                    return ['success' => false, 'message' => 'FILE_UPLOAD_FAILED: ' . $file_name];
                }
            } else {
                return ['success' => false, 'message' => 'FILE_UPLOAD_ERROR: ' . $file_name . ' (Error ' . $file_error . ')'];
            }
        }
    }

    return ['success' => true, 'files' => $files];
}

private function upload_file_for_follow_up_activity($file_name, $field_name, $directory)
{
    $config['upload_path'] = "./$directory/";
    $config['allowed_types'] = '*';
    $new_name = time() . '-' . $file_name;
    $config['file_name'] = $new_name;

    $this->load->library('upload', $config);
    $this->upload->initialize($config);

    if (!$this->upload->do_upload($field_name) && !empty($file_name)) {
        log_message('error', 'File upload error: ' . $this->upload->display_errors());
        return false;
    }

    $upload_data = $this->upload->data();
    return base_url() . "$directory/" . $upload_data['file_name'];
}

private function upload_files_for_follow_up_activity($file_name, $field_name, $directory, $index)
{
    $config['upload_path'] = "./$directory/";
    $config['allowed_types'] = '*';
    $new_name = time() . '-' . $file_name;
    $config['file_name'] = $new_name;

    $this->load->library('upload', $config);
    $this->upload->initialize($config);

    $_FILES['userfile']['name'] = $_FILES[$field_name]['name'][$index];
    $_FILES['userfile']['type'] = $_FILES[$field_name]['type'][$index];
    $_FILES['userfile']['tmp_name'] = $_FILES[$field_name]['tmp_name'][$index];
    $_FILES['userfile']['error'] = $_FILES[$field_name]['error'][$index];
    $_FILES['userfile']['size'] = $_FILES[$field_name]['size'][$index];

    if (!$this->upload->do_upload('userfile') && !empty($file_name)) {
        log_message('error', 'File upload error: ' . $this->upload->display_errors());
        return false;
    }

    $upload_data = $this->upload->data();
    return base_url() . "$directory/" . $upload_data['file_name'];
}

private function handle_soft_delete_follow_up_activity_product_files($product_id, $user_id)
{
    $this->db->where('product_id', $product_id);
    $this->db->where('is_active', 1);
    $this->db->update('follow_up_activity_product_files', [
        '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')
    ]);
}

private function handle_hard_delete_follow_up_activity_product($product_id)
{
    $this->db->where('product_id', $product_id);
    $this->db->delete('follow_up_activity_product_files');
    $this->db->where('id', $product_id);
    $this->db->delete('follow_up_activity_products');
}

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);
        $users = $this->db->get('users')->result_array();
        foreach ($users as $user) {
            $details[] = ['id' => $user['id'], 'first_name' => $user['first_name'], 'avatar' => $user['avatar']];
        }
    }
    return $details;
}

private function get_product_files($product_id, $category)
{
    if ($category !== 'folder') return [];
    $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();
    return array_map(function ($file) {
        return [
            'id' => $file['id'],
            'name' => $file['name'],
            'type' => $file['type'],
            'url' => $file['url'],
            'date' => $file['date'],
            'size' => $file['size']
        ];
    }, $files_data);
}

private function get_product_type($prod_type_id)
{
    $this->db->where('id', $prod_type_id);
    return $this->db->get('product_types')->row_array();
}

private function parse_in_charge_ids($in_charge_ids)
{
    $in_charge_ids_array = [];
    if (!empty($in_charge_ids)) {
        $parsed_ids = json_decode($in_charge_ids, true);
        if (is_array($parsed_ids)) {
            $in_charge_ids_array = array_filter(array_map('intval', $parsed_ids));
        } else {
            $ids = explode(',', str_replace(['[', ']', '"'], '', $in_charge_ids));
            $in_charge_ids_array = array_filter(array_map('trim', $ids), 'strlen');
            $in_charge_ids_array = array_map('intval', $in_charge_ids_array);
        }
    }
    return $in_charge_ids_array;
}

private function validate_activity_id($id, $table)
{
    $this->db->where('id', $id);
    return $this->db->get($table)->num_rows() > 0;
}

private function validate_users_exist($user_ids)
{
    $this->db->where_in('id', $user_ids);
    return $this->db->get('users')->num_rows() === count($user_ids);
}

private function update_activity_status($activity_id, $table, $user_id)
{
    $this->db->where('id', $activity_id);
    $activity = $this->db->get($table)->row_array();
    if ($activity && $activity['status'] !== 'Finalised') {
        $this->db->where('id', $activity_id);
        $this->db->update($table, [
            'status' => 'In Progress',
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
    }
}


// OUTPUTS
public function add_follow_up_activity_output()
{
    // Get form data
    $follow_up_activity_id = $this->input->post('follow_up_activity_id');
    $title = $this->input->post('title');
    $status = $this->input->post('status') ?? 'Not Started';
    $planned = $this->input->post('planned') ?? 0;
    $achieved = $this->input->post('achieved') ?? 0;
    $comments = $this->input->post('comments');
    $user_id = $this->input->post('user_id');

    // Validate required fields
    if (empty($follow_up_activity_id) || empty($title) || 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 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 follow_up_activity_id exists and is active
    $this->db->where('id', $follow_up_activity_id);
    $this->db->where('is_active', 1);
    $activity_exists = $this->db->get('follow_up_activities')->num_rows() > 0;

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

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

    // Prepare data for insertion
    $data = [
        'follow_up_activity_id' => $follow_up_activity_id,
        'title' => $title,
        'status' => $status,
        'planned' => (int)$planned,
        'achieved' => (int)$achieved,
        'comments' => $comments,
        'created_by' => $user_id,
        'updated_by' => $user_id,
        'is_active' => 1
    ];

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

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

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

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

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

    $response_data = [
        'success' => true,
        'message' => 'OUTPUT_ADDED_SUCCESSFULLY',
        'data' => [
            'id' => $output_id,
            'follow_up_activity_id' => $follow_up_activity_id,
            'title' => $title,
            'status' => $status,
            'planned' => (int)$planned,
            'achieved' => (int)$achieved,
            'comments' => $comments
        ]
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(201)
        ->set_output(json_encode($response_data));
}

public function edit_follow_up_activity_output($id)
{
    // Get form data
    $follow_up_activity_id = $this->input->post('follow_up_activity_id');
    $title = $this->input->post('title');
    $status = $this->input->post('status');
    $planned = $this->input->post('planned');
    $achieved = $this->input->post('achieved');
    $comments = $this->input->post('comments');
    $user_id = $this->input->post('user_id');

    // 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 output exists and is active
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $output = $this->db->get('follow_up_activity_outputs')->row_array();

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

    // Prepare data for update (only include provided fields)
    $data = [];
    if ($follow_up_activity_id) $data['follow_up_activity_id'] = $follow_up_activity_id;
    if ($title) $data['title'] = $title;
    if ($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']));
        }
        $data['status'] = $status;
    }
    if ($planned !== null) $data['planned'] = (int)$planned;
    if ($achieved !== null) $data['achieved'] = (int)$achieved;
    if ($comments !== null) $data['comments'] = $comments;

    // Add audit fields
    $data['updated_by'] = $user_id;
    $data['updated_at'] = date('Y-m-d H:i:s');

    // Validate follow_up_activity_id if provided
    if (isset($data['follow_up_activity_id'])) {
        $this->db->where('id', $data['follow_up_activity_id']);
        $this->db->where('is_active', 1);
        $activity_exists = $this->db->get('follow_up_activities')->num_rows() > 0;

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

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

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

    // Update the output
    $this->db->where('id', $id);
    $update = $this->db->update('follow_up_activity_outputs', $data);

    if (!$update) {
        $this->db->trans_rollback();
        log_message('error', "Failed to update follow-up activity output: " . $this->db->error()['message']);
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'OUTPUT_NOT_UPDATED - ' . $this->db->error()['message']]));
    }

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

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

    // Fetch updated output for response
    $this->db->where('id', $id);
    $updated_output = $this->db->get('follow_up_activity_outputs')->row_array();

    $response_data = [
        'success' => true,
        'message' => 'OUTPUT_UPDATED_SUCCESSFULLY',
        'data' => [
            'id' => $updated_output['id'],
            'follow_up_activity_id' => $updated_output['follow_up_activity_id'],
            'title' => $updated_output['title'],
            'status' => $updated_output['status'],
            'planned' => (int)$updated_output['planned'],
            'achieved' => (int)$updated_output['achieved'],
            'comments' => $updated_output['comments']
        ]
    ];

    return $this->output
        ->set_content_type('application/json')
        ->set_status_header(200)
        ->set_output(json_encode($response_data));
}

public function delete_follow_up_activity_output()
{
    // Get input data
    $id = $this->input->get('output_id');
    $user_id = $this->input->get('user_id');

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

    if (empty($id) || !is_numeric($id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_OUTPUT_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 output exists and is active
    $this->db->where('id', $id);
    $this->db->where('is_active', 1);
    $output = $this->db->get('follow_up_activity_outputs')->row_array();

    if (empty($output)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'OUTPUT_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
        $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')
        ];
        $this->db->where('id', $id);
        $this->db->update('follow_up_activity_outputs', $data);
    } else {
        // Perform hard delete
        $this->db->where('id', $id);
        $this->db->delete('follow_up_activity_outputs');
    }

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

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


public function delete_follow_up_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)
            ->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 follow_up_activity_id from input (required)
    $follow_up_activity_id = $this->input->get('follow_up_activity_id');
    if (empty($follow_up_activity_id) || !is_numeric($follow_up_activity_id)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_FOLLOW_UP_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)
            ->set_output(json_encode(['success' => false, 'message' => 'INVALID_DELETE_TYPE']));
    }

    // Check if follow_up_activity exists and meets delete condition
    $this->db->where('id', $follow_up_activity_id);
    if ($delete_type === 'soft') {
        $this->db->where('is_active', 1); // Ensure the follow-up activity is active before soft deleting
    } else {
        $this->db->where('is_active', 0); // For hard delete, ensure it's already soft-deleted
    }
    $follow_up_activity = $this->db->get('follow_up_activities')->row_array();

    if (empty($follow_up_activity)) {
        return $this->output
            ->set_content_type('application/json')
            ->set_status_header(400)
            ->set_output(json_encode(['success' => false, 'message' => 'FOLLOW_UP_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'),
            'updated_by' => $user_id,
            'updated_at' => date('Y-m-d H:i:s')
        ];

        $this->db->where('id', $follow_up_activity_id);
        $this->db->update('follow_up_activities', $data);

        // Soft delete related records
        $this->soft_delete_related_follow_up_activity_records($follow_up_activity_id, $user_id);
    } else {
        // Perform hard delete: delete follow_up_activity and related records
        $this->hard_delete_follow_up_activity_and_related($follow_up_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)
            ->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' => ($delete_type === 'soft' ? 'FOLLOW_UP_ACTIVITY_SOFT_DELETED_SUCCESSFULLY' : 'FOLLOW_UP_ACTIVITY_HARD_DELETED_SUCCESSFULLY'),
            'data' => [
                'follow_up_activity_id' => $follow_up_activity_id,
                'delete_type' => $delete_type
            ]
        ]));
}

// Helper function to soft delete related records for follow-up activity
private function soft_delete_related_follow_up_activity_records($follow_up_activity_id, $user_id)
{
    $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')
    ];

    // Soft delete follow_up_activity_products
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->update('follow_up_activity_products', $data);

    // Soft delete follow_up_activity_product_files
    $this->db->where('product_id IN (SELECT id FROM follow_up_activity_products WHERE follow_up_activity_id = ' . $this->db->escape($follow_up_activity_id) . ')');
    $this->db->update('follow_up_activity_product_files', $data);

    // Soft delete follow_up_activity_outputs
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->update('follow_up_activity_outputs', $data);

    // Soft delete follow_up_activity_months (if it exists)
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->update('follow_up_activity_months', $data);
}

// Helper function to hard delete follow-up activity and related records
private function hard_delete_follow_up_activity_and_related($follow_up_activity_id)
{
    // Get product IDs for this follow-up activity
    $this->db->select('id');
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $products = $this->db->get('follow_up_activity_products')->result_array();
    $product_ids = array_column($products, 'id');

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

    // Delete follow_up_activity_products
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->delete('follow_up_activity_products');

    // Delete follow_up_activity_outputs
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->delete('follow_up_activity_outputs');

    // Delete follow_up_activity_months (if it exists)
    $this->db->where('follow_up_activity_id', $follow_up_activity_id);
    $this->db->delete('follow_up_activity_months');

    // Delete the follow_up_activity
    $this->db->where('id', $follow_up_activity_id);
    $this->db->delete('follow_up_activities');
}



}