<?php 

defined('BASEPATH') OR exit('No direct script access allowed');
header('Content-Type: application/json');

class Services extends CI_Controller{
    public function __construct(){

        parent::__construct();

        date_default_timezone_set('Asia/Kolkata');

        
        // Enable CORS
        header("Access-Control-Allow-Origin: https://mrit-24277.web.app");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        header("Access-Control-Allow-Headers: Content-Type, Authorization");
        header("Access-Control-Allow-Headers: Content-Type, Authorization, auth-token");
        // Handle preflight OPTIONS request
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(200);
            exit;
        }

        if ((!isset($_SERVER['HTTP_AUTH_TOKEN'])) || empty($_SERVER['HTTP_AUTH_TOKEN'])) {
            echo json_encode([
                'status' => '0',
                'message' => 'auth token required',
                'details' => []
            ]);
            exit;
        }

    }

   
    // ? check user
    protected function get_user_details(){
        $valid = $this->cm->search_single_where(['auth_token' => $_SERVER['HTTP_AUTH_TOKEN']], 'user_tokens');
        if (empty($valid)) {
            echo json_encode([
                'status' => '0',
                'message' => 'invalid auth token',
                'details' => []
            ]);
            exit;
        } else {
            $user = $this->cm->search_single_where( ['id' => $valid['user_id']] , 'users');
            
            return $user;
        }
    }


    // * get all services 
    public function get_services_list(){

        request_method('GET');

        $services = $this->cm->select_multiple_where('*', ['type' => 'bot'], 'DESC', 'id', 'services'); // type : bot , other

        if(empty($services)){
            echo json_encode([
                'status' => '0',
                'message' => 'data not found'
            ]);exit;
        }

        echo json_encode([
            'status' => '1',
            'message' => 'data found',
            'details' => $services
        ]);exit;

    }


    // * create service request
    public function service_request(){
        request_method('POST');

        $user = $this->get_user_details();
        
        $request = check_parameter([
            'service_id' => true,
            'link' => true,
            'quantity' => true
        ]);

        $service = $this->cm->search_single_where(['id' => $request['service_id']], 'services');

        if(empty($service)){
            echo json_encode([
                'status' => '0',
                'message' => 'invalid service id'
            ]);exit;
        }

        // Fetch the applicable discount based on quantity
        $quantity = $request['quantity'];
        $discount = $this->cm->select_single_where("MAX(discount_percentage) AS discount_percentage", [
            'min_quantity <=' => $quantity
        ], 'discounts');

         // Apply discount if available
        $discount_percentage = !empty($discount['discount_percentage']) ? $discount['discount_percentage'] : 0;
        $user_wallet = $user['wallet'];
        
        // Calculate service charges with the applicable discount
        $service_charges = ($service['coins'] / 100) * $quantity;
        $discount_amount = ($service_charges * $discount_percentage) / 100;
        $total_charges = $service_charges - $discount_amount;

        if($total_charges > $user_wallet){
            echo json_encode([
                'status' => '1',
                'message' => 'Insufficient balance in wallet'
            ]);
            exit;
        }


        $smmApi = "https://smmsocialmedia.in/api/v2";

        $form_data = array(
            // 'key' => '2f86f17dc543edf4db9676852c110d0c',
            'key' => 'b7c6f03113d091b14d966c84e68eb121',
            'action' => 'add',
            'service' => $service['service_id'],
            'link' => $request['link'],
            'quantity' => $quantity,
        );

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $smmApi,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $form_data,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false
        ));

        // Execute the cURL request
        $response = curl_exec($curl);

        // Check for errors
        if(curl_errno($curl)){
             $error_msg = curl_error($curl);
             // Handle error
             $responseData = array('error' => $error_msg);

             echo json_encode([
                'status' => '0',
                'message' => 'error! try again',
                'details' => $error_msg
             ]);
             
             // Close cURL session
            curl_close($curl);

             exit;

        } else {

       
            $responseData = json_decode($response, true);


            if(isset($responseData['error'])){
                echo json_encode([
                    'status' => '0',
                    'message' => $responseData['error']
                ]);exit;
            }

            $req['user_id'] = $user['id'];
            $req['service_code'] = $service['service_id'];
            $req['service_id'] = $service['id'];
            $req['link'] = $request['link'];
            $req['target'] = $request['quantity'];
            $req['order_no'] = $responseData['order'];
            $req['discount_applied'] = $discount_percentage;
            $req['total_charges'] = (int)$total_charges;
            $req['created_at'] = date('Y-m-d H:i:s');
            $req['updated_at'] = date('Y-m-d H:i:s');

            $ins = $this->cm->save_data($req, 'user_service_requests');

            $req_id = $this->cm->last_id();

            if($user['referred_by'] != null){

                $request_count = count($this->cm->select_multiple_where('*', ['user_id' => $user['id']], 'DESC', 'id', 'user_service_requests'));

                $referrer_details = $this->cm->search_single_where(['referrer_id' => $user['referred_by']], 'referral_tracking');

                $reward_data = $this->cm->search_single_where(['user_type' => $referrer_details['referrer_type']], 'referral_rewards_settings');


                if($request_count > 1 && ($referrer_details['referrer_type'] == 'regular')){

                }else{

                    $referrer1 = $this->db->get_where('users', ['id' => $referrer_details['referrer_id']])->row_array();

                    $this->db->set('wallet', 'wallet + ' . (int)$reward_data['reward_coins'], FALSE);
                    $this->db->where('id', $referrer_details['referrer_id']);
                    $this->db->update('users');


                   

                    $record = array(
                        'referrer_id' => $referrer_details['referrer_id'],
                        'referrer_type' => $referrer_details['referrer_type'],
                        'referee_id' => $referrer_details['referee_id'],
                        'request_id' => $req_id,
                        'reward_coins' => $reward_data['reward_coins'],
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s')
                    );

                    $rewardId = $this->cm->save_data($record, 'referral_rewards');


                    // Log coin assignment
                    $entry = [
                        'user_id' => $referrer_details['referrer_id'],
                        'type' => 'referrer_purchase',
                        'from' => $referrer1['wallet'],
                        'coins' => $reward_data['reward_coins'],
                        'to' => $referrer1['wallet'] + $reward_data['reward_coins'],
                        'request_id' => $req_id,
                        'created' => date('Y-m-d H:i:s')
                    ];

                    $this->db->insert('user_wallet_history', $entry);


                }

            }

            $this->db->set('wallet', 'wallet - ' . (int)$total_charges, FALSE);
            $this->db->where('id', $user['id']);
            $this->db->update('users');


             // Log coin assignment
             $entry = [
                'user_id' =>  $user['id'],
                'type' => 'user_purchase',
                'from' =>  $user_wallet,
                'coins' => $total_charges,
                'to' => $user_wallet - $total_charges,
                'request_id' => $req_id,
                'created' => date('Y-m-d H:i:s')
            ];

            $this->db->insert('user_wallet_history', $entry);


            echo json_encode([
                'status' => '1',
                'message' => 'request added',
                'details' => $responseData
             ]);
             
             // Close cURL session
            curl_close($curl);
             exit;
        }
        
    }


    // * get service request history
    public function get_history() {
        request_method('GET');
    
        $user = $this->get_user_details();
    
        // Fetch only the user requests that are not completed or canceled yet
        $pending_requests = $this->db->select('user_service_requests.*, services.name')
                            ->from('user_service_requests')
                            ->join('services', 'services.id = user_service_requests.service_id')
                            ->where('user_service_requests.user_id', $user['id'])
                            ->where_not_in('user_service_requests.status', ['Completed', 'Canceled']) // Exclude already completed/canceled
                            ->get()
                            ->result_array();
    
        if (!$pending_requests) {
            echo json_encode([
                'status' => '0',
                'message' => 'No pending data found'
            ]);
            exit;
        }
    
        // Extract order numbers
        $order_ids = array_column($pending_requests, 'order_no');
        if (empty($order_ids)) {
            echo json_encode([
                'status' => '0',
                'message' => 'No order numbers found'
            ]);
            exit;
        }
    
        $order_ids_string = implode(',', $order_ids);
    
        // Call the external API to get the latest order statuses
        $smmApi = "https://smmsocialmedia.in/api/v2";
        $api_key = 'b7c6f03113d091b14d966c84e68eb121'; // Secure API Key
    
        $form_data = [
            'key' => $api_key,
            'action' => 'status',
            'orders' => $order_ids_string
        ];
    
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => $smmApi,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $form_data,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
    
        $response = curl_exec($curl);
        curl_close($curl);
    
        if (!$response) {
            echo json_encode([
                'status' => '0',
                'message' => 'Failed to fetch order status from API'
            ]);
            exit;
        }
    
        $order_statuses = json_decode($response, true);
    
        // Start transaction to ensure consistency
        $this->db->trans_start();
    
        foreach ($pending_requests as $request) {


            $order_no = $request['order_no'];
            
            if (isset($order_statuses[$order_no]) && !isset($order_statuses[$order_no]['error'])) {
                $new_status = $order_statuses[$order_no]['status'];
                $remaining_count = isset($order_statuses[$order_no]['remains']) ? $order_statuses[$order_no]['remains'] : 0;
                $completed_count = $request['target'] - $remaining_count;
    
                $update_data = [
                    'status' => $new_status,
                    'remaining_count' => $remaining_count,
                    'completed_count' => $completed_count
                ];
    
                $this->db->where('order_no', $order_no)
                         ->update('user_service_requests', $update_data);
    
                // If the order is canceled, return the charges to the user's wallet
                if ($new_status === "Canceled") {
                    $refund_amount = (int) $request['total_charges'];

                    $user1 = $this->db->get_where('users', ['id' => $user['id']])->row_array();

                    $this->db->set('wallet', 'wallet + ' . $refund_amount, FALSE)
                             ->where('id', $user['id'])
                             ->update('users');

                    // Log coin assignment
                    $entry = [
                        'user_id' =>  $user1['id'],
                        'type' => 'refund',
                        'from' =>  $user1['wallet'],
                        'coins' => $refund_amount,
                        'to' => $user1['wallet'] + $refund_amount,
                        'request_id' => $request['id'],
                        'created' => date('Y-m-d H:i:s')
                    ];

                    $this->db->insert('user_wallet_history', $entry);


                }
            }
        }
    
        // Commit the transaction
        $this->db->trans_complete();
    
        if ($this->db->trans_status() === FALSE) {
            echo json_encode([
                'status' => '0',
                'message' => 'Transaction failed, please try again.'
            ]);
            exit;
        }
    
        // Fetch updated data
        $updated_data = $this->db->select('user_service_requests.*, services.name')
                                ->from('user_service_requests')
                                ->join('services', 'services.id = user_service_requests.service_id')
                                ->where('user_service_requests.user_id', $user['id'])
                                ->order_by('id', 'desc')
                                ->get()
                                ->result_array();
    
        echo json_encode([
            'status' => '1',
            'message' => 'Data updated successfully',
            'details' => $updated_data
        ]);
        exit;
    }
    

    // ! Create new request by user 
    public function create_new_request(){

        // - Check the service existence , coins in users wallet
        // - create new request in the "user_service_requests" table 
        // - Deduct the coins from wallet
        // - Add buffer of 5% in the requested count 

        // check method 
        request_method('POST');

        // check user token 
        $user = $this->get_user_details();

        // get input data 
        $service_id = $this->input->post('service_id');
        $link = $this->input->post('link');
        $target = $this->input->post('target');

        // validate data 
        $request = check_parameter([
            'service_id' => true,
            'link' => true,
            'target' => true
        ]);

        if ($target <= 0) {
            echo json_encode([
                'status' => '0',
                'message' => 'Target must be greater than 0.'
            ]); exit;
        }


        // check service_id and get coins 
        $service = $this->cm->search_single_where(['id' => $service_id], 'services');

        if(empty($service)){
            echo json_encode([
                'status' => '0',
                'message' => 'Invalid service Id'
            ]);exit;
        }

        // calculate total charges (coins for each request is stored for 100 users)
        $total_charges = ($service['coins']/100) * $target; 

        // check coins in users wallet 
        if($user['wallet'] < $total_charges){
            echo json_encode([
                'status' => '0',
                'message' => 'Insufficient wallet balance. You need ' . ($total_charges - $user['wallet']) . ' more coins.'
            ]);exit;
        }

        // Calculate buffer and initialize counts
        $buffer_percentage = 10; 
        $buffered_count = ceil($target + ($target * $buffer_percentage / 100));
        $remaining_count = $buffered_count; 

        // add request 
        $request_data = array(
            'user_id' => $user['id'],
            'service_code' => $service['service_id'],
            'service_id' => $service['id'],
            'link' => $link,
            'target' => $target,
            'buffered_count' => $buffered_count,
            'remaining_count' => $remaining_count,
            'completed_count' => 0,
            'total_charges' => $total_charges,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        );


        $this->cm->save_data($request_data, 'user_service_requests');

        $request_id = $this->cm->last_id();

        if($request_id){
            // update user wallet
            $this->db->trans_start();

            // Update wallet
            $updated_wallet_balance = $user['wallet'] - $total_charges;
            $this->cm->update_where(['wallet' => $updated_wallet_balance], ['id' => $user['id']], 'users');

            $this->db->trans_complete();

            if ($this->db->trans_status() === FALSE) {
                echo json_encode([
                    'status' => '0',
                    'message' => 'Transaction failed. Please try again.'
                ]); exit;
            }

            // Log coin assignment
            $entry = [
                'user_id' =>  $user['id'],
                'type' => 'request_purchase',
                'from' =>  $user['wallet'],
                'coins' => $total_charges,
                'to' => $user['wallet'] - $total_charges,
                'request_id' => $request_id,
                'created' => date('Y-m-d H:i:s')
            ];

            $this->db->insert('user_wallet_history', $entry);
            

            echo json_encode([
                'status' => '1',
                'message' => 'request created successfully',
                'details' => ['request_id' => $request_id]
            ]);exit;

        }else{
            echo json_encode([
                'status' => '0',
                'message' => 'failed to create request'
            ]);exit;
        }

    }



    // ! fetch pendin request to earn coins 
    public function fetch_requests_to_earn_coins(){

        // check request method
        request_method('GET');

        // check user token 
        $user = $this->get_user_details();

        // check input data 
        $request = check_get_parameter([
            'service_id' => true
        ]);


        $service_id = $request['service_id'];

        // check service_id
        // $service = $this->cm->search_single_where(['id' => $service_id], 'services');'
        

        // if(empty($service)){
        //     echo json_encode([
        //         'status' => '0',
        //         'message' => 'Invalid service Id'
        //     ]);exit;
        // }

        $pending_requests = $this->request_model->get_pending_requests($service_id, $user['id']);
        $pending_requests1 = $this->request_model->get_pending_requests1($service_id, $user['id']);

        if (!empty($pending_requests)) {
            echo json_encode([
                'status' => '1',
                'message' => 'Pending requests fetched successfully.',
                'details' => $pending_requests,
                'details1' => $pending_requests1
            ]); exit;
        } else {
            echo json_encode([
                'status' => '0',
                'message' => 'No pending requests found.'
            ]); exit;
        }

    }



    // ! Get all pending request
    public function fetch_all_pending_requests(){

        // check request method 
        request_method('GET');

        // check user details
        $user = $this->get_user_details();

        $pending_requests = $this->request_model->get_all_pending_requests($user['id']);
        $pending_requests1 = $this->request_model->get_pending_requests1(15, $user['id'], 'view', 'watch_admin_videos');


        if (!empty($pending_requests)) {
            echo json_encode([
                'status' => '1',
                'message' => 'Pending requests fetched successfully.',
                // 'data1' => $pending_requests,
                'data' => $pending_requests1
            ]); exit;
        } else {
            echo json_encode([
                'status' => '0',
                'message' => 'No pending requests found.'
            ]); exit;
        }
    }
    public function fetch_all_pending_requests_likes(){

        // check request method 
        request_method('GET');

        // check user details
        $user = $this->get_user_details();

        // $pending_requests = $this->request_model->get_all_pending_requests($user['id']);
        $pending_requests1 = $this->request_model->get_pending_requests2(15, $user['id'], 'like', 'like_admin_videos');




        if (!empty($pending_requests1)) {
            echo json_encode([
                'status' => '1',
                'message' => 'Pending requests fetched successfully.',
                // 'data1' => $pending_requests,
                'data' => $pending_requests1
            ]); exit;
        } else {
            echo json_encode([
                'status' => '0',
                'message' => 'No pending requests found.'
            ]); exit;
        }
    }
    public function fetch_all_pending_requests_subscribe(){

        // check request method 
        request_method('GET');

        // check user details
        $user = $this->get_user_details();

        // $pending_requests = $this->request_model->get_all_pending_requests($user['id']);
        $pending_requests1 = $this->request_model->get_pending_requests2(15, $user['id'], 'subscribe' , 'subscribe_admin_videos');


        if (!empty($pending_requests1)) {
            echo json_encode([
                'status' => '1',
                'message' => 'Pending requests fetched successfully.',
                // 'data1' => $pending_requests,
                'data' => $pending_requests1
            ]); exit;
        } else {
            echo json_encode([
                'status' => '0',
                'message' => 'No pending requests found.'
            ]); exit;
        }
    }


   
    // ! complete action 
    public function complete_action(){
        // check request method 
        request_method('POST');

        // check user details
        $user = $this->get_user_details();

      

        $post_request = check_parameter([
            'request_id' => true
        ]);

        // check request_id 
        // $request = $this->cm->search_single_where(['id' => $post_request['request_id']], 'user_service_requests');
        
        // if(empty($request)){
        //     echo json_encode([
        //         'status' => '0',
        //         'message' => 'Invalid request Id'
        //     ]);exit; 
        // }


        // get service details 
        // $service = $this->cm->search_single_where(['id' => $request['service_id']], 'services');

        $request = $this->db->get_where('admin_videos', ['id' => $post_request['request_id']])->row_array();

        $request_id = $request['id'];
        $video_type = $request['type']; // Retrieve the type of action

        if($request['type']=='view'){
            $video_type = 'watch_admin_videos';
        }else if($request['type']=='like'){
            $video_type = 'like_admin_videos';
        }else if($request['type']=='subscribe'){
            $video_type = 'subscribe_admin_videos';
        }else{
            $video_type = 'watch_admin_videos';
        }


        if ($request['remaining_count'] <= 0 || $request['remaining_count'] > $request['buffered_count']) {
            echo json_encode([
                'status' => '0',
                'message' => 'No actions remaining for this request.'
            ]); exit;
        }

        // update request progress
        $this->db->trans_start();

         // Decrement remaining_count and increment completed_count
        $this->request_model->update_request_progress($request_id);


        $coins_settings = $this->db->get_where('coins_rewards_settings', ['type' => $video_type])->row_array();
    
        
        // Reward user with coins and update wallet 
        $reward_coins = !empty($coins_settings['coins'])? $coins_settings['coins'] : 0.1;
        // $reward_coins = $service['reward_coins']? $service['reward_coins'] : 0;
        $updated_wallet_balance = $reward_coins + $user['wallet'];
        $this->cm->update_where(['wallet' => $updated_wallet_balance], ['id' => $user['id']], 'users');


        $history = array(
            'admin_video_id' => $request_id,
            'type' => $request['type'],
            'user_id' => $user['id']
        );

        $this->db->insert('admin_videos_history', $history);

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

        // Log coin assignment
        $entry = [
            'user_id' => $user['id'],
            'type' => 'purchase',
            'from' => $user['wallet'],
            'coins' => $reward_coins,
            'to' => $updated_wallet_balance,
            'record_id' => $record_id,
            'created' => date('Y-m-d H:i:s')
        ];

        $this->db->insert('user_wallet_history', $entry);

        // Log action
        // $this->request_model->log_action($user['id'], $request_id, $service['name'],$reward_coins);

        // Mark as completed if remaining_count == 0
        // $remaining_count_after_update = $request['remaining_count'] - 1;
        // if ($remaining_count_after_update == 0) {
        //     $this->Requests_model->mark_as_completed($request_id);
        // }

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE) {
            echo json_encode([
                'status' => '0',
                'message' => 'Transaction failed. Please try again.'
            ]); exit;
        }
    
        // Success response
        echo json_encode([
            'status' => '1',
            'message' => 'Action completed successfully.',
            'data' => [
                'reward_coins' => $reward_coins
            ]
        ]); exit;

    }


    // !  get user requests
    public function get_user_requests(){

        // check request method
        request_method('GET');

        // check user details
        $user = $this->get_user_details();

        // Pagination parameters
        $page = $this->input->get('page') ?? 1;
        $limit = $this->input->get('limit') ?? 10;
        $offset = ($page - 1) * $limit;

        // Optional filter for status
        $status = $this->input->get('status'); // e.g., Pending, Completed, or Canceled

        // Fetch user requests
        $user_requests = $this->request_model->get_requests_by_user($user['id'], $limit, $offset, $status);

        // Check if data is available
        if (empty($user_requests)) {
            echo json_encode([
                'status' => '0',
                'message' => 'No requests found for this user.'
            ]); exit;
        }

        // Return data
        echo json_encode([
            'status' => '1',
            'message' => 'User requests fetched successfully.',
            'data' => $user_requests
        ]); exit;

    }

}