<?php

/**
 * Controller used to perfom actions on Sales and related tables
 *
 * 
 *
 * @author Mario Vallejo <wappsi.desarrollomovil01@gmail.com>
 */

namespace App\Controllers;

//
//

use App\Models\SmaCompaniesModel;
use App\Validation\SalesValidation;
use Config\Services;
use CodeIgniter\RESTful\ResourceController;

class Sales extends ResourceController
{
    public function index()
    {
        //
    }


    /**
     * Creates a sale for a given data on post request
     * 
     * Request type: POST
     * Request validation rules can be viewed on
     * 
     * @filesource App\Validation\SalesValidation::newSaleRules()
     * @filesource App\Validation\SalesValidation::newSaleMessages()
     *
     * @return httpResponse
     */
    function new()
    {
        $this->setModel(new SmaCompaniesModel($this->dbGroupFromRequest()));

        // print_r($this->request->getJSON());

        $rules = SalesValidation::newSaleRules();

        $message = SalesValidation::newSaleMessages();

        if (!$this->validate($rules, $message)) {

            // if validation fails

            $response = [
                'status' => 400,
                'error' => true,
                'message' => $this->validator->getErrors(),
                'data' => [],
            ];

            return $this->respondCreated($response);
        } else {
            $sale = $this->request->getJSON(true);
            // print_r($this->checkSale($sale));
            $syncValidation = $this->checkSale($sale);

            // print_r($syncValidation);
            if (
                $syncValidation['sma_warehouses_products'] == false && ($syncValidation['sma_products']) == false
                && ($syncValidation['sma_product_prices']) == false && ($syncValidation['sma_companies']) == false
                && ($syncValidation['sma_units']) == false && ($syncValidation['sma_unit_prices']) == false
            ) {
                $sale['from_app'] = true;

                $sale[csrf_token()] = csrf_hash();

                // print_r($sale);

                // to get wappsi endPoint to sales
                helper('jwt');
                $authHeader = $this->request->getServer('HTTP_AUTHORIZATION');
                $token = getJWTFromRequest($authHeader);
                $company_url = companyURLFromJWT($token);
                // $company_url = "https://wappsi281.com/dulcelandia_2/";
                $wappsi_web_endp = Services::getWappsiWebSalesEndpoint();

                ///TODO: Remove this step
                // $defaultSaleCurrency = SmaCurrencies::getDefaultCurrency($this->dbGroupFromRequest());

                $sale['sale_currency'] = 'COP';

                //build url
                $url = Services::buildURL($company_url, $wappsi_web_endp);
                $regSale = $this->httpPostXform($url, $sale);

                $regSale = $this->renameKey(json_decode($regSale), "\"", '');


                if (isset($regSale['error'])) {
                    $regSale['error'] == 1 ? $regSale['error'] = true : $regSale['error'] = false;
                } else {
                    $regSale['error'] = true;
                }
                if ($regSale['error'] == true) {
                    // log error 
                    log_message('critical', json_encode($regSale));
                }

                $regSale['fe_print_footer'] = AppSettings::getStaticFooterPrint($this->dbGroupFromRequest());

                try {
                    if ($regSale['error'] ?? true) {
                        $response = [
                            'status' => 401,
                            'error' => true,
                            'sync' => false,
                            'message' => $regSale['message'] ?? "Ha ocurrido un error al registrar la venta en erp.",
                            'data' => $regSale,
                            'endpoint_erp' => $url,
                            'data_sent' => ($sale),
                        ];
                    } else {
                        $response = [
                            'status' => 201,
                            'error' => false,
                            'current_server_date' => $this->getServerDateTime(),
                            'sync' => false,
                            'message' => $regSale['message'],
                            'data' => $regSale,
                        ];
                    }
                } catch (\Throwable $th) {
                    $response = [
                        'status' => 401,
                        'error' => true,
                        'sync' => false,
                        'message' => 'Error en el registro de la venta',
                        'error_message' => "$th",
                        'data' => $regSale,
                    ];
                }

                // $response = $regSale;

                return $this->respondCreated($response);
            } else {
                $response = [
                    'status' => 401,
                    'error' => true,
                    'sync' => true,
                    'message' => 'Detalles de productos no sincronizados con el servidor, sincronizando',
                    'data' => $syncValidation,
                ];

                return $this->respondCreated($response);
            }
        }
    }

    /**
     * Checks sale data
     * 
     * Verify if overselling is allowed in settings (sma_settings), if it's allowed return [],
     * if not return array of changes that could be empty.
     *
     *
     * @param array  $sale  Sale data to verify
     *
     * @return array|[]
     */
    public function checkSale($sale)
    {
        // return [
        //     'sma_warehouses_products' => false, 'sma_product_prices' => false,
        //     "sma_products" => false, "sma_companies" => false, 'sma_units' => false, 'sma_unit_prices' => false,
        // ];
        // print_r('here');

        $result = SmaSettings::getSettingsColumnData('overselling', $this->dbGroupFromRequest());
        if ($result == 0) {
            return $this->verifyProductsDetails($sale, true, $this->dbGroupFromRequest());
        } else {
            return $this->verifyProductsDetails($sale, false, $this->dbGroupFromRequest());
        }
    }

    /**
     * Verify product data from sale
     * 
     * Returns list of arrays, ['sma_warehouses_products'] is sma_warehouses_products,
     * ['sma_product_prices'] are sma_product_prices and ['sma_products']
     * is sma_products, only return values if there is some irregularity
     *
     * @param array  $sale  Sale data to verify
     *
     * @param boolean  $verifyQuantities  To specify if quantity verification (inventory) is required
     *
     * @return array|[] Array containing table names were changes where found
     */
    public function verifyProductsDetails($sale, $verifyQuantities = true, String $dbGroup)
    {
        $pricePolicy = SmaSettings::getSettingsColumnData('prioridad_precios_producto', $dbGroup);
        $customer = SmaCompanies::getCompaniesData($sale['customer'], $dbGroup);

        // $billerPId   = $this->
        $sync = [
            'sma_warehouses_products' => false, 'sma_product_prices' => false,
            "sma_products" => false, "sma_companies" => false, 'sma_units' => false, 'sma_unit_prices' => false
        ];
        // print_r(($sync['sma_warehouses_products']==false)?1:0);
        foreach ($sale['product_id'] as $key => $value) {
            if ($verifyQuantities) {
                $sync['sma_warehouses_products'] = SmaWarehousesProducts::verifyProductsQuantities(
                    $value,
                    $sale['quantity'][$key],
                    $sale['warehouse'],
                    $dbGroup,
                );
            }

            // If sale requires to verify prices
            if ($sale["verify_prices"] == 1) {
                if ($pricePolicy == 6) {
                    $billerPId = SmaBillerData::getBillerData($sale['biller'], 'default_price_group', $dbGroup);
                    $cAddressPId = SmaAddresses::getAddressesData($sale['address_id'], 'price_group_id', $dbGroup);
                    if (($customer['price_group_id'] == $sale['customer_price_group_id']) &&
                        $customer['customer_group_id'] == $sale['customer_group_id']
                    ) {
                        $temp = $this->verifyProductsPrices(
                            $value,
                            $sale['real_unit_price'][$key],
                            $sale['unit_price'][$key],
                            $customer['price_group_id'],
                            $billerPId,
                            $cAddressPId,
                            null,
                            $pricePolicy,
                            $dbGroup,
                        );
                        if ($temp['sma_product_prices']) {

                            $sync['sma_product_prices'] = $temp['sma_product_prices'];
                        }
                        if ($temp['sma_products']) {

                            $sync['sma_products'] = $temp['sma_products'];
                        }
                    } else {
                        $sync['sma_companies'] = true;
                    }
                } else if ($pricePolicy == 10) {
                    // print_r($value);
                    $temp = $this->verifyProductsPrices(
                        $value,
                        $sale['real_unit_price'][$key],
                        $sale['unit_price'][$key],
                        null,
                        null,
                        null,
                        $sale['product_unit_id_selected'][$key] ?? null,
                        $pricePolicy,
                        $dbGroup,
                    );
                    // $sync['sma_product_prices'] = $temp['sma_product_prices'];
                    // print_r($temp['sma_products']==true?1:0);
                    if ($temp['sma_products']) {

                        $sync['sma_products'] = $temp['sma_products'];
                    }
                    if ($temp['sma_units']) {

                        $sync['sma_units'] = $temp['sma_units'];
                    }
                    if ($temp['sma_unit_prices']) {

                        $sync['sma_unit_prices'] = $temp['sma_unit_prices'];
                    }
                }
            }
        }

        return $sync;
    }


    /**
     * Verify product prices 
     * 
     * Returns array from sma_price_products where base price of given product
     * in sale is difererent based on sma_prioridad_precios_producto.
     *
     * @param int $product  product_id
     * @param double $productPrice  
     * @param double $realProductPrice
     * @param int $customerPGId Customer price group id
     * @param int $billerPId    Biller Id
     * @param int $cAddressPId  Customer address price_group_id
     * @param int $pricePolicy  Price policy param from settings
     *
     * @return array
     */
    public function verifyProductsPrices($product, $realProductPrice, $productPrice = 0, $customerPGId, $billerPId, $cAddressPId, $unit_id, $pricePolicy, String $dbGroup)
    {
        $resp = ['sma_products' => false, "sma_product_prices" => false, 'sma_units' => false, 'sma_unit_prices' => false];

        if ($pricePolicy == 6) {
            $productPromo = SmaProducts::getProductPromo($product, $dbGroup);
            if ($productPromo == null) {
                $pResp = SmaProductPrices::getProductPrices($product, $customerPGId, $dbGroup);
                if ($pResp == null) {
                    $pResp = SmaProductPrices::getProductPrices($product, $billerPId, $dbGroup);
                    if ($pResp != null) {

                        if ($pResp['price'] != $realProductPrice) {
                            $resp['sma_product_prices'] = true;
                            /// force sma_products to be sync
                            $resp['sma_products'] = true;
                        }
                    } else {
                        $pResp = SmaProductPrices::getProductPrices($product, $cAddressPId, $dbGroup);
                        if (!empty($pResp)) {
                            if ($pResp['price'] != $realProductPrice) {
                                $resp['sma_product_prices'] = true;
                                /// force sma_products to be sync
                                $resp['sma_products'] = true;
                            }
                        }
                    }
                } else {

                    if ($pResp['price'] != $realProductPrice) {
                        $resp['sma_product_prices'] = true;
                        /// force sma_products to be sync
                        $resp['sma_products'] = true;
                    }
                }
            } else {

                if ($productPromo['tax_method'] == 0) {
                    if ($productPrice != $productPromo['promo_price']) {
                        $resp['sma_products'] = true;
                    }
                } else {

                    if ($productPrice != $productPromo['promo_price']) {
                        $resp['sma_products'] = true;
                    }
                }
                // if($sale[})
            }
        } else if ($pricePolicy == 10) {
            $pResp = SmaUnitPrices::getUnitPrices($product, $customerPGId, $unit_id, $dbGroup);
            if (!empty($pResp)) {
                $pPrice = $pResp['valor_unitario'] / ($pResp['operation_value'] ?? 1);
                if ($realProductPrice != $pPrice) {

                    $resp['sma_unit_prices'] = true;
                    // $resp['sma_products']=true;
                }
            } else {
                $pResp = SmaUnitPrices::getDefaultUnitPrices($product, $unit_id, $dbGroup);
                if (!empty($pResp)) {
                    $pPrice = $pResp['valor_unitario'] / ($pResp['operation_value'] ?? 1);
                    // print_r($pResp['valor_unitario']/($pResp['operation_value']??1));
                    if ($realProductPrice != $pPrice) {

                        // $resp['sma_unit_prices']=true;
                        $resp['sma_products'] = true;
                    }
                } else {
                    // $pResp = SmaUnitPrices::getDefaultUnitPrices($product, $unit_id);
                    $resp['sma_units'] = true;
                }
            }
        }

        return $resp;
    }
}
