<?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/reports/net_group_summary/bs_group_summary/bs_group_summary.php";
require_once $base_path . 'modules/accounting/book_management/basic_book_info_function.php';
require_once $base_path . "modules/accounting/groups_ledgers/functions/ledger_functions.php";
require_once $base_path . 'modules/accounting/functions/basic_balance_function.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['company_id']) or !checkIfIssetAndNotEmpty($postdata['company_id']) or  !isset($postdata['branch_id']) or !checkIfIssetAndNotEmpty($postdata['branch_id']) or
    !isset($postdata['book_id']) or !checkIfIssetAndNotEmpty($postdata['book_id']) 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;
//print_r($workspace_id);die();
$role = $jwt_validate->data->role;
$username = $jwt_validate->data->username;

function reverseSigns($data, $reverse_total_closing_bool = true)
{
    // print_r($data);
    // die();
    foreach ($data['data'] as &$entry) {
        if (isset($entry['net_closing_balance']) and !empty($entry['net_closing_balance'])) {
            $entry['net_closing_balance'] = floatval($entry['net_closing_balance']) * -1;
        }
    }
    if ($reverse_total_closing_bool == true and !empty($data['total_closing'])) {
        $data['total_closing'] = floatval($data['total_closing']) * -1;
    }
    return $data;
}

if ($postdata['function_type']  == "balancesheet") {

    // receiving input variable
    {
        $company_id = trim($postdata['company_id']);
        $branch_id = trim($postdata['branch_id']);
        $book_id = trim($postdata['book_id']);

        $function_code = $postdata['function_type'];
        $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_info = GetBasicBook($specific_db_conn, $workspace_id, $company_id, $branch_id, $book_id);
        $book_opening_date = $book_info['book_basic_info']['book_opening_date'];
        $book_closing_date = $book_info['book_basic_info']['book_closing_date'];



        $export_type = (isset($postdata['export_type']) and !empty($postdata['export_type'])) ? trim($postdata['export_type']) : null;


        if (isset($postdata['mindate']) and !empty($postdata['mindate']) and isset($postdata['maxdate']) and !empty($postdata['maxdate']) and strtotime($postdata['mindate']) and strtotime($postdata['maxdate'])) {
            $mindate = trim($postdata['mindate']);
            $maxdate = trim($postdata['maxdate']);
        } else errorreturn('Kindly enter valid dates.');

        if (isset($postdata['valuation_method'])) {
            $valuation_method = $postdata['valuation_method'];
            if (!in_array($valuation_method, ['FIFO', 'LIFO', 'AVG_CP'])) {
                $valuation_method = 'FIFO';
            }
        } else {
            $valuation_method = 'AVG_CP';
        }
    }

    require_once './bs_groups_structure.php';

    /*
    create two array named liabilties_data, assets_data
    foreach bs_group
    -- create a temp array for the group, initialised for every iteration
    -- get netGroupSummary of Each Children and place all of them under the temp array for the group
    -- if total of all total_closing for each item in the temp array is positive it means debit, else credit
    -- compare dr or cr with the default key of the current bs_group, if it is dr and default is positive
    */

    $assets = [];
    $liabilities = [];
    $assets_total = 0.00;
    $liabilities_total = 0.00;
    $totalSum = 0.00;

    // closing stock calculation
    {
        // include valuation_method file
        if ($valuation_method == 'FIFO') {
            require_once '../valuation_methods/closing_stock_summary/fifo_summary_function.php';
            $stock_object = getFifoSummaryClosingStock($specific_db_conn, $mindate, $maxdate, $workspace_id, $company_id, $branch_id, $book_id);
        } else if ($valuation_method == 'LIFO') {
            require_once '../valuation_methods/closing_stock_summary/lifo_summary_function.php';
            $stock_object = getFifoSummaryClosingStock($specific_db_conn, $mindate, $maxdate, $workspace_id, $company_id, $branch_id, $book_id);
        } else if ($valuation_method == 'AVG_CP') {
            require_once '../valuation_methods/closing_stock_summary/avg_cp_summary_function.php';
            $stock_object = getAvgCpSummaryClosingStock($specific_db_conn, $mindate, $maxdate, $workspace_id, $company_id, $branch_id, $book_id);
        }

        if ($stock_object['status'] == 1) {
            $closing_stock = $stock_object['closing_stock'];
            $opening_stock = $stock_object['opening_stock'];
        } else {
            errorreturn('Error in calculating stock valuation.');
        }
    }

    // calculating profit and loss
    {
        // status of profit & loss
        #1. // get the opening balance from profit loss ledger
        // get the opening_stock, closing_stock from the net_valuation_reports on the basis of the valuation method asked
        // get the total of (income ledgers + closing_stock), and (expense ledgers + opening_stock)
        // sum (income and expense ledgers)
        #2. // if the result is negative, then it is profit
        #2. // if the result is positive, then it is loss

        // add them into a group like above groups, named as Profit & Loss
        // it will have two child data , Opening balance : #1. , Current Period : #2.
        // If the sum of these two is negative it stays on the liability side otherwise on the asset side
        $pl_ledgerheads = [
            'Income (Direct)', 'Income (Indirect)', 'Expenses (Direct)', 'Expenses (Indirect)', 'Indirect Expenses', 'Purchase Account', 'Sales Account', 'Direct Expenses'
        ];

        // Create a comma-separated list of categories for the SQL query
        $pl_ledgerheads = "'" . implode("', '", $pl_ledgerheads) . "'";

        // total dr means loss cr means profit
        $prev_pl_balance = 0;
        $current_period_pl = 0;

        // fetch profit and loss account for last period
        $sql = "SELECT COALESCE(sum(ledger_opening_bal), 0.00) as total_opening_bal FROM act_ledgerdetails WHERE workspace_id = ? and company_id = ? and branch_id = ? and book_id = ? and ledger_main_ledgerhead = ? ";
        $stmt = $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, 'Profit & Loss Account'));
        $prev_pl_balance = $stmt->fetchAll()[0]['total_opening_bal'];

        if ($mindate == $book_opening_date) {
            // write a query that sums all total_opening_bal of the ledgerheads (Income, Expense, Purchase, Sales)
            $sql = "SELECT SUM(ledger_opening_bal) AS total_sum FROM act_ledgerdetails WHERE workspace_id  =? and company_id =? and branch_id =? and book_id =?  and ledger_main_ledgerhead IN ($pl_ledgerheads)";
            $stmt = $specific_db_conn->prepare($sql);
            $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id));
            $current_period_pl = $stmt->fetchAll()[0]['total_sum'];
        } else {
            $current_period_pl = 0;
        }

        // getting their current sums by adding the transactions as dr and cr
        $sql = "SELECT sum(amount) as total, balancetype FROM act_transactionrecord WHERE workspace_id = ? and company_id = ? and branch_id = ? and book_id = ? and
        date >= ? and date <= ? and main_ledgerhead IN ($pl_ledgerheads) group by balancetype";
        $stmt = $specific_db_conn->prepare($sql);
        $stmt->execute(array($workspace_id, $company_id, $branch_id, $book_id, $mindate, $maxdate));
        foreach ($stmt->fetchAll() as $temp_pl) {
            if ($temp_pl['balancetype'] == 'dr') {
                $current_period_pl += floatval($temp_pl['total']);
            } else {
                $current_period_pl -= floatval($temp_pl['total']);
            }
        }

        //  adding opening and deducting closing to find current year profit / loss
        $current_period_pl += $opening_stock;
        if ($closing_stock >= 0) {
            // deduct
            $current_period_pl -= $closing_stock;
        } else {
            // add
            $current_period_pl += $closing_stock;
        }

        $net_pl_balance = $current_period_pl + $prev_pl_balance;

        if ($net_pl_balance >= 0) {
            // loss
            // going to assets
            $children_summary = [];
            if ($prev_pl_balance > 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => ($prev_pl_balance));
            } else if ($prev_pl_balance < 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => $prev_pl_balance);
            }
            if ($current_period_pl > 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => ($current_period_pl));
            } else if ($current_period_pl < 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => $current_period_pl);
            }

            $assets[] = array('bs_group_name' => 'Profit & Loss Account', 'data' => $children_summary, 'total_closing' => abs($net_pl_balance), 'type' => 'pl_account', 'clickable' => true);
            $assets_total += abs($net_pl_balance);
        } else {
            // profit
            // going to liabilities
            $children_summary = [];
            if ($prev_pl_balance > 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => - ($prev_pl_balance));
            } else if ($prev_pl_balance < 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => abs($prev_pl_balance));
            }
            if ($current_period_pl > 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => - ($current_period_pl));
            } else if ($current_period_pl < 0) {
                $children_summary[] = array('type' => 'ledger', 'clickable' => false, 'name' => 'Opening balance', 'net_closing_balance' => abs($current_period_pl));
            }

            $liabilities[] = array('bs_group_name' => 'Profit & Loss Account', 'data' => $children_summary, 'total_closing' => abs($net_pl_balance), 'type' => 'pl_account', 'clickable' => true);
            $liabilities_total += abs($net_pl_balance);
        }
    }

    // getting other groups
    foreach ($default_bs_groups as $temp_bs_groups) {
        $bs_group_name = $temp_bs_groups['bs_group_name'];
        $default = $temp_bs_groups['default'];
        $bs_group_data_specific = [];
        $bs_group_specific_sum = 0.00;

        // getting bs group summary
        require_once $base_path . "modules/accounting/reports/net_group_summary/bs_group_summary/bs_group_summary.php";
        $bs_group_data_specific = getBSGroupSummary($specific_db_conn, $workspace_id, $company_id, $branch_id, $book_id, $maxdate, $bs_group_name);


        // exception to be added in case of assets, you will also send the closing stocck with it
        if ($bs_group_name == 'Current Assets') {
            if ($closing_stock != 0) {
                $bs_group_data_specific['data'][] = [
                    "type" => "closing_stock",
                    "clickable" => false,
                    "name" => "Closing Stock",
                    "net_closing_balance" => $closing_stock
                ];
                $bs_group_data_specific['total_closing'] += $closing_stock;
            }
        }

        if ($bs_group_data_specific['total_closing'] == 0 and count($bs_group_data_specific['data']) <= 0) {
            continue;
        }

        // putting into the right assets / liabilities array
        if ($bs_group_data_specific['total_closing'] > 0 and $default == 'dr') { // should come as positive
            // put into assets
            $assets[] = $bs_group_data_specific;
            $assets_total += abs($bs_group_data_specific['total_closing']);
        } else if ($bs_group_data_specific['total_closing'] > 0 and $default != 'dr') { // should come as positive
            // put into assets
            $assets[] = $bs_group_data_specific;
            $assets_total += abs($bs_group_data_specific['total_closing']);
        } else if ($bs_group_data_specific['total_closing'] < 0 and $default == 'cr') { // should come as negative
            // reverse the signs and put into liabiltiies
            $liabilities[] = reverseSigns($bs_group_data_specific);
            $liabilities_total += abs($bs_group_data_specific['total_closing']);
        } else if ($bs_group_data_specific['total_closing'] < 0 and $default != 'cr') {
            // should come as negative
            // reverse the signs put into liabilities
            $liabilities[] = reverseSigns($bs_group_data_specific);
            $liabilities_total += abs($bs_group_data_specific['total_closing']);
        } else if ($bs_group_data_specific['total_closing'] == 0 and $default == 'cr') {
            // reverse the signs put into assets
            $liabilties[] = reverseSigns($bs_group_data_specific);
            $liabilities_total += abs($bs_group_data_specific['total_closing']);
        } else if ($bs_group_data_specific['total_closing'] == 0 and $default == 'dr') {
            // put into assets
            $assets[] = $bs_group_data_specific;
            $assets_total += abs($bs_group_data_specific['total_closing']);
        }
    }

    if (abs($liabilities_total) > abs($assets_total)) {
        $assets[] = array(
            "bs_group_name" => "Difference In Opening Balance",
            "data" => [],
            "total_closing" => abs($liabilities_total) - abs($assets_total),
            "clickable" => false,
        );
        $assets_total += (abs($liabilities_total) - abs($assets_total));
    } else if (abs($assets_total) > abs($liabilities_total)) {
        $liabilities[] = array(
            "bs_group_name" => "Difference In Opening Balance",
            "data" => [],
            "total_closing" => abs($assets_total) - abs($liabilities_total),
            "clickable" => false,
        );
        $liabilities_total += (abs($assets_total) - abs($liabilities_total));
    }

    // then after sum of all assets and liabilities groups, the difference is calculated by deducting
    // the smaller closing balance on either side from the greater one/
    // it is the difference in opening balance. and displayed on the lesser side as non clickable and expandable to make the sides equal

    if ($export_type == null) {

        successreturn(array('assets' => $assets, 'liabilities' => $liabilities, 'assets_total' => $assets_total, 'liabilities_total' => $liabilities_total));
    } else {
        if (isset($export_type)) { // true // value check should either be spreadsheet pdf 
            if ($export_type == 'pdf') {

                require_once $base_path . 'modules/accounting/reports/export/manage_balancesheet/pdf/export_manage_transactions_table_pdf.php';
            } else  if ($export_type == 'print') {

                require_once $base_path . 'modules/accounting/reports/export/manage_balancesheet/print/export_manage_transactions_table_print.php';
            }
        }
    }
} else {
    errorreturn('group name is not exists in leadgerheads basics');
}
