<?php
error_reporting(1); // Suppress all errors
ini_set('display_errors', 1); // Do not display errors

defined('BASEPATH') or exit('No direct script access allowed');
require(APPPATH . '/libraries/REST_Controller.php');

use Restserver\Libraries\REST_Controller;

class OperationController extends REST_Controller
{

    /**
     * __construct function.
     * 
     * @access public
     * @return void
     */

    public function __construct()
    {
        parent::__construct();
        $this->load->library('Authorization_Token');
        $this->load->library('form_validation');
        $this->load->library('encryption'); // Internal Data Enc func
        $this->load->helper('encryption_helper'); //For MasterEncrypt,Master Decrypt (transport enc func)
        $this->load->model('restAppApi/OperationModel');
        $this->load->model('restAppApi/UserModel');
        $this->load->database();
        date_default_timezone_set('Asia/Kolkata');
        $this->apiKey = 'c510cd9a-4dc9-42e9-81d7-65192e7647d8';
    }


    function LoanCalculation_post()
    {
        $u_id = MasterDecrypt($this->input->post('u_id'));
        $amount = MasterDecrypt($this->input->post('amount'));

        if (!$this->validateToken()) {
            return;
        }
        $u_id = $this->input->post('u_id');
        $decryptedUID = $this->validateAndDecryptUID($u_id);
        if (!$decryptedUID) {
            return;
        }

        $responseValue = $this->MasterCalculation($amount);
        if ($responseValue != "") {
            $response = array(
                'status' => true,
                'message' => 'Loan Options',
                'data' => $responseValue
            );
            $encrypted_response = MasterEncrypt(json_encode($response));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        } else {
            $response = array(
                'status' => false,
                'message' => 'Invalid ',
                'data' => null
            );
            $encrypted_response = MasterEncrypt(json_encode($response));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        }
    }

    public function LoanEmiDetails_post()
    {
        if (!$this->validateToken()) {
            return;
        }
        $u_id = $this->input->post('u_id');
        $decryptedUID = $this->validateAndDecryptUID($u_id);
        if (!$decryptedUID) {
            return;
        }
        /* -------------------------------------| DRIVER CODE |------------------  */
        // $u_id_normal = MasterDecrypt($u_id);
        $amount = MasterDecrypt($this->input->post('amount'));
        $tenure = MasterDecrypt($this->input->post('tenure'));

        if (!is_numeric($amount) || $amount <= 0 || !ctype_digit($tenure) || $tenure < 1) {
            $response = [
                'status' => false,
                'message' => 'Invalid amount or tenure',
                'given_amt' => $amount,
                'given_tenure' => $tenure
            ];
            $encrypted_response = MasterEncrypt(json_encode($response));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        }

        $responsex = $this->MasterCalculation($amount, $tenure);

        // echo json_encode($responsex);
        // die();

        $interestRate = $responsex[0]['interestRate'];
        $platformFee = $responsex[0]['platformFee'];
        $processingFee = $responsex[0]['processingFee'];
        $gstPlatformFee = $responsex[0]['gstPlatformFee'];
        $gstProcessingFee = $responsex[0]['gstProcessingFee'];
        $amount = $responsex[0]['amount'];

        $args = [$interestRate, $platformFee, $processingFee, $gstPlatformFee, $gstProcessingFee, $amount, $tenure];

        $finalLoanDetails = $this->calculateEmiAmountsDates($args);

        if ($finalLoanDetails != "") {
            $encrypted_response = MasterEncrypt(json_encode($finalLoanDetails));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        } else {
            $response = array(
                'status' => false,
                'message' => 'Something Went Wrong'
            );
            $encrypted_response = MasterEncrypt(json_encode($response));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        }
    }

    private function MasterCalculation($amount, $tenure = null)
    {
        $details = array();
        // Define the ranges and corresponding values
        $loanRanges = [
            ['min' => 1000, 'max' => 5000, 'interestRate' => 24, 'tenure' => [1, 2, 3], 'platformFee' => 100, 'processingFeePercent' => 1.5],
            ['min' => 5001, 'max' => 10000, 'interestRate' => 20, 'tenure' => [3, 4, 6], 'platformFee' => 150, 'processingFeePercent' => 2],
            ['min' => 10001, 'max' => 15000, 'interestRate' => 18, 'tenure' => [6, 8, 9], 'platformFee' => 200, 'processingFeePercent' => 2.5],
            ['min' => 15001, 'max' => 20000, 'interestRate' => 16, 'tenure' => [9, 10, 12], 'platformFee' => 250, 'processingFeePercent' => 2.75],
            ['min' => 20001, 'max' => 30000, 'interestRate' => 14, 'tenure' => [12, 15, 18], 'platformFee' => 300, 'processingFeePercent' => 2.5],
            ['min' => 30001, 'max' => 40000, 'interestRate' => 12, 'tenure' => [18, 21, 24], 'platformFee' => 350, 'processingFeePercent' => 2],
            ['min' => 40001, 'max' => PHP_INT_MAX, 'interestRate' => 10, 'tenure' => [18, 21, 24], 'platformFee' => 400, 'processingFeePercent' => 1.5]
        ];

        // Determine the loan details based on the amount
        foreach ($loanRanges as $range) {
            if ($amount >= $range['min'] && $amount <= $range['max']) {
                foreach ($range['tenure'] as $availableTenure) {
                    // Check if the specified tenure matches
                    if ($tenure === null || $tenure == $availableTenure) {
                        // Fixed interest rate, platform fee, and processing fee percentage based on defined rules
                        $interestRate = $range['interestRate'];
                        $platformFee = $range['platformFee'];
                        $processingFeePercent = $range['processingFeePercent'];

                        // Calculate processing fee
                        $processingFee = $amount * ($processingFeePercent / 100);

                        // Calculate GST
                        $gstPlatformFee = $platformFee * 0.18;
                        $gstProcessingFee = $processingFee * 0.18;

                        // Store details
                        $details[] = array(
                            'amount' => $amount,
                            'interestRate' => sprintf('%02.2f', $interestRate),
                            'tenure' => $availableTenure,
                            'platformFee' => sprintf('%02.2f', $platformFee),
                            'processingFee' => sprintf('%02.2f', $processingFee),
                            'gstPlatformFee' => sprintf('%02.2f', $gstPlatformFee),
                            'gstProcessingFee' => sprintf('%02.2f', $gstProcessingFee)
                        );
                    }
                }
                break;
            }
        }

        return $details;
    }



    private function calculateEmiAmountsDates($args)
    {
        $interestRate = $args[0];
        $platformFee = $args[1];
        $processingFee = $args[2];
        $gstPlatformFee = $args[3];
        $gstProcessingFee = $args[4];
        $amount = $args[5];
        $tenure = $args[6];

        // Calculate interest amount and the amount to be deducted
        $interestAmount = ($interestRate / 100) * $amount;
        $deductAmount = $platformFee + $gstPlatformFee + $processingFee + $gstProcessingFee;

        // Calculate the net amount user will receive and total amount to be paid with interest
        $userWillGetAmount = $amount - $deductAmount;
        $userWillPayWithInterest = $amount + $interestAmount;

        // Round up all calculated amounts to the nearest integer
        $userWillGetAmount = ceil($userWillGetAmount);
        $userWillPayWithInterest = ceil($userWillPayWithInterest);

        // Calculate the monthly EMI amount and round it up to the nearest integer
        $monthlyEmi = ceil($userWillPayWithInterest / $tenure);

        // Prepare EMI schedule with dates
        $emiSchedule = [];
        $emiDate = new DateTime();  // Start from the current date

        for ($i = 0; $i < $tenure; $i++) {
            $emiDate->modify('+1 month');
            $emiSchedule[] = [
                'date' => $emiDate->format('Y-m-d'),
                'amount' => $monthlyEmi  // Already rounded up
            ];
        }

        return [
            'loan_amount' => $amount,
            'disburse_amount' => $userWillGetAmount,
            'processing_fee' => $processingFee + $gstProcessingFee,
            'platform_fee' => $platformFee + $gstPlatformFee,
            'interest_rate' => $interestRate,
            'payable_amount' => $userWillPayWithInterest,
            'emiSchedule' => $emiSchedule
        ];
    }

    /*---------------------------------------------| Loan Controller End |--------------------------------------------------------- */

    public function validateBankDetails_post()
    {
        $u_id = MasterDecrypt($this->input->post('u_id'));
        $bank_name = MasterDecrypt($this->input->post('bank_name'));
        $ac_no = MasterDecrypt($this->input->post('account_no'));
        $ifsc_code = MasterDecrypt($this->input->post('ifsc_code'));
        $ac_holder_name = MasterDecrypt($this->input->post('account_holder_name'));


        if (!$this->validateToken()) {
            return;
        }
        $decryptedUID = $this->validateAndDecryptUID($this->input->post('u_id'));
        if (!$decryptedUID) {
            return;
        }

        $apirespons = json_decode($this->verify_bank($ac_no, $ifsc_code));


        if ($apirespons->status == 'success') {
            $matchDetails = $this->UserModel->matchUserInfo($apirespons->data->full_name, $u_id);

            if ($matchDetails) {
                $data = array("u_id" => $u_id, "bank_name" => $bank_name, "account_holder_name" => $ac_holder_name, "ifsc_code" => $ifsc_code, "account_no" => $ac_no, "validation_status" => '1');
                $this->UserModel->InsertBankInfo('user_bank_details', $data);
                $encrypted_response = MasterEncrypt(json_encode($apirespons));
                $this->response($encrypted_response, REST_Controller::HTTP_OK);
                return;
            } else {
                $response = array(
                    "data" => [
                        "upi_id" => null,
                        "full_name" => null,
                    ],
                    "message" => "User Name Mismatched.",
                    "status" => "error"
                );
                $encrypted_response = MasterEncrypt(json_encode($response));
                $this->response($encrypted_response, REST_Controller::HTTP_OK);
                return;
            }
        } else {
            $encrypted_response = MasterEncrypt(json_encode($apirespons));
            $this->response($encrypted_response, REST_Controller::HTTP_OK);
            return;
        }
    }

    public function verify_bank($ac_no, $ifsc_code)
    {
        // API Endpoint
        $url = 'https://api.quickekyc.com/api/v1/bank-verification';

        // Payload for the POST request
        $data = array(
            'key' => $this->apiKey, // Replace with your actual API key
            'id_number' => $ac_no, // Replace with the actual bank number
            'ifsc' => $ifsc_code // Replace with the actual IFSC code
        );

        // Convert data array to JSON
        $jsonData = json_encode($data);

        // Initialize cURL session
        $ch = curl_init();

        // Set cURL options
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);

        // Execute cURL session and store the response
        $response = curl_exec($ch);

        // Check for cURL errors
        if (curl_errno($ch)) {
            $error_msg = curl_error($ch);
            curl_close($ch);
            // Handle error here
            echo json_encode(array('error' => $error_msg));
            return;
        }

        // Close cURL session
        curl_close($ch);

        // Output the response
        return $response;
    }


    /*---------------------------------------------| Bank Validation Controller End |--------------------------------------------------------- */


    protected function validateToken()
    {
        $headers = $this->input->request_headers();
        if (isset($headers['authorization'])) {
            $decodedToken = $this->authorization_token->validateToken($headers['authorization']);
            if (!$decodedToken['status']) {
                // Token expired or invalid
                $this->sendErrorResponse('Token Expired!', REST_Controller::HTTP_OK);
                return false;
            }
            return true;
        } else {
            $this->sendErrorResponse('Authentication failed', REST_Controller::HTTP_OK);
            return false;
        }
    }

    protected function validateAndDecryptUID($uid)
    {
        $decryptedUID = MasterDecrypt($uid);
        if (!$this->validateUID($decryptedUID)) {
            $this->sendErrorResponse('Invalid User', REST_Controller::HTTP_BAD_REQUEST);
            return false;
        }
        return $decryptedUID;
    }

    protected function sendErrorResponse($message, $httpCode)
    {
        $response = [
            'status' => false,
            'message' => $message
        ];
        $encrypted_response = MasterEncrypt(json_encode($response));
        $this->response($encrypted_response, $httpCode);
    }

    private function validateUID($u_id)
    {
        $mdl_response = $this->UserModel->validateUID($u_id);
        // Check if the length is 10 characters
        if ($mdl_response) {
            return true;
        } else {
            return false;
        }
    }
    /*---------------------------------------------| Internal Functions End |--------------------------------------------------------- */
}
