<?php

namespace App\Controllers\Client;

use App\Controllers\BaseController;
use App\Core\Library\Mailer;
use App\Core\Service\Logger;
use App\Core\Library\Crypto;
use App\Model\MasterModel;
use App\Model\MasterDataSetModel;
use App\Model\MasterDataRulesModel;
use App\Model\OrderModel;
use App\Config\Main;
use App\Model\FxModel;
use App\Service\AttachmentUploader;
use Exception;

class MasterController extends BaseController
{

    private $model;
    private $dataSetModel;
    private $OrderModel;
    private $masterDataRulesModel;
    private $FxModel;

    public function  __construct()
    {
        parent::__construct();
        $this->model = new MasterModel();
        $this->dataSetModel = new MasterDataSetModel();
        $this->OrderModel = new OrderModel();
        $this->masterDataRulesModel = new MasterDataRulesModel();
        $this->FxModel     = new FxModel();
    }

    //   COUPON LIST WHILE GET REC --  ADD MORE 
    public function getBulkCouponList()
    {
        try {
            $id = $this->input['id'];
            $dbname = 'sanordo_clientdb_' . $this->user_data->comp_id;
            $dataArray = $this->model->getBulkCouponData($dbname, "coupon_master_id = $id");
            if (!$dataArray['status'])
                throw new \Exception($dataArray['error']);
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetched successfully', 'data' => $dataArray['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 500, 'message' => 'Internal Server Error', 'data' => null, 'error' => $e->getMessage()));
        }
    }
    //   DROPDOWNS
    public function getDropdownOptions()
    {
        try {
            $dropdown_names_list = $this->input['dropdown_names_list'];
            $where = !empty($this->input['dropdown_filter_list']) ? $this->input['dropdown_filter_list'] : [];

            if (array_search('users', $dropdown_names_list) !== false) {
                if ($this->user_data->master_type != 1) {
                    $urs = $this->FxModel->getChildUsers($this->user_data->id);
                    if (empty($urs['status'])) {
                        throw new \Exception($urs['error']);
                    } else if (!empty($urs['data'])) {
                        if (!empty($where['users'])) {
                            $where['users']['user_id'] = $urs['data']['child_users'];
                        } else {
                            $where['users'] = ['user_id' => $urs['data']['child_users']];
                        }
                    }
                }
            }
            $retData = $this->model->getOptionList($dropdown_names_list, $this->user_data->comp_id, $where);
            if (!$retData['status']) {
                throw new \Exception($retData['error']);
            }

            $this->sendResponse(array('code' => 200, 'message' => 'Data fetched successfully', 'data' => $retData['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   ITEM AUTOCOMPLETE
    public function itemAutoComplete()
    {
        try {
            $master_name = $this->input['master_name'];
            if (empty($master_name)) {
                throw new \Exception('Master name is required');
            }
            $where = ' AND 1 = 1';
            $dbname = 'sanordo_clientdb_' . $this->user_data->comp_id;
            if ($master_name == 'itemList') {
                $keyword = $this->input['keyword'];
                $where = " AND item_name LIKE '%$keyword%'";
                $sql = "SELECT item_id AS id, item_name AS text,rate FROM `$dbname`.`item_master` WHERE status = 1$where";
                $resp = $this->model->fetchAllData($sql);
                if (!$resp['status']) {
                    throw new \Exception($resp['error']);
                }
                $returnData = $resp['data'];
            }
            if ($master_name == 'purchaseItemTaxList') {
                $branch_id = $this->input['branch_id'];
                $vendor_id = $this->input['vendor_id'];
                $taxArray = $this->model->getAllTaxType($dbname, $branch_id, $vendor_id);
                foreach ($this->input['tax_item_ids'] as $key => $item_ids) {
                    $tax_item_id = $item_ids['item_id'];

                    $itemSql = "SELECT i.*,g.group_name,c.hsn_code,c.total_tax FROM `$dbname`.`item_master` i
            LEFT JOIN `$dbname`.`item_group_master` g ON i.group_id = g.id
            LEFT JOIN `$dbname`.`itemcategory_master` c ON i.category_id=c.itemcat_id
            WHERE i.item_id = $tax_item_id ORDER BY i.item_name ASC";
                    $itemResp = $this->model->fetchAllData($itemSql);
                    if (!$itemResp['status']) {
                        throw new \Exception($itemResp['error']);
                    }
                    $dataItem[] = $itemResp['data'][0];
                    $dataTax[] = $this->model->getItemTaxDetail($dbname, "i.item_id = $tax_item_id", $taxArray);
                }
                $flattenedArray = [];
                foreach ($dataTax as $subArray) {
                    foreach ($subArray as $item) {
                        $flattenedArray[] = $item;
                    }
                }
                $returnData = ['taxData' => $flattenedArray, 'itemData' => $dataItem];
            }
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetched successfully', 'data' => $returnData));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   PURCHASE RETURN ITEM LIST
    public function purchaseReturnItemList()
    {
        try {
            $dbPrefix = 'sanordo_clientdb_' . $this->user_data->comp_id;
            $resp = $this->model->getPurchaseReturnItemList($this->input['purchase_id'], $dbPrefix);
            if (!$resp['status'])
                throw new Exception($resp['error']);
            $taxArray = $this->model->getAllTaxType($dbPrefix, $this->input['branch_id'], $this->input['vendor_id']);
            foreach ($resp['data'] as $key => $item_ids) {
                $tax_item_id = $item_ids['item_id'];
                $dataTax[] = $this->model->getItemTaxDetail($dbPrefix, "i.item_id = $tax_item_id", $taxArray);
            }
            $flattenedArray = [];
            foreach ($dataTax as $subArray) {
                foreach ($subArray as $item) {
                    $flattenedArray[] = $item;
                }
            }

            $data = ['itemData' => $resp['data'], 'taxData' => $flattenedArray];
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetch successfully', 'data' => $data));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   INSERT ITEM STOCK
    public function itemStockInsert()
    {
        try {
            $dbname = 'sanordo_clientdb_' . $this->user_data->comp_id;
            $item_id = $this->input['item_id'];
            foreach ($this->input['stockForm'] as $key => $val) {
                $data[] = array('item_id' => $item_id, 'branch_id' => $val['branch_id'], 'opening_stock' => $val['opening_stock'], 'stock_in' => $val['stock_in'], 'stock_out' => $val['stock_out'], 'stock' => $val['stock'], 'rol' => $val['rol']);
            }
            foreach ($data as $key => $value) {
                $branch_id = $value['branch_id'];
                $itemList = $this->model->fetchAllData("SELECT * FROM `$dbname`.`item_stock` WHERE item_id = $item_id AND branch_id = $branch_id");
                if (!$itemList['status']) {
                    throw new \Exception($itemList['error']);
                }
                if (!empty($itemList['data']) && count($itemList['data']) > 0 && $itemList['data'][0]['opening_stock'] > 0) {
                    $db = $this->model->stockOpeningUpdate($value['item_id'], $value['branch_id'], $itemList['data'][0]['opening_stock'], $dbname, 1);
                }

                $db = $this->model->stockOpeningUpdate($value['item_id'], $value['branch_id'], $value['opening_stock'], $dbname, 0);
            }
            if (!$db['status']) {
                throw new \Exception($db['error']);
            }
            if (isset($db['insert_id'])) {
                $msg = $db['insert_id'] . ') inserted by ';
            }
            if (isset($db['affected_rows'])) {
                $msg = $db['affected_rows'] . ') updated by ';
            }
            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => 'Item Stock (Id:' . $msg . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$dbname`.`api_user_logs`", $logData);
            $this->sendResponse(array('code' => 200, 'message' => 'Data Updated Successfully', 'data' => $db));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 500, 'message' => 'Internal Server Error', 'data' => null, 'error' => $e->getMessage()));
        }
    }
    //   INSERT RECORD 
    public function dataInsert()
    {
        try {
            if (empty($this->input['master_name'])) {
                throw new \Exception('Master name is required');
            }
            $master_name = $this->input['master_name'];
            $primaryKey = 'id';
            $rules  = $this->masterDataRulesModel->getMasterTableRules($master_name, 'insert', $this->input);
            $validation = $this->validateReqData($rules, $this->input);
            if (empty($validation['status'])) {
                throw new \Exception($validation['error']);
            }
            if (!$validation['valid']) {
                $this->sendResponse(array('code' => 400, 'message' => $this->getFirstValidationError(), 'data' => $validation['validation_error']));
            }
            $dbData = $this->input;
            $dbData['comp_id'] = $this->user_data->comp_id;
            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;

            if (array_key_exists($master_name, $this->model->tables) == 1) {
                //  GET MASTER CONFIGURATION FROM CONFIG FILE  --  START
                $preProcess = Main::$mastersConfig;
                $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;
                $primaryKey = $preProcess[$master_name]['primaryKey'];
                $dbData['dbname'] = $dbname;
                $dbData['action'] = 'insert';
                $getDbData = $this->dataSetModel->preInsertUpdateGetData($master_name, $dbData);

                if (!$getDbData['status']) {
                    $this->sendResponse(array('code' => 400, 'message' => $getDbData['error']));
                }
                $dbData = $getDbData['dbData'];
                //  GET MASTER CONFIGURATION FROM CONFIG FILE  --  END
            } else {
                throw new \Exception('Table name not exist');
            }

            $DBFields = $this->model->getMasterTableFields("`$dbname`.`$master_name`");

            if (!$DBFields['status']) {
                throw new \Exception($DBFields['error']);
            }
            $fields = $DBFields['fields'];
            $db_keys = (is_array($dbData)) ? array_keys($dbData) : [];
            foreach ($db_keys as $keyName) {
                if (!in_array($keyName, $fields)) {
                    unset($dbData[trim($keyName)]);
                } else {
                    if (array_key_exists($keyName, $dbData)) {
                        if (!empty($dbData[$keyName]) ||  $dbData[$keyName] == null && $dbData[$keyName] != 0) {
                            if ($dbData[$keyName] == null) {
                                $dbData[$keyName] = 'null';
                            }
                            $dbData[$keyName] = addslashes(trim(trim($dbData[$keyName])));
                            if ($dbData[$keyName] == 'null') {
                                $dbData[$keyName] = null;
                            }
                        } else if ($dbData[$keyName] != 0) {
                            // else if ($keyName != 'is_default' && $keyName != 'isDefault' && $keyName != 'is_union_territory' && $keyName != 'status' && $dbData[$keyName] != 0) {
                            $dbData[$keyName] = '';
                        }
                    }
                }
            }

            $dbData['cr_usr'] = $this->user_data->id;
            $dbData['created_at'] = date('Y-m-d H:i:s');

            if (array_key_exists('is_default', $dbData)) {
                // CHECK DEFAULT VALUE BFR INSERT RECORD (COZ ATLEAST ONE RECORD SHOULD BE DEFAULT)
                if ($dbData['is_default'] == 0) {
                    $updIsDefaultResp = $this->model->getMasterDataByID($dbname, $master_name, '1', 'is_default');
                    if (!isset($updIsDefaultResp['data'])) {
                        $this->sendResponse(array('code' => 400, 'message' => 'Sorry, atleast one record should be default'));
                    }
                }
            }
            $inserted = $this->model->insert("`$clientDB`.`$master_name`", $dbData);
            if (!$inserted['status']) {
                throw new \Exception($inserted['error']);
            }
            if ($master_name == 'users_master') {
                $dbData['comp_user_id'] = $inserted['insert_id'];
                unset($dbData['user_code']);
                unset($dbData['doj']);
                unset($dbData['profile']);
                unset($dbData['ext_no']);
                unset($dbData['user_id']);
                unset($dbData['orderby_change_rights']);
                $this->model->insert("`sanordo_db`.`client_users_master`", $dbData);
            }
            //   ALL WORK AFTER INSERT LIKE ---- INSERT ADD MORE FIELDS (START)
            $this->input['clientDB'] = $clientDB;
            $this->input['dbname'] = $dbname;
            $this->input['insert_id'] = $inserted['insert_id'];
            $this->input['action'] = 'insert';
            $this->input['user_id'] = $this->user_data->id;
            $this->input['comp_id'] = $this->user_data->comp_id;
            $postIns = $this->dataSetModel->postInsertUpdateProcess($master_name, $this->input);

            if (!$postIns['status']) {
                throw new \Exception($postIns['error']);
            }
            //   ALL WORK AFTER INSERT LIKE ---- INSERT ADD MORE FIELDS (END)
            if (array_key_exists('is_default', $dbData)) {
                if ($dbData['is_default'] == 1) {
                    $updIsDefaultResp = $this->model->updateIsDefault("`$dbname`.`$master_name`", $inserted['insert_id'], $primaryKey, 'is_default');

                    if (!$updIsDefaultResp['status']) {
                        throw new \Exception($updIsDefaultResp['error']);
                    }
                }
            }

            if (array_key_exists('isDefault', $dbData)) {
                if ($dbData['isDefault'] == 1) {
                    $updIsDefaultResp = $this->model->updateIsDefault("`$dbname`.`$master_name`", $inserted['insert_id'], $primaryKey, 'isDefault');

                    if (!$updIsDefaultResp['status']) {
                        throw new \Exception($updIsDefaultResp['error']);
                    }
                }
            }

            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $master_name . ' (Id:' . $inserted['insert_id'] . ') inserted by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$dbname`.`api_user_logs`", $logData);
            $this->sendResponse(array('code' => 200, 'message' => 'Data inserted successfully', 'data' => array($primaryKey => $inserted['insert_id'])));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 500, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   DATA UPDATE
    public function dataUpdate()
    {
        try {
            $master_name = $this->input['master_name'];
            if (empty($master_name)) {
                throw new \Exception('Master name is required');
            }
            $rules  = $this->masterDataRulesModel->getMasterTableRules($master_name, 'update', $this->input);
            $validation = $this->validateReqData($rules, $this->input);

            if (empty($validation['status'])) {
                throw new \Exception($validation['error']);
            }
            if (!$validation['valid']) {
                $this->sendResponse(array('code' => 400, 'message' => $this->getFirstValidationError(), 'data' => $validation['validation_error']));
            }

            $primaryKey = 'id';
            $dbData = $this->input;
            $dbData['comp_id'] = $this->user_data->comp_id;
            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;

            if (array_key_exists($master_name, $this->model->tables) == 1) {
                //  GET MASTER CONFIGURATION FROM CONFIG FILE  --  START
                $preProcess = Main::$mastersConfig;
                $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;
                $primaryKey = $preProcess[$master_name]['primaryKey'];
                $dbData['dbname'] = $dbname;
                $dbData['action'] = 'update';
                $getDbData = $this->dataSetModel->preInsertUpdateGetData($master_name, $dbData);

                if (!$getDbData['status']) {
                    $this->sendResponse(array('code' => 400, 'message' => $getDbData['error']));
                }
                $dbData = $getDbData['dbData'];

                if (isset($dbData['CouponsData'])) {
                    // FOR COUPONS CHECK
                    $this->input['CouponsData'] = $dbData['CouponsData'];
                }
                //  GET MASTER CONFIGURATION FROM CONFIG FILE  --  END
            }

            $DBFields = $this->model->getMasterTableFields("`$dbname`.`$master_name`");
            if (!$DBFields['status']) {
                throw new \Exception($DBFields['error']);
            }
            $fields = $DBFields['fields'];
            $db_keys = (is_array($dbData)) ? array_keys($dbData) : [];
            foreach ($db_keys as $keyName) {
                if (!in_array($keyName, $fields)) {
                    unset($dbData[trim($keyName)]);
                } else {
                    if (array_key_exists($keyName, $dbData)) {
                        if (!empty($dbData[$keyName]) ||  $dbData[$keyName] == null && $dbData[$keyName] != 0) {
                            if ($dbData[$keyName] == null) {
                                $dbData[$keyName] = 'null';
                            }
                            $dbData[$keyName] = addslashes(trim(trim($dbData[$keyName])));
                            if ($dbData[$keyName] == 'null') {
                                $dbData[$keyName] = null;
                            }
                        } else if ($dbData[$keyName] != 0) {
                            $dbData[$keyName] = NULL;
                        }
                    }
                }
            }
            $dbData['md_usr'] = $this->user_data->id;
            $dbData['updated_at'] = date('Y-m-d H:i:s');
            $update_id = $this->input[$primaryKey] ?? null;
            if (empty($update_id)) {
                throw new \Exception("$primaryKey is required for update");
            }

            if (array_key_exists('is_default', $dbData)) {
                // CHECK DEFAULT VALUE BFR UPDATE RECORD (COZ ATLEAST ONE RECORD SHOULD BE DEFAULT)
                if ($dbData['is_default'] == 0) {
                    $updIsDefaultResp = $this->model->getMasterDataByID($dbname, $master_name, '1', 'is_default', '*', '', "$primaryKey != $update_id");
                    if (!isset($updIsDefaultResp['data'])) {
                        echo json_encode(array('statusCode' => 400, 'message' => 'Sorry, atleast one record should have default value'));
                        die;
                    }
                }
            }

            if (array_key_exists('isDefault', $dbData)) {
                // CHECK DEFAULT VALUE BFR UPDATE RECORD (COZ ATLEAST ONE RECORD SHOULD BE DEFAULT)
                if ($dbData['isDefault'] == 0) {
                    $updIsDefaultResp = $this->model->getMasterDataByID($dbname, $master_name, '1', 'isDefault', '*', '', "$primaryKey != $update_id");
                    if (!isset($updIsDefaultResp['data'])) {
                        echo json_encode(array('statusCode' => 400, 'message' => 'Sorry, atleast one record should have default value'));
                        die;
                    }
                }
            }

            $retData = $this->model->update("$dbname.$master_name", $dbData, [$primaryKey => $update_id]);
            if (!$retData['status']) {
                throw new \Exception($retData['error']);
            }

            if ($master_name == 'users_master') {
                $dbData['comp_user_id'] = $update_id;
                unset($dbData['user_id']);
                unset($dbData['user_code']);
                unset($dbData['doj']);
                unset($dbData['profile']);
                unset($dbData['ext_no']);
                unset($dbData['orderby_change_rights']);
                $this->model->update("`sanordo_db`.`client_users_master`", $dbData, ['comp_user_id' => $update_id]);
            }

            //   ALL WORK AFTER UPDATE LIKE ---- INSERT ADD MORE FIELDS (START)
            $this->input['clientDB'] = $clientDB;
            $this->input['dbname'] = $dbname;
            $this->input['action'] = 'update';
            $this->input['insert_id'] = $update_id;
            $this->input['user_id'] = $this->user_data->id;
            $postIns = $this->dataSetModel->postInsertUpdateProcess($master_name, $this->input);

            if (!$postIns['status']) {
                throw new \Exception($postIns['error']);
            }
            //   ALL WORK AFTER UPDATE LIKE ---- INSERT ADD MORE FIELDS (END)

            if (array_key_exists('is_default', $dbData)) {
                if ($dbData['is_default'] == 1) {
                    $updIsDefaultResp = $this->model->updateIsDefault("`$dbname`.`$master_name`", $update_id, $primaryKey, 'is_default');

                    if (!$updIsDefaultResp['status']) {
                        throw new \Exception($updIsDefaultResp['error']);
                    }
                }
            }

            if (array_key_exists('isDefault', $dbData)) {
                if ($dbData['isDefault'] == 1) {
                    $updIsDefaultResp = $this->model->updateIsDefault("`$dbname`.`$master_name`", $update_id, $primaryKey, 'isDefault');

                    if (!$updIsDefaultResp['status']) {
                        throw new \Exception($updIsDefaultResp['error']);
                    }
                }
            }

            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $master_name . ' (Id:' . $update_id . ') updated by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$clientDB`.`api_user_logs`", $logData);

            $this->sendResponse(array('code' => 200, 'message' => 'Data updated successfully', 'data' => array($primaryKey => $update_id)));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 500, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   DATA DELETE
    public function dataDelete()
    {
        try {
            $master_name = $this->input['master_name'];
            $primaryKey = $this->input['primary_key'];
            $delete_id = $this->input[$primaryKey] ?? null;
            if (empty($delete_id)) {
                throw new \Exception("$primaryKey is required for delete");
            }
            if (empty($master_name)) {
                throw new \Exception('Master name is required');
            }
            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;
            if (array_key_exists($master_name, $this->model->tables) == 1) {

                $preProcess = Main::$mastersConfig;
                $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;
                $primaryKey = $preProcess[$master_name]['primaryKey'];

                $preDeleteData['dbname'] = $dbname;
                $preDeleteData['delete_id'] = $delete_id;

                $preDeleteResp = $this->dataSetModel->preDeleteProcess($master_name, $preDeleteData);

                if (!$preDeleteResp['status']) {
                    throw new \Exception($preDeleteResp['error']);;
                }
            }

            $retData = $this->model->delete("$dbname.$master_name", [$primaryKey => $delete_id]);
            if ($retData['code'] == 1451) {
                throw new \Exception('Cannot delete this record because it has related records in another table');
            }
            if (!$retData['status'])
                throw new \Exception($retData['error']);

            $postDeleteResp = $this->dataSetModel->postDeleteProcess($master_name, $preDeleteResp['data']);
            if (!$postDeleteResp['status'])
                throw new \Exception($postDeleteResp['error']);

            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $master_name . ' (Id:' . $delete_id . ') deleted by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$clientDB`.`api_user_logs`", $logData);

            $this->sendResponse(array('code' => 200, 'message' => 'Data deleted successfully', 'data' => array($primaryKey => $delete_id)));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 500, 'message' => $e->getMessage(), 'data' => null));
        }
    }
    //   DATA LIST
    public function dataList()
    {
        try {
            $master_name = $this->input['master_name'] ?? null;
            if (empty($master_name)) {
                throw new \Exception('Master name is required');
            }

            $search = $this->input['search'] ?? [];

            if (isset($search['valid_date'])) {
                $valid_date = $search['valid_date'];
                unset($search['valid_date']);
                if (!empty($valid_date)) {
                    $search['start_date'] = date('Y-m-d', strtotime($valid_date[0]));
                    $search['end_date'] = date('Y-m-d', strtotime($valid_date[1]));
                }
            }

            if (isset($search['days_filter'])) {
                unset($search['days_filter']);
            }

            $searchArray = $search;

            $page_no = isset($this->input['page_no']) && is_numeric($this->input['page_no']) ? (int)$this->input['page_no'] : 1;
            $limit = isset($this->input['limit']) && is_numeric($this->input['limit']) ? (int)$this->input['limit'] : 10;

            $sortBy = $this->input['sort_by'] ?? '';
            if ($sortBy) {
                $sort_type = $this->input['sort_type'] ?? 'ASC';
                $sortBy = $sortBy . ' ' . strtoupper($sort_type);
            }

            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;

            $where = '';
            $join_DB = '';
            // $finalSortBy = '';

            if (array_key_exists($master_name, $this->model->tables)) {

                $preProcess = Main::$mastersConfig;
                $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;

                switch ($master_name) {
                    case 'order':
                        $cond = $this->FxModel->getOrderListConditions($this->user_data, $this->input);
                        if (!$cond['status']) {
                            throw new Exception($cond['error']);
                        }
                        $where = $cond['data'];
                        break;
                    case 'disposition_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_disposition_name' => 'LIKE'],
                            ['id_disposition_name' => "CONCAT(disposition_id, ' ', COALESCE(disposition_name,''))"]
                        );
                        // $finalSortBy = 'status DESC';
                        break;
                    case 'tax_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_tax_name' => 'LIKE'],
                            ['id_tax_name' => "CONCAT(tax_id, ' ', COALESCE(tax_name,''))"]
                        );
                        // $finalSortBy = 'tax_status DESC';
                        break;
                    case 'coupon_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['coupon_title' => 'LIKE'],
                            []
                        );
                        // $finalSortBy = 'status DESC';
                        break;
                    case 'location_city':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['state_id' => 't1.', 'status' => 't1.'],
                            ['city_name' => 'LIKE'],
                            []
                        );
                        $finalSortBy = 'status DESC';
                        break;
                    case 'location_pincode':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['id' => 't1.', 'state_id' => 't1.', 'status' => 't1.'],
                            ['pincode' => 'LIKE'],
                            []
                        );
                        // $finalSortBy = 'status DESC';
                        break;
                    case 'customer_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['id' => 't1.', 'status' => 't1.', 'customer_type' => 't1.'],
                            ['customer_name' => 'LIKE'],
                            []
                        );
                        // $finalSortBy = 'status DESC';
                        break;
                    case 'lead_type':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_lead_name' => 'LIKE'],
                            ['id_lead_name' => "CONCAT(id, ' ', COALESCE(lead_name,''))"]
                        );
                        break;
                    case 'order_status':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['status_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'users_group_master':
                        $join_DB = 'sanordo_clientdb_' . $this->user_data->comp_id;
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.'],
                            ['group_name' => 'LIKE'],
                            []
                        );
                        // $comp_id = $this->user_data->comp_id;
                        // $where .= " AND comp_id = $comp_id";
                        break;
                    case 'campaign_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['campaign_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'users_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['user_id' => 't1.', 'user_name' => 't1.', 'status' => 't1.'],
                            ['user_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'payment_type':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['payment_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'inventory_type':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['inventory_type_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'invoice_type':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['title' => 'LIKE'],
                            []
                        );
                        break;
                    case 'admin_courier_api_master':
                        $where = '1=1';
                        break;
                    case 'admin_payment_gateway_master':
                        $where = '1 = 1';
                        break;
                    case 'item_group_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_group_name' => 'LIKE'],
                            ['id_group_name' => "CONCAT(id, ' ', COALESCE(group_name,''))"]
                        );
                        break;
                    case 'itemcategory_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['itemcat_id_name' => 'LIKE'],
                            ['itemcat_id_name' => "CONCAT(itemcat_id, ' ', COALESCE(name,''))"]
                        );
                        break;
                    case 'item_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.'],
                            ['item_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'item_package_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['package_name' => 'LIKE'],
                            []
                        );
                        break;
                    case 'item_stock':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            [],
                            []
                        );
                        break;
                    case 'stockout_inventory':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            [],
                            []
                        );
                        break;
                    case 'branch_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.'],
                            ['branch_name' => 'LIKE', 'branch_code' => 'LIKE'],
                            []
                        );
                        break;
                    case 'lead_status':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.'],
                            ['id_title' => 'LIKE'],
                            ['id_title' => "CONCAT(t1.id, ' ', COALESCE(t1.title,''))"]
                        );
                        break;
                    case 'lead_source':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.'],
                            ['id_title' => 'LIKE'],
                            ['id_title' => "CONCAT(t1.id, ' ', COALESCE(t1.title,''))"]
                        );
                        break;
                    case 'api_provider':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_title' => 'LIKE'],
                            ['id_title' => "CONCAT(id, ' ', COALESCE(title,''))"]
                        );
                        break;
                    case 'leads':
                        if ($searchArray['list_by_flp']) {
                            $ids = $this->model->getIdsOfLeadFlpLog($dbname, $searchArray['list_by_flp']);
                            if (!$ids['status'])
                                throw new Exception($ids['error']);
                            $searchArray['list_by_flp'] = $ids['data'][0]['lead_id'];
                        }
                        $where = $this->model->whereString(
                            $searchArray,
                            ['status' => 't1.', 'customer_type' => 't1.', 'item_id' => 't7.', 'item_package' => 't8.', 'list_by_flp' => 't1.'],
                            [
                                'id_name_email' => 'LIKE',
                                'item_id' => 'FINDINSET',
                                'item_package' => 'FINDINSET',
                                'start_date' => 'DGTE',
                                'end_date' => 'DLTE',
                                'contact_no' => 'LIKE',
                                'order_id' => 'NULLNOTNULL'
                            ],
                            ['id_name_email' => "CONCAT(t1.id, ' ', COALESCE(t1.client_name,''), ' ', COALESCE(t1.email,''))", 'start_date' => 'lead_date', 'end_date' => 'lead_date', 'list_by_flp' => 'id']
                        );
                        break;
                    case 'client_user_login_log':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            [],
                            []
                        );
                        $comp_id = $this->user_data->comp_id;
                        $where .= " AND t2.comp_id = $comp_id";
                        $join_DB = $clientDB;
                        break;
                    case 'purchase_master':
                        $where = $this->model->whereString(
                            $searchArray,
                            ['branch_id' => 't1.', 'id' => 't1.'],
                            [],
                            []
                        );
                        break;
                    case 'order_message_template':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_title' => 'LIKE'],
                            ['id_title' => "CONCAT(id, ' ', COALESCE(template_name,''))"]
                        );
                        break;
                    case 'courier':
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            ['id_title' => 'LIKE'],
                            ['id_title' => "CONCAT(id, ' ', COALESCE(title,''))"]
                        );
                        break;
                    default:
                        $where = $this->model->whereString(
                            $searchArray,
                            [],
                            [],
                            []
                        );
                        break;
                }
            }
            // if (!empty($sortBy)) {
            //     $finalSortBy .= ','.$sortBy;
            // } else {;
            // }
            if ($master_name == 'order') {
                $dataList = $this->OrderModel->getOrderList($this->user_data->comp_id, $where, $page_no, $limit, $sortBy);
            } else {
                $dataList = $this->model->getMasterData($dbname, $master_name, $where, $page_no, $limit, $sortBy, $join_DB);
            }

            if ($dataList['status']) {
                if ($master_name != 'api_user_logs') {
                    $logData = array(
                        'user_id' => $this->user_data->id,
                        'message' => $master_name . ' list searched by ' . $this->user_data->user_name,
                        'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                        'is_master'  => $this->user_data->master_type,
                        'cr_date'    => date('Y-m-d H:i:s')
                    );
                    $this->model->insert("`$clientDB`.`api_user_logs`", $logData);
                }
                $this->sendResponse([
                    'code' => 200,
                    'message' => 'Data fetched successfully',
                    'data' => $dataList['data'],
                    'count' => $dataList['count'],
                    'page' => $dataList['page'],
                    'page_limit' => $dataList['page_limit']
                ]);
            } else {
                throw new \Exception($dataList['error']);
            }
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => $e->getMessage(),
                'data' => null
            ]);
        }
    }
    //   GET EDIT RECORD
    public function dataById()
    {
        try {
            $master_name = $this->input['master_name'] ?? null;
            $primaryKey = $this->input['primary_key'] ?? null;

            if (empty($master_name) || empty($primaryKey)) {
                throw new \Exception('Master name and primary key are required.');
            }

            $edit_id = $this->input[$primaryKey] ?? null;
            if (empty($edit_id)) {
                throw new \Exception("Missing value for primary key: {$primaryKey}");
            }

            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;
            $select = '*';
            $query = '';
            if (array_key_exists($master_name, $this->model->tables)) {

                $preProcess = Main::$mastersConfig;
                $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;

                switch ($master_name) {
                    case 'coupon_master':
                        $select = "*,date_format(date(valid_from),'%Y-%m-%d') as valid_from,date_format(date(valid_to),'%Y-%m-%d') as valid_to";
                        break;
                    case 'location_pincode':
                        $query = "SELECT t1.*,t2.city_name FROM `$dbname`.`location_pincode` as t1
                        LEFT JOIN `$dbname`.`location_city` t2 ON t1.city_id=t2.id";
                        $primaryKey = 't1.id';
                        break;
                    case 'order':
                        $query = "SELECT id, customer_order_id FROM `$dbname`." . $this->model->tables[$master_name];
                        $primaryKey = 'id';
                        break;
                }
            }

            $dataList = $this->model->getMasterDataByID($dbname, $master_name, $edit_id, $primaryKey, $select, $query);
            if (!$dataList['status']) {
                throw new \Exception($dataList['error']);
            }

            $postDataByIdResp = $this->dataSetModel->postDataByIdProcess($master_name, $dbname, $dataList['data'], $edit_id);

            if (!$postDataByIdResp['status']) {
                throw new \Exception($postDataByIdResp['error']);
            }

            $dataList = $postDataByIdResp['data'];

            if ($master_name == 'users_master') {
                $db = 'sanordo_clientdb_' . $this->user_data->comp_id;
                $select = "SELECT * FROM `$db`.`branch_user_rights` WHERE user_id = $edit_id";
                $userBranch = $this->model->fetchAllData($select);
                $dataList['branchRights'] = $userBranch['data'];
            }

            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $master_name . ' (Id:' . $edit_id . ') retrieve data by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$clientDB`.`api_user_logs`", $logData);

            $this->sendResponse([
                'code' => 200,
                'message' => 'Data fetched successfully',
                'data' => $dataList
            ]);
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => $e->getMessage(),
                'data' => null
            ]);
        }
    }

    //   CUSTOMER ADDRESS  --  ADD MORE
    public function getPincodeListByKeyword()
    {
        try {
            $dbPrefix = 'sanordo_clientdb_' . $this->user_data->comp_id;
            $keyword = trim($this->input['keyword']);
            $likeArray = "c.city_name LIKE '%$keyword%' OR p.pincode LIKE '%$keyword%'";
            $searchData = $this->model->getCityStatePincodeBySearch($dbPrefix, 'p.status = 1', $likeArray, 20);
            $this->sendResponse(['code' => 200, 'message' => 'Data fetch successfully', 'data' => $searchData]);
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => 'Internal Server Error',
                'data' => null,
                'error' => $e->getMessage()
            ]);
        }
    }
    //   GROUP PERMISSION LIST  ---  COMMON FOR USER AND GROUP
    public function getUserGroupPermissions()
    {
        try {
            if ($this->input['type'] == 'GROUP') {
                if (empty($this->input['profile_id'])) {
                    throw new \Exception('Profile id is required.');
                }
                $id = $this->input['profile_id'];
            } else if ($this->input['type'] == 'USER') {
                if (empty($this->input['user_id'])) {
                    throw new \Exception('User id is required.');
                }
                $id = $this->input['user_id'];
            }
            $dbPrefix = $this->model->client_db_prefix . $this->user_data->comp_id;
            $menuList = $this->model->getUserProfileRights($id, $this->input['type'], $dbPrefix);
            if (!$menuList['status']) {
                throw new \Exception($menuList['error']);
            }
            if (!empty($menuList['data'])) {
                $menuList = $menuList['data'];
                $organizedMenus = [];
                foreach ($menuList as $menu) {
                    $parentId = $menu['menu_parent'];
                    if (!isset($organizedMenus[$parentId])) {
                        $organizedMenus[$parentId] = [];
                    }
                    $organizedMenus[$parentId][] = $menu;
                }

                $menuTree = [];
                foreach ($menuList as $menu) {
                    $menuId = $menu['menu_id'];
                    $parentId = $menu['menu_parent'];

                    if ($parentId == 0) {
                        $childMenus = isset($organizedMenus[$menuId]) ? $organizedMenus[$menuId] : [];
                        if (!empty($childMenus)) {
                            $menu['child_menus'] = $childMenus;
                        }
                        $menuTree[] = $menu;
                    } elseif (isset($organizedMenus[$menuId])) {
                        continue;
                    }
                }
                $ret_data['menu_list'] = $menuTree;

                if (!empty($ret_data)) {
                    // $dbname = $this->model->client_db_prefix . $this->user_data->comp_id;
                    $logData = array(
                        'user_id' => $this->user_data->id,
                        'message' => $this->input['type'] . 'permission (Id:' . $id . ') get by ' . $this->user_data->user_name,
                        'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                        'is_master'  => $this->user_data->master_type,
                        'cr_date'    => date('Y-m-d H:i:s')
                    );
                    $this->model->insert("`$dbPrefix`.`api_user_logs`", $logData);

                    return $this->sendResponse(array('code' => 200, 'message' => 'Data fetch successfully', 'data' => $ret_data['menu_list']));
                } else {
                    throw new \Exception('Failed to retrieve menu data.');
                }
            }
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => 'Internal Server Error',
                'data' => null,
                'error' => $e->getMessage()
            ]);
        }
    }

    public function updateUserProfileRights()
    {
        try {
            $id = (strtoupper($this->input['type']) == 'USER') ? $this->input['user_id'] : $this->input['profile_id'];
            $menus = $this->dataSetModel->extractMenusRights($this->input['rights'], $id, $this->input['type']);
            $dbPrefix = $this->model->client_db_prefix . $this->user_data->comp_id;
            if ($this->input['type'] == 'GROUP') {
                $table = 'users_profile_rights';
                $cond = ['profile_id' => $this->input['profile_id']];
                $id = $this->input['profile_id'];
            } else if ($this->input['type'] == 'USER') {
                $table = 'users_master_rights';
                $cond = ['user_id' => $this->input['user_id']];
                $id = $this->input['user_id'];
            }
            $resp = $this->dataSetModel->updateUserProfileRights("`$dbPrefix`.`$table`", $cond, $menus);
            if (!$resp['status']) {
                throw new \Exception($resp['error']);
            }
            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $this->input['type'] . 'permission (Id:' . $id . ') updated by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$dbPrefix`.`api_user_logs`", $logData);
            $this->sendResponse(['code' => 200, 'message' => 'Updated successfully', 'data' => null]);
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => 'Internal Server Error',
                'data' => null,
                'error' => $e->getMessage()
            ]);
        }
    }

    public function uploadImg()
    {
        try {
            if (empty($this->user_data->comp_id)) {
                throw new \Exception("Invalid Company ID");
            }
            if (empty($_FILES['upload_img'])) {
                throw new \Exception("Please select image to upload");
            }
            if (empty($this->input['id'])) {
                throw new \Exception("ID is required to upload image");
            }
            $max_file_size = Main::getLogoUploadMaxSize();
            $allowed_file_types = Main::getAllowedLogoFileTypes();
            if ($_FILES["upload_img"]["size"] > Main::getLogoUploadMaxSize()) {
                throw new \Exception('File size should be less than ' . ($max_file_size / 1024) . ' KB');
            }
            if (!in_array($_FILES["upload_img"]["type"], $allowed_file_types)) {
                throw new \Exception('Only ' . implode(", ", $allowed_file_types) . ' files are allowed.');
            }
            $uploadDir = Main::getUploadPath();
            $uploadFolder = Main::getUploadFolder();
            $uploadBasePath = $uploadDir . '/comp-' . $this->user_data->comp_id . '/';
            if (!is_dir($uploadBasePath)) {
                mkdir($uploadBasePath, 0755, true);
            }
            if (!is_dir($uploadBasePath)) {
                throw new \Exception("Upload path does not exist");
            }
            $file_name = $this->input['type'] . '_' . $this->input['id'] . '.' . pathinfo($_FILES['upload_img']['name'], PATHINFO_EXTENSION);
            if (!move_uploaded_file($_FILES['upload_img']['tmp_name'], $uploadBasePath . $file_name)) {
                throw new \Exception("Error in uploading logo file");
            }
            $img_path = $uploadFolder . '/comp-' . $this->user_data->comp_id . '/' . $file_name;
            $data = ['img_path' => $img_path];

            $dbname = $this->model->client_db_prefix . $this->user_data->comp_id;
            $master = $this->input['master_name'];
            $primaryKey = $this->input['primary'];
            $retData = $this->model->update("$dbname." . "$master", $data, [$primaryKey => $this->input['id']]);
            if (!$retData['status']) {
                throw new \Exception($retData['error']);
            }
            $this->sendResponse(array('code' => 200, 'message' => 'Image uploaded successfully', 'data' => ['img_path' => $img_path]));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function getOnlyList()
    {
        try {
            if (empty($this->input['master_name'])) {
                throw new \Exception('Master name is required');
            }
            $master_name = $this->input['master_name'];
            $dbData['comp_id'] = $this->user_data->comp_id;
            $dbname = 'sanordo_db';
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;
            $preProcess = Main::$mastersConfig;
            $dbname = $preProcess[$master_name]['clientDB'] ? $clientDB : $dbname;
            $where = '1=1';
            $query = "SELECT * FROM `$dbname`.`$master_name`";
            if ($master_name == 'lead_flp_log') {
                $id = $this->input['id'];
                $where = "flp_lead_id = $id";
                $query = "SELECT t1.lead_flp_comment,t2.title lead_flp_status,t2.color_code,t3.user_name,DATE_FORMAT(t1.created_at,'%d-%m-%Y %H:%m:%s') created_at,DATE_FORMAT(t1.lead_flp_date,'%d-%m-%Y %H:%m:%s') as lead_flp_date FROM `$dbname`.`$master_name` t1
                LEFT JOIN `$dbname`.`lead_status` t2 ON t2.id = t1.lead_flp_status
                LEFT JOIN `$clientDB`.`users_master` t3 ON t3.user_id = t1.cr_usr
                WHERE $where ORDER BY t1.id DESC";
            }
            $sql =  $query;
            $resp = $this->model->fetchAllData($sql);
            if (!$resp['status']) {
                throw new \Exception($resp['error']);
            }
            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $master_name . 'list searched by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$dbname`.`api_user_logs`", $logData);
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetch successfully', 'data' => $resp['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function assignLead()
    {
        try {
            $dbname = $this->model->client_db_prefix . $this->user_data->comp_id;
            for ($i = 0; $i < count($this->input['lead_ids']); $i++) {
                $where = ['id' => $this->input['lead_ids'][$i]];
                $upd_data['assign_to'] = $this->input['user_id'];
                $retData = $this->model->update("`$dbname`.`leads`", $upd_data, $where);
                if (!$retData['status']) {
                    throw new \Exception($retData['error']);
                }
            }
            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => 'Lead assigned (Ids : ' . implode(',', $this->input['lead_ids']) . ') to ' . $this->input['user_id'] . ' by ' . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $this->model->insert("`$dbname`.`api_user_logs`", $logData);
            $this->sendResponse(array('code' => 200, 'message' => 'Lead Assign Successfully', 'data' => $retData['affected_rows']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function commonAPI()
    {
        try {
            if (empty($this->input['master_name'])) {
                throw new \Exception('Master name is required');
            }
            $msg = 'Data inserted successfully';
            $this->input['user_id'] = $this->user_data->id;
            $this->input['dbname'] = $this->model->client_db_prefix . $this->user_data->comp_id;
            if ($this->input['master_name'] == 'order_logic') {
                $resp = $this->dataSetModel->insertOrderLogicData($this->input);
                $logmsg = $resp['data'] . 'rows inserted by';
            } else if ($this->input['master_name'] == 'change_password') {
                $resp = $this->dataSetModel->changePassword($this->input);
                $msg = 'Password changed successfully';
                $logmsg = 'password changed by';
            }
            if (!$resp['status'])
                throw new \Exception($resp['error']);

            $logData = array(
                'user_id' => $this->user_data->id,
                'message' => $this->input['master_name'] . $logmsg . $this->user_data->user_name,
                'ip_address' =>  $_SERVER['REMOTE_ADDR'],
                'is_master'  => $this->user_data->master_type,
                'cr_date'    => date('Y-m-d H:i:s')
            );
            $dbname = $this->input['dbname'];
            $this->model->insert("`$dbname`.`api_user_logs`", $logData);
            $this->sendResponse(array('code' => 200, 'message' => $msg, 'data' => $resp['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function getLeadDashboard()
    {
        try {
            $where2 = ' 1=1';
            $comp_id = $this->user_data->comp_id;
            $where2 .= " AND comp_id = $comp_id";
            $user_id = $this->user_data->id;
            $search = $this->input['search'] ?? [];
            $valid_date = $search['valid_date'];
            unset($search['valid_date']);
            unset($search['date_type']);
            if (!empty($valid_date)) {
                $search['start_date'] = date('Y-m-d', strtotime($valid_date[0]));
                $search['end_date'] = date('Y-m-d', strtotime($valid_date[1]));
            }
            $where = $this->model->whereString(
                $search,
                [],
                ['start_date' => 'DGTE', 'end_date' => 'DLTE'],
                ['start_date' => 'lead_date', 'end_date' => 'lead_date']
            );
            // if ($this->input['branch_ids']) {
            //     $branch_ids = $this->input['branch_ids'];
            // } else {
            //     $branch_ids = ' ';
            // }
            $clientDB = $this->model->client_db_prefix . $this->user_data->comp_id;
            if ($this->user_data->master_type != 1) {
                $where .=  " AND (assign_to = " . $user_id . " OR assign_to IN (
                    WITH RECURSIVE UserHierarchy AS (
                    SELECT user_id FROM `$clientDB`.`users_master` WHERE manager_id = " . $user_id . "
                    UNION ALL
                    SELECT  u.user_id FROM `$clientDB`.`users_master` u INNER JOIN
                    UserHierarchy uh ON u.manager_id = uh.user_id
                    )
                    SELECT user_id FROM UserHierarchy
                    ))";
                // $where .= " AND branch IN ($branch_ids)";
                $where2 .=  " AND (user_id = " . $user_id . " OR user_id IN (
                    WITH RECURSIVE UserHierarchy AS (
                    SELECT user_id FROM `$clientDB`.`users_master` WHERE manager_id = " . $user_id . "
                    UNION ALL
                    SELECT  u.user_id FROM `$clientDB`.`users_master` u INNER JOIN
                    UserHierarchy uh ON u.manager_id = uh.user_id
                    )
                    SELECT user_id FROM UserHierarchy
                    ))";
            }

            $dashData = $this->model->getLeadDashboardData($this->model->client_db_prefix . $this->user_data->comp_id, $where, $where2);
            if (!$dashData['status'])
                throw new Exception($dashData['error']);
            $returnData = [];
            $returnData['cards']         = $dashData['dash_cards'];
            $returnData['leadStatusPie'] = $dashData['lead_status_piechart'];
            $returnData['leadSourcePie'] = $dashData['lead_source_piechart'];
            $returnData['leadMonthWise'] = $dashData['lead_month'];
            $returnData['lead_user_wise'] = $dashData['lead_user_wise'];
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetch successfully', 'data' => $returnData));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function fetchMasterList()
    {
        try {
            $master_name = !empty($this->input['master']) ? trim($this->input['master']) : "";
            if (empty($master_name)) {
                throw new \Exception("Master name is required.");
            }
            $where = [];
            if ($master_name == 'pincode') {
                $where = !empty($this->input['srch']) ? ['pincode' => ['pincode' => $this->input['srch']]] : [];
            } else if ($master_name == 'itemList') {
                $where = !empty($this->input['srch']) ? ['itemList' => ['name' => $this->input['srch']]] : [];
                if (!empty($this->input['category_id'])) {
                    $where['itemList']['category_id'] = $this->input['category_id'];
                }
            }

            $retData = $this->model->getOptionList([$master_name], $this->user_data->comp_id, $where, []);
            if (!$retData['status']) {
                throw new \Exception($retData['error']);
            }
            $this->sendResponse(array('code' => 200, 'message' => 'Data fetched successfully', 'data' => $retData['data']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse([
                'code' => 500,
                'message' => 'Something went wrong while fetching data. ' . $e->getMessage(),
                'data' => null,
                'error' => $e->getMessage()
            ]);
        }
    }

    public function leadStatusCreateOrder()
    {
        try {
            $dbPrefix = $this->model->client_db_prefix . $this->user_data->comp_id;
            $lead_status = $this->input['lead_status'];
            $leadStatusData = $this->model->fetchSingleData("SELECT * FROM `$dbPrefix`.`lead_status` WHERE id = $lead_status");
            if (!$leadStatusData['status']) {
                throw new Exception($leadStatusData['error']);
            }
            if ($leadStatusData['data']['create_order'] == 1) {
                // $this->createLeadBulkOrder();
            } else {
                $this->sendResponse(array('code' => 200, 'message' => 'On this status order will not create', 'data' => ''));
            }
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function generateToken()
    {
        try {
            $url = '';
            $urlarr = Main::WebhookURLs();
            $encToken = Crypto::encryptData(json_encode([
                "comp_id" => $this->user_data->comp_id,
                "random_value" => mt_rand(100, 999)
            ]));
            if ($this->input['type'] == 'COURIER') {
                if (!empty($this->input['courier'])) {
                    if (!empty($urlarr[$this->input['courier']])) {
                        $url = $urlarr[$this->input['courier']];
                    }
                }
            } else if ($this->input['type'] == 'PAYMENT') {

                if (!empty($this->input['gateway'])) {
                    if (!empty($urlarr[$this->input['gateway']])) {
                        $url = $urlarr[$this->input['gateway']];
                    }
                }
            } else if ($this->input['type'] == 'SHOPIFY') {
                $url = $_ENV['SHOPIFY_WEBHOOK_URL'];
            }
            $webhook = !empty($url) ? $url . '?token=' . $encToken : "";
            $this->sendResponse(array('code' => 200, 'message' => 'Token Generated', 'data' => $encToken, 'webhook' => $webhook));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

    public function uploadAttachments()
    {
        try {
            $uploaderService = new AttachmentUploader();
            $attachs = $uploaderService->processAttachments($_FILES, $this->input, $this->user_data);
            if (!$attachs['status']) {
                throw new Exception($attachs['error']);
            };
            $insertData = [];
            foreach ($attachs['attachment_list'] as $data) {
                $insertData[] = array(
                    'path' => $data['path'],
                    'file_name' => $data['name'],
                    'order_id' => $this->input['ref_id'],
                    'size' => $data['size'],
                    'mime' => $data['type'],
                    'cr_usr' => $this->user_data->id
                );
            }
            if (!empty($insertData)) {
                $dbPrefix = $this->model->client_db_prefix . $this->user_data->comp_id;
                $table = $this->model->tables[$this->input['master_name']];
                $resp = $this->model->batchInsert("`$dbPrefix`.`$table`", $insertData);
            } else {
                throw new Exception('Data empty to insert');
            }
            if (!$resp['status']) {
                throw new Exception($resp['error']);
            }
            $this->sendResponse(array('code' => 200, 'message' => 'Uploaded Successfully', 'data' => $resp['inserted_rows']));
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => $e->getMessage(), 'data' => null));
        }
    }

}
