<?php

/**
 * purchases table's controller.
 *
 * Used to perform operations on purchases table.
 *
 * @author Mario Vallejo <wappsi.desarrollomovil01@gmail.com>
 */

namespace App\Controllers;

use App\Models\SmaPurchasesModel;
use App\Validation\SmaPurchasesValidations;
use CodeIgniter\RESTful\ResourceController;

class SmaPurchases extends ResourceController
{
    /**
     * Get updated purchases table's rows.
     *
     * Based on last_sync value (from request), return updated rows from purchases.
     *
     * Request should contain last_sync value (date) to get updated rows based on
     * that date.
     *
     * If request contains first_time = true, it returns all data in table.
     *
     * Validation rules and messages are taken from SmaPurchasesValidations file.
     *
     * @filesource App/Validation/SmaPurchasesValidations
     *
     * @return HttpResponse
     */
    public function sync()
    {

        $this->setModel(new SmaPurchasesModel($this->dbGroupFromRequest()));
        $rules = SmaPurchasesValidations::getSyncRules();

        $message = SmaPurchasesValidations::getSyncMessages();
        if (!$this->validate($rules, $message)) {

            // if validation fails

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

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

            // validate
            $purchase = [];
            $purchaseItems = [];

            $authHeader = $this->request->getServer('HTTP_AUTHORIZATION');
            $token = getJWTFromRequest($authHeader);
            $view_right = viewRightFromJWT($token);

            $filter_to_all = [];
            $filter_to_update = null;

            if ($view_right == 0) {
                $uId = userIdFromJWT($authHeader);
                $filter_to_all['created_by'] = $uId;
                $filter_to_update = ['created_by' => $uId];
                // print_r($filter_to_all);
            }

            if (($this->request->getVar('first_time') ?? false) == true) {

                $purchase = $this->getAllRows(['id' => 'id_cloud'], $filter_to_all);
            } else if (($this->request->getVar('first_time') ?? false) == false) {

                $purchase = $this->getUpdatedRows(['id' => 'id_cloud'], $filter_to_update,'updated_at');
            } else {
                $response = [
                    'status' => 400,
                    'error' => true,
                    'message' => 'EL campo "first_time" no es valido',
                    'data' => [],
                ];

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

            // now get orderItems
            for ($i = 0; $i < count($purchase); $i++) {
                $items = SmaPurchaseItems::getPurchaseItems($purchase[$i]['id_cloud'], $this->dbGroupFromRequest());
                array_push($purchaseItems, $items);
            }

            $response = [
                'status' => 200,
                'error' => false,
                'message' => 'Exito',
                'server_date_time' => $this->getServerDateTime(),
                'data' => [
                    'sma_purchases' => $purchase,
                    'sma_purchase_items' => $purchaseItems,

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

    /**
     * Create a new purchase.
     *
     * Given purchase and purchase_items on request, create a new purchase and it's items.
     * 
     * 
     * Validation rules and messages are taken from SmaPurchasesValidations file.
     *
     * @filesource App/Validation/SmaPurchasesValidations
     *
     * @return  
     */
    function new()
    {
        $rules = SmaPurchasesValidations::newRules();
        $message = SmaPurchasesValidations::newMessages();

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

            // if validation fails

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

            return $this->respondCreated($response);
        } else {
            $purchaseData = ($this->request->getJsonVar("purchase", true) ?? null);
            // validate if purchase info is in request

            $response = [];

            if ($purchaseData != null) {
                // get order items data
                $purchaseItemsData = ($this->request->getJsonVar("purchase_items", true));

                //insert order data into purchase model

                $this->setModel(new SmaPurchasesModel($this->dbGroupFromRequest()));

                $ref_no = null;

                try {

                    $ref_no = $this->getUniqueRefNo(
                        $purchaseData['reference_no'],
                        $purchaseData['supplier_id'],
                        $purchaseData['document_type_id'],
                        $this->dbGroupFromRequest(),
                    );

                    // print_r($purchaseItemsData);
                    if ($ref_no != null && $ref_no != false) {
                        $purchaseData['reference_no'] = $ref_no;
                        $cons_supp_validation = $this->verifyConsecutiveNo(
                            $purchaseData['consecutive_supplier'],
                            $purchaseData['supplier_id'],
                            $this->dbGroupFromRequest(),
                        );

                        if ($cons_supp_validation) {
                            $purchase_id = $this->model->insert($purchaseData, true);
                            if ($purchase_id ?? false) {
                                // switch to OrderSaleItemModel

                                $result = SmaPurchaseItems::insertPurchaseItems($purchaseItemsData, $purchase_id, $this->dbGroupFromRequest());
                                // check everythings goes nice
                                if ($result != false && $result == count($purchaseItemsData)) {
                                    // send email to notify new order
                                    // EmailController::sendOrderEmail($purchaseData,$purchaseItemsData);
                                    $response = [
                                        'status' => 201,
                                        'error' => false,
                                        'message' => "Compra registrada",
                                        'data' => [
                                            'purchase_id' => $purchase_id,
                                            'reference_no' => $purchaseData['reference_no'],
                                            'server_date' => $this->getServerDateTime(),
                                        ],
                                    ];
                                } else {
                                    //if neeeded we can undo document consecutive
                                    // if(isset($refNo)){
                                    //     SmaDocumentsTypes::undoReferenceNo($purchaseData['document_type_id']);
                                    // }

                                    // set orderSale status to error
                                    // $this->disablepurchase($purchase_id);

                                    $response = [
                                        'status' => 400,
                                        'error' => true,
                                        'message' => "Eror al registrar items de compra",
                                        'data' => [],
                                    ];
                                }
                            }
                        } else {
                            $error_message = empty($purchaseData['consecutive_supplier'])
                                ? 'El consecutivo de proveedor necesario'
                                : 'El consecutivo de proveedor ya en uso';
                            $response = [
                                'status' => 400,
                                'error' => true,
                                'message' => $error_message,
                                'data' => [],
                            ];
                        }
                    } else if ($ref_no == false) {
                        $response = [
                            'status' => 400,
                            'error' => true,
                            'message' => "El numero de referencia de compra ya esta en uso para este proveedor",
                            'data' => [],
                        ];
                    } else {
                        $response = [
                            'status' => 400,
                            'error' => true,
                            'message' => "Ha ocurrido un error al generar el numero de referencia de la compra",
                            'data' => [],
                        ];
                    }
                } catch (\Throwable $th) {

                    // // if orderSales was inserted to db, then set status to error
                    // if($purchase_id??false){
                    //     $this->disablepurchase($purchase_id);
                    // }

                    $response = [
                        'status' => 400,
                        'error' => true,
                        'message' => "Eror al registrar la compra",
                        'error_message' => "$th",
                        'data' => [],
                    ];
                }
            } else {
                $response = [
                    'status' => 400,
                    'error' => true,
                    'message' => "El campo purchase es necesario",
                    'data' => [],
                ];
            }

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

    // /**
    //  * When purchase is need to be disable
    //  *
    //  * @param integer $purchase_id
    //  * @return bool
    //  */
    // static public function disablepurchase($purchase_id){
    //     try {
    //         $orderSModel = new SmaPurchasesModel();
    //         // echo $purchase_id;
    //         $result = $orderSModel->update($purchase_id,['sale_status'=>'error']);
    //         // echo $result?1:0;
    //         return $result;
    //     } catch (\Throwable $th) {
    //         // echo "$th";
    //         return false;
    //     }
    // }

    /**
     * Validate if reference_no on purchase is unique
     *
     * @return HttpResponse
     */
    public function checkReferenceNo()
    {

        $rules = SmaPurchasesValidations::checkReferenceNoRules();
        $this->request;
        $message = SmaPurchasesValidations::checkReferenceNoMessages();
        if (!$this->validate($rules, $message)) {

            // if validation fails

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

            return $this->respondCreated($response);
        } else {
            $this->setModel(new SmaPurchasesModel($this->dbGroupFromRequest()));
            // validate
            $ref_no = $this->request->getVar('reference_no');
            $supplier_id = $this->request->getVar('supplier_id');

            $ref_is_valid = $this->verifyRefNo($ref_no, $supplier_id, $this->dbGroupFromRequest());
            $response = [
                'status' => 200,
                'error' => false,
                'message' => 'Exito',
                'server_date_time' => $this->getServerDateTime(),
                'data' => [
                    'valid_ref' => $ref_is_valid,

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

    /**
     * Verify if reference_no is already in use for a given supplier_id
     *
     * @return bool
     */
    public static function verifyRefNo(String $ref_no, int $supplier_id, $dbGroup)
    {
        $purchasesModel = new SmaPurchasesModel($dbGroup);

        $purchases = $purchasesModel
            ->where(['reference_no' => $ref_no, 'supplier_id' => $supplier_id])
            ->findAll();
        // print_r($purchases);
        if (count($purchases) >= 1) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Validate if consecutive_supplier on pruchase is unique
     *
     * @return HttpResponse
     */
    public function checkConsecutiveNo()
    {

        $rules = SmaPurchasesValidations::checkConsecutiveNoRules();
        $this->request;
        $message = SmaPurchasesValidations::checkConsecutiveNoMessages();
        if (!$this->validate($rules, $message)) {

            // if validation fails

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

            return $this->respondCreated($response);
        } else {
            $this->setModel(new SmaPurchasesModel($this->dbGroupFromRequest()));
            // validate
            $consecutive_no = $this->request->getVar('consecutive_supplier');
            $supplier_id = $this->request->getVar('supplier_id');

            $consecutive_is_valid = $this->verifyConsecutiveNo($consecutive_no, $supplier_id, $this->dbGroupFromRequest(),);
            $response = [
                'status' => 200,
                'error' => false,
                'message' => 'Exito',
                'server_date_time' => $this->getServerDateTime(),
                'data' => [
                    'valid_consecutive' => $consecutive_is_valid,

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

    /**
     * Validation of consecutive_supplier, if needed, inf not it just return true.
     * Verify if consecutive_supplier is already in use for a given supplier_id,
     * @param String|null $consecutive_no
     * @return bool
     */
    public static function verifyConsecutiveNo($consecutive_no, int $supplier_id, $dbGroup)
    {
        $purchasesModel = new SmaPurchasesModel($dbGroup);
        $sup_cons_enabled = SmaSettings::getSettingsColumnData('management_consecutive_suppliers', $dbGroup);
        if ($sup_cons_enabled == 1) {
            if (empty($consecutive_no)) {
                return false;
            } else {
                $purchases = $purchasesModel
                    ->where(['consecutive_supplier' => $consecutive_no, 'supplier_id' => $supplier_id])
                    ->findAll();
                // print_r($purchases);
                if (count($purchases) >= 1) {
                    return false;
                } else {
                    return true;
                }
            }
        } else {
            return true;
        }
    }

    /**
     * Get a unique reference_no for a given supplier. If ref_no!=null, validate if its unique and returns it,
     * if is not unique, generate a new one. If there is some error on generating a reference_no returns null, if ref_no sended
     * is already in use, returns false.
     *
     * @param String | null  $ref_no
     *
     * @return String|bool|null
     */
    public static function getUniqueRefNo($ref_no, int $supplier_id, int $document_type, $dbGroup)
    {
        $ref_no_return = null;
        if (empty($ref_no)) {
            $res = SmaDocumentsTypes::getReferenceNo($document_type, $dbGroup);
            //
            if (isset($res)) {
                $chech_ref_no = SmaPurchases::verifyRefNo($res, $supplier_id, $dbGroup);
                if ($chech_ref_no) {
                    $ref_no_return = $res;
                } else {
                    $ref_no_return = SmaPurchases::getUniqueRefNo(null, $supplier_id, $document_type, $dbGroup);
                }
            }
            // $refNo=0;

        } else {
            $chech_ref_no = SmaPurchases::verifyRefNo($ref_no, $supplier_id, $dbGroup);
            if ($chech_ref_no) {
                $ref_no_return = $ref_no;
            }
        }

        return $ref_no_return;
    }
}
