<?php

ini_set('display_errors', 1);

require_once '../../../resources/base_path_include.php';
require_once $base_path_to_resources . "includes/config.php"; // use require for mandatory files
require_once $base_path_to_resources . 'lib/function.php';
require_once $base_path_to_resources . "lib/currency_functions.php";

//valdation file
require_once $base_path_to_resources . 'lib/validate_api_signature.php';
require_once $base_path_to_resources . 'lib/validate_function.php';
require_once $base_path . 'user_management/authenticate.php';
require_once $base_path . 'modules/accounting/groups_ledgers/update_ledger_balance.php';
require_once $base_path . 'modules/accounting/global_settings/transaction_settings/function_renumber_automatic_transaction.php';
//curl api
require_once $base_path . 'resources/external_requests/education_curl/curl_book_update.php';

//creating dynamic db
require_once $base_path_to_resources . 'includes/specific_db_config.php';
$postdata = json_decode(file_get_contents("php://input"), true);
checkIfNoPhpContentsReceive();
if (
    !isset($postdata['api_signature']) or !checkIfIssetAndNotEmpty($postdata['api_signature']) or
    !isset($postdata['function_type']) or !checkIfIssetAndNotEmpty($postdata['function_type']) or !isset($postdata['jwt_token']) or !checkIfIssetAndNotEmpty($postdata['jwt_token'])
) {
    errorreturn("All fields are required.");
}
validateApiSignature($postdata['api_signature']);

//authenticate jwt token
$jwttoken = $postdata['jwt_token'];
$jwt_validate = authenticate_jwt($jwttoken);
//then workspace_id is decoded in data of jwt use from there
$userid = $jwt_validate->data->id;
$workspace_id = $jwt_validate->data->workspace_id;
$role = $jwt_validate->data->role;
$created_by = $jwt_validate->data->username;


if ($postdata['function_type'] == "create_book") {
    if (
        !isset($postdata['company_id']) or !checkIfIssetAndNotEmpty($postdata['company_id']) or
        !isset($postdata['branch_id']) or !checkIfIssetAndNotEmpty($postdata['branch_id']) or
        !isset($postdata['name']) or  !checkIfIssetAndNotEmpty($postdata['name']) or
        !isset($postdata['book_opening_date']) or !checkIfIssetAndNotEmpty($postdata['book_opening_date']) or
        !isset($postdata['book_closing_date']) or !checkIfIssetAndNotEmpty($postdata['book_closing_date']) or
        !isset($postdata['api_signature']) or !checkIfIssetAndNotEmpty($postdata['api_signature']) or
        !isset($postdata['financial_year_startdate']) or !checkIfIssetAndNotEmpty($postdata['financial_year_startdate'])
    ) {
        errorreturn("All * fields are required.");
    }

    $company_id = trim($postdata['company_id']);
    $branch_id = trim($postdata['branch_id']);
    $name = ucwords(trim($postdata['name']));
    //FIFI,LIFO,AVG PRICE
    //$stock_valuation_mode = ucwords(trim($postdata['stock_valuation_mode']));

    $book_opening_date = trim(date('Y-m-d', strtotime($postdata['book_opening_date'])));


    $book_closing_date = trim(date('Y-m-d', strtotime($postdata['book_closing_date'])));
    // $financial_year_startdate = trim(date('m-d', strtotime($postdata['financial_year_startdate'])));
    $financial_year_startdate = trim($postdata['financial_year_startdate']);
    // Construct a date string for a fixed year (e.g., 2000) using the financial year start date
    $financial_year = $financial_year_startdate . "-2000";

    // Check if the constructed date is valid
    if (strtotime($financial_year)) {
        // Format the date as 'm-d'
        $financial_year_startdate = date("m-d", strtotime($financial_year));
    } else {
        // Handle the error case
        errorreturn("Invalid financial year start date.");
    }
    $date_pattern = '/^(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/';

    // Check if the input date matches the expected format
    if (!preg_match($date_pattern, $financial_year_startdate)) {
        // Handle invalid date format
        errorreturn('Invalid date format for Financial Year Starts On. Please provide a valid date in the format mm-dd.');
    }
    //print_r($book_closing_date);die();

    $function_code = $postdata['function_type'];
    //also check if the company is being created by a super_admin and admin only, if not throw access not granted error.

    $confirmed_role_user = validatePrimaryAccess($conn, $workspace_id, $role, $userid, ['superadmin', 'admin', null]);
    if (!$confirmed_role_user) {
        errorreturn('Access denied.');
    } else {
        $specific_db_conn = dynamicDbConnection($confirmed_role_user);
        if ($role == null) {
            checkCompanyBranchFunctionAccess($specific_db_conn, $role, $userid, $workspace_id, $company_id, $branch_id, $book_id,  $function_code);
        }
    }
    //Book Opening Date Y-m-d
    if (!CheckStartDate($book_opening_date)) {
        //eg House Name, Street Name
        errorreturn('Invalid Date Format');
    }

    //Book Opening Date Y-m-d
    if (!CheckStartDate($book_closing_date)) {
        //eg House Name, Street Name
        errorreturn('Invalid Date Format');
    }

    if ($book_opening_date >= $book_closing_date) {
        errorreturn('Invalid Date Range');
    }

    // validate from users if existing super admins have either the same email or mobile, incase yes stop from proceeding
    $res = $specific_db_conn->prepare("SELECT workspace_id,name FROM act_books WHERE workspace_id = ? and name= ? and company_id = ? and branch_id = ?");
    $res->execute(array($workspace_id, $name, $company_id, $branch_id));
    $result1 = $res->fetchAll();
    if (count($result1) >= 1) {
        errorreturn("Account Book Name already exists");
    }


    try {

        $sql = "INSERT INTO act_books(workspace_id,company_id,branch_id,name,book_opening_date,book_closing_date,financial_year_startdate,lock_status) VALUES(?,?,?,?,?,?,?,?)";
        $stmt =  $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $name, $book_opening_date, $book_closing_date, $financial_year_startdate, '1'));
        $book_id = $specific_db_conn->lastInsertId();
        // get book id added here
        // insert a row into inventory_groups_info where group_name =  'Primary'
        $book_id = $specific_db_conn->lastInsertId();
        // insert primary groups in inventory grous info
        $sql = "INSERT INTO inventory_groups_info(workspace_id,company_id,branch_id,book_id,group_name)
                             VALUES(?,?,?,?,?)";
        $stmt =  $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, 'Primary'));

        //insert primary location for region when we create act_book
        $sql = "INSERT INTO inventory_region_details(workspace_id,company_id,branch_id,book_id,name,address,city,pincode,country) VALUES(?,?,?,?,?,?,?,?,?)";
        $stmt =  $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, 'Primary', '', '', '', ''));



        // over here you need to add a ledger in both ledgerdetails and ledgerbalance
        // ledgername = 'Profit & Loss A/c'
        $ledgerhead = 'Profit & Loss Account'; // add this to ledgerhead_basics first
        $ledger_name = 'Profit & Loss A/c';
        $ledger_opening_bal = 0.00;
        $ledger_current_bal = 0.00;
        $sql = "INSERT INTO act_ledgerdetails(workspace_id,company_id,branch_id,book_id,ledger_name,ledger_opening_bal,ledger_current_bal,ledger_parent_group,ledger_main_ledgerhead,date_created,
          time_created,created_by,status)
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
        $stmt =  $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, $ledger_name, $ledger_opening_bal, $ledger_current_bal, $ledgerhead, $ledgerhead, date('Y-m-d'), time(), $created_by, '1'));

        $ledgerid = $specific_db_conn->lastInsertId();

        UpdateLedgerBalance($specific_db_conn, $workspace_id, $company_id, $branch_id, $book_id, $ledgerid, $ledger_opening_bal, $book_opening_date, $ledgerhead, $ledgerhead);
        //act book settings
        $logo = null;
        $default_transaction_numbering_system = json_encode(array("manual" => [], "automatic" => $transactiontypes_array_settings));
        $sql = "INSERT INTO act_book_settings(workspace_id,company_id,branch_id,book_id,logo,print_logo_bool,report_print_company_name,report_print_branch_name,report_print_book_name,bank_details_1,bank_details_2,print_bank_details_1,print_bank_details_2,terms_conditions, transaction_numbering_system)
        VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?)";
        $stmt =  $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, $logo, 0, 1, 1, 1, null, null, 0, 0, null, $default_transaction_numbering_system));


        successreturn(array('book_id' => $book_id, 'successmsg' => "Successfully account book added."));
    } catch (Exception $e) {
        echo "Error : " . $e->getMessage();
    }
} else if ($postdata['function_type'] == "alter_book") {

    if (!isset($postdata['book_id']) or !checkIfIssetAndNotEmpty($postdata['book_id'])) {
        errorreturn('Error in updating the book.');
    } else {
        $book_id = $postdata['book_id'];
    }

    if (
        !isset($postdata['company_id']) or !checkIfIssetAndNotEmpty($postdata['company_id']) or
        !isset($postdata['branch_id']) or !checkIfIssetAndNotEmpty($postdata['branch_id']) or
        !isset($postdata['name']) or  !checkIfIssetAndNotEmpty($postdata['name']) or
        !isset($postdata['book_opening_date']) or !checkIfIssetAndNotEmpty($postdata['book_opening_date']) or
        !isset($postdata['book_closing_date']) or !checkIfIssetAndNotEmpty($postdata['book_closing_date']) or
        !isset($postdata['api_signature']) or !checkIfIssetAndNotEmpty($postdata['api_signature']) or
        !isset($postdata['financial_year_startdate']) or !checkIfIssetAndNotEmpty($postdata['financial_year_startdate'])
    ) {
        errorreturn("All * fields are required.");
    }

    $branch_id = $postdata['branch_id'];
    $company_id = $postdata['company_id'];
    $name = $postdata['name'];
    $function_code = $postdata['function_type'];
    //also check if the company is being created by a super_admin and admin only, if not throw access not granted error.
    $confirmed_role_user = validatePrimaryAccess($conn, $workspace_id, $role, $userid, ['superadmin', 'admin', null]);
    if (!$confirmed_role_user) {
        errorreturn('Access denied.');
    } else {
        $specific_db_conn = dynamicDbConnection($confirmed_role_user);
        if ($role == null) {
            checkCompanyBranchFunctionAccess($specific_db_conn, $role, $userid, $workspace_id, $company_id, $branch_id, $book_id,  $function_code);
        }
    }
    // validate from branch if existing super admins 
    $res = $specific_db_conn->prepare("SELECT id,company_id,branch_id,workspace_id,name FROM act_books WHERE id != ? and workspace_id =? and company_id = ? and branch_id = ? and name=?");
    $res->execute(array($book_id, $workspace_id, $company_id, $branch_id, $name));
    $result1 = $res->fetchAll();
    if (count($result1) >= 1) {
        errorreturn("Branch Name already exists");
    }
    $company_id = trim($postdata['company_id']);
    $branch_id = trim($postdata['branch_id']);
    $name = trim($postdata['name']);

    //$stock_valuation_mode = strtolower(trim($postdata['stock_valuation_mode'])); // 'fifo /lifo / avgcp' options available
    // validation to check amongst three options

    $book_opening_date = trim(date('Y-m-d', strtotime($postdata['book_opening_date'])));
    $book_closing_date = trim(date('Y-m-d', strtotime($postdata['book_closing_date'])));
    // $financial_year_startdate = trim(date('m-d', strtotime($postdata['financial_year_startdate'])));
    $financial_year_startdate = trim($postdata['financial_year_startdate']);
    // Construct a date string for a fixed year (e.g., 2000) using the financial year start date
    $financial_year = $financial_year_startdate . "-2000";

    // Check if the constructed date is valid
    if (strtotime($financial_year)) {
        // Format the date as 'm-d'
        $financial_year_startdate = date("m-d", strtotime($financial_year));
    } else {
        // Handle the error case
        errorreturn("Invalid financial year start date.");
    }
    //Book Opening Date Y-m-d
    if (!CheckStartDate($book_opening_date)) {
        //eg House Name, Street Name
        errorreturn('Invalid Date Format');
    }

    //Book Opening Date Y-m-d
    if (!CheckStartDate($book_closing_date)) {
        //eg House Name, Street Name
        errorreturn('Invalid Date Format');
    }

    if ($book_opening_date > $book_closing_date) {
        errorreturn('Invalid Date Range');
    }

    $date_pattern = '/^(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/';

    // Check if the input date matches the expected format
    if (!preg_match($date_pattern, $financial_year_startdate)) {
        // Handle invalid date format
        errorreturn('Invalid date format for Financial Year Starts On. Please provide a valid date in the format mm-dd.');
    }

    //check if any transaction exists out of the range of new opening date and new closing date 
    $sql_transaction = "Select count(*) as total  from  act_transactiondata where workspace_id = ? and company_id =? and branch_id =? and book_id =? and (date > ? or date < ?)";
    $stmt_transaction = $specific_db_conn->prepare($sql_transaction);
    $stmt_transaction->execute(array($workspace_id, $company_id, $branch_id, $book_id, $book_closing_date, $book_opening_date));
    $result_transaction = $stmt_transaction->fetchAll();

    if ($result_transaction[0]['total'] >= 1) {
        errorreturn("Unable to update the book. Transactions exist out of the range of the new book opening and book closing date.");
    }


    // Set the isolation level to READ COMMITTED
    $specific_db_conn->exec("SET TRANSACTION ISOLATION LEVEL READ COMMITTED");

    // Begin a transaction
    $specific_db_conn->beginTransaction();
    try {
        $sql = "Select book_opening_date, book_closing_date, financial_year_startdate  from act_books where id = ? and  workspace_id = ? and company_id =? and branch_id =?";
        $stmt_book = $specific_db_conn->prepare($sql);
        $stmt_book->execute(array($book_id, $workspace_id, $company_id, $branch_id));
        $result_book = $stmt_book->fetchAll();

        if (count($result_book) >= 1) {
            $existing_book_openingdate = $result_book[0]['book_opening_date'];
            $existing_financial_year_startdate = $result_book[0]['financial_year_startdate'];

            if ($book_opening_date != $existing_book_openingdate) {
                // need to create new opening ledger balance entries

                // allowed for no transactions to be deleted only

                $sql_insert_ledgerbalance = "INSERT IGNORE INTO act_ledgerbalances(workspace_id,company_id,branch_id,book_id,ledgerid,date,closing_balance,main_ledgerhead,parent_ledgerhead, uid)
                     VALUES(?,?,?,?,?,?,?,?,?, ?)";
                $insert_act_ledgerbalances = $specific_db_conn->prepare($sql_insert_ledgerbalance);



                $sql = "SELECT id, ledger_opening_bal, ledger_main_ledgerhead, ledger_parent_group from act_ledgerdetails where workspace_id = ? and company_id = ? and branch_id = ? and book_id = ?";
                $fetch = $specific_db_conn->prepare($sql);
                $fetch->execute(array($workspace_id, $company_id, $branch_id, $book_id));
                $result = $fetch->fetchAll();
                foreach ($result as $temp_ledgers) {
                    $uid = $book_opening_date . "_" . $temp_ledgers['id'];

                    $insert_act_ledgerbalances->execute(array($workspace_id, $company_id, $branch_id, $book_id, $temp_ledgers['id'], $book_opening_date, $temp_ledgers['ledger_opening_bal'], $temp_ledgers['ledger_main_ledgerhead'], $temp_ledgers['ledger_parent_group'], $uid));
                }

                $sql_delete = "DELETE from act_ledgerbalances where workspace_id = ? and company_id = ? and branch_id = ? and book_id = ? and date = ?";
                $delete_ledgerbalances = $specific_db_conn->prepare($sql_delete);
                $delete_ledgerbalances->execute(array($workspace_id, $company_id, $branch_id, $book_id, $existing_book_openingdate));
            }
        } else {
            $specific_db_conn->rollBack();
            errorreturn('Book not found.');
        }

        $sql = "UPDATE act_books SET company_id=?, branch_id=?, name=?,book_opening_date=?,book_closing_date=?,financial_year_startdate = ? WHERE id=? and workspace_id  =?";
        $specific_db_conn->prepare($sql)->execute(array($company_id, $branch_id, $name, $book_opening_date, $book_closing_date, $financial_year_startdate, $book_id, $workspace_id));

        if ($financial_year_startdate != $existing_financial_year_startdate) {
            $sql = "Select prefix_financial_year, transaction_numbering_system from act_book_settings where workspace_id = ? and company_id = ? and branch_id = ? and book_id = ?";
            $fetch_financial_year = $specific_db_conn->prepare($sql);
            $fetch_financial_year->execute(array($workspace_id, $company_id, $branch_id, $book_id));
            $result_financial_year = $fetch_financial_year->fetchAll();
            $financial_year_bool = $result_financial_year[0]['prefix_financial_year'];
            $transaction_numbering_system = json_decode($result_financial_year[0]['transaction_numbering_system'], true);

            if ($financial_year_bool == 1 and count($transaction_numbering_system['automatic']) > 0) {
                // calculate new financial years and then renumber transactions
                // set financial year for all transactions
                foreach ($transaction_numbering_system['automatic'] as $transactiontype) {
                    if (!updateFinancialYearTransactions($specific_db_conn, $workspace_id, $company_id, $branch_id, $book_id, $transactiontype)) {
                        $specific_db_conn->rollBack();
                        errorreturn('Error in updating transaction settings.');
                    }

                    if (!renumberAutomaticTransaction($specific_db_conn, $workspace_id, $company_id, $branch_id, $book_id, $transactiontype)) {
                        $specific_db_conn->rollBack();
                        errorreturn('Error in updating transaction settings.');
                    }
                }
            }
        }
        
        
        //This curl api is link with learning and if book data and closing date update in this book then update learning branch if exists then
        // $book_update_data = array("workspace_id"=>$workspace_id,"book_id"=>$book_id,"company_id"=>$company_id,"branch_id"=>$branch_id,"book_opening_date"=>$book_opening_date,
        // "book_closing_date"=>$book_closing_date,"function_type"=>"alter_book_learning_branch");
        
        // curlUpdateLearningBranchBook($book_update_data);
        

        $specific_db_conn->commit();

        successreturn("Updated accounts book successfully");
    } catch (Exception $e) {
        $specific_db_conn->rollBack();
        errorreturn('Error : ' . $e->getMessage());
    }
} else if ($postdata['function_type'] == "unlock_account") {


    if (
        !isset($postdata['book_id']) or !checkIfIssetAndNotEmpty($postdata['book_id']) or !isset($postdata['branch_id']) or !checkIfIssetAndNotEmpty($postdata['branch_id']) or
        !isset($postdata['company_id']) or !checkIfIssetAndNotEmpty($postdata['company_id'])
    ) {
        errorreturn("All fields are required.");
    }

    // used to alter book lock status
    $id = $postdata['book_id'];
    $branch_id = $postdata['branch_id'];
    $company_id = $postdata['company_id'];

    $function_code = $postdata['function_type'];
    //also check if the company is being created by a super_admin and admin only, if not throw access not granted error.
    $confirmed_role_user = validatePrimaryAccess($conn, $workspace_id, $company_id, $branch_id, null, $role, $userid, $function_code);
    if (!$confirmed_role_user) {
        errorreturn('Access denied.');
    } else {
        $specific_db_conn = dynamicDbConnection($confirmed_role_user);
    }

    //  $lock_status = $postdata['lock_status'];
    $res = $specific_db_conn->prepare("SELECT id,company_id,workspace_id,company_id,branch_id,lock_status FROM act_books WHERE id = ? and workspace_id =? and company_id = ? and branch_id =?");
    $res->execute(array($id, $workspace_id, $company_id, $branch_id));
    $result1 = $res->fetch();
    $lockstatus = $result1['lock_status'];
    //echo $lock_status;die();

    if ($lockstatus == '1') {
        $lock_status = '0';
        $sql = "UPDATE act_books SET lock_status=?  WHERE id=?  and workspace_id= ? and company_id=?";
        $specific_db_conn->prepare($sql)->execute(array($lock_status, $id, $workspace_id, $company_id));
    } else if ($lockstatus == '0') {
        $lock_status = '1';
        $sql = "UPDATE act_books SET lock_status=?  WHERE id = ?  and workspace_id =? and company_id=?";
        $specific_db_conn->prepare($sql)->execute(array($lock_status, $id, $workspace_id, $company_id,));
    }
    successreturn("Account status updated Successfully");
}
