<?php

namespace App\Controllers\Client;

use App\Controllers\BaseController;
use App\Core\Service\Logger;
use App\Model\MasterModel;
use App\Model\OrderModel;
use App\Model\MasterDataSetModel;
use App\Model\FxModel;
use App\Library\Fx;
use App\Service\Pdf;
use App\Library\Utilities;

class DocumentController extends BaseController
{
    private $MasterModel;
    private $MasterDataSetModel;
    private $OrderModel;
    private $FxModel;
    private $fx;
    public function __construct()
    {
        parent::__construct();
        $this->MasterModel = new MasterModel();
        $this->OrderModel  = new OrderModel();
        $this->FxModel     = new FxModel();
        $this->MasterDataSetModel = new MasterDataSetModel();
        $this->fx = new Fx();
    }

    private function getDataForDocument($comp_id, $order_id)
    {
        try {
            $cmprs = $this->fx->getCompanyDetail($comp_id);
            if (empty($cmprs['status'])) {
                throw new \Exception($cmprs['error']);
            }

            $ordrs = $this->OrderModel->getOrderDetail($comp_id, "o.id IN(" . $order_id . ")", 1, 0);
            if (empty($ordrs['status'])) {
                throw new \Exception($ordrs['error']);
            }
            if (empty($ordrs['data'])) {
                throw new \Exception("Order detail not found");
            }
            $retorder = [];
            foreach ($ordrs['data'] as $order) {
                $ordItemrs = $this->OrderModel->getOrderItemList($comp_id, "order_id=" . $order['id'], 0, 0);
                if (empty($ordItemrs['status'])) {
                    throw new \Exception($ordItemrs['error']);
                }
                if (empty($ordItemrs['data'])) {
                    throw new \Exception("Order Item detail not found");
                }
                $ordTax = $this->OrderModel->getOrderItemTaxList($comp_id, "order_id=" . $order['id']);
                if (empty($ordTax['status'])) {
                    throw new \Exception($ordTax['error']);
                }
                $tax_list = [];
                $tax_item_list = [];
                if (!empty($ordTax['data'])) {
                    foreach ($ordTax['data'] as $tax) {
                        $tax_list[$tax['tax_id']] = $tax['tax_name'];
                        if (array_key_exists($tax['item_id'], $tax_item_list) == false) {
                            $tax_item_list[$tax['item_id']] = [];
                        }
                        $tax_item_list[$tax['item_id']][$tax['tax_id']] = $tax;
                    }
                }

                $branchrs = $this->fx->getBranchDetail($comp_id, $this->user_data, $order['branch_id']);
                if (empty($branchrs['status'])) {
                    throw new \Exception($branchrs['error']);
                }
                if (empty($branchrs['data'])) {
                    throw new \Exception("Branch detail not found");
                }
                $return_address = $branchrs['data']['complete_address'];
                if (!empty($order['dealer_id'])) {
                    $dealrs = $this->FxModel->getCustomerAddress($comp_id, "customer_id=" . $order['dealer_id'], 1, 'address_id', 'DESC');
                    if (empty($dealrs['status'])) {
                        throw new \Exception($dealrs['error']);
                    }
                    if (!empty($dealrs['data'])) {
                        $return_address = $dealrs['data']['complete_address'];
                    }
                }
                $custrs = $this->fx->getOrderCustomerDetail($comp_id, $order);
                if (empty($custrs['status'])) {
                    throw new \Exception($custrs['error']);
                }
                if (empty($custrs['data'])) {
                    throw new \Exception("Customer detail not found");
                }
                $deliveryRemarks = '';
                $ordLogs = $this->OrderModel->getOrderLogList($comp_id, "order_id=" . $order['id'] . " AND cs.status_type=2", true);
                if (empty($ordLogs['status'])) {
                    throw new \Exception($ordLogs['error']);
                }
                if (!empty($ordLogs['data'])) {
                    $deliveryRemarks = $ordLogs['data']['remarks'];
                }
                $table_name = $this->FxModel->client_db_prefix . $comp_id . "." . $this->MasterModel->tables['courier_pincode'];
                $pinrs = $this->FxModel->getFromTable($table_name, "pin_code=" . $custrs['data']['address_pincode'] . " AND courier_id=" . $order['courier_id']);
                if (empty($pinrs['status'])) {
                    throw new \Exception($pinrs['error']);
                }
                $item_total_qty = $this->FxModel->getOrderItemsTotalQty($comp_id, $order['id']);
                if (empty($item_total_qty['status'])) {
                    throw new \Exception($item_total_qty['error']);
                }
                $retorder[] = [
                    'order' => $order,
                    'company' => $cmprs['data'],
                    'branch' => $branchrs['data'],
                    'customer' => $custrs['data'],
                    'tax_list' => $tax_list,
                    'tax_item_list' => $tax_item_list,
                    'order_item_list' => $ordItemrs['data'],
                    'return_address' => $return_address,
                    'pincode_data' => $pinrs['data'],
                    'item_total_qty' => $item_total_qty['data'],
                    'delivery_remarks' => $deliveryRemarks
                ];
            }
            return ["status" => true, "data" => $retorder];
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
        }
    }

    public function getLeadDataForDocument($comp_id, $lead_id)
    {
        try {
            $cmprs = $this->fx->getCompanyDetail($comp_id);
            if (empty($cmprs['status'])) {
                throw new \Exception($cmprs['error']);
            }
            // $table_name = $this->FxModel->client_db_prefix . $comp_id . "." . $this->FxModel->tables['leads'];
            // $leadrs = $this->FxModel->getRowFromTable($table_name, "id=:lead_id", [":lead_id" => $lead_id]);
            $leadrs = $this->MasterModel->getMasterData($this->FxModel->client_db_prefix . $comp_id, $this->FxModel->tables['leads'], "t1.id=$lead_id");
            if (empty($leadrs['status'])) {
                throw new \Exception($leadrs['error']);
            }
            if (empty($leadrs['data'])) {
                throw new \Exception("Lead detail not found");
            }
            $leadrs['data'] = $leadrs['data'][0];
            $branchrs = $this->fx->getBranchDetail($comp_id, $this->user_data, $leadrs['data']['branch_id']);
            if (empty($branchrs['status'])) {
                throw new \Exception($branchrs['error']);
            }
            if (empty($branchrs['data'])) {
                throw new \Exception("Branch detail not found");
            }
            $ldrs = $this->MasterDataSetModel->postDataByIdProcess('leads', $this->FxModel->client_db_prefix . $comp_id, $leadrs['data'], $lead_id);

            if (empty($ldrs['status'])) {
                throw new \Exception($ldrs['error']);
            }
            if (empty($ldrs['data'])) {
                throw new \Exception("Lead Item and tax detail not found");
            }

            $retorder = [];
            // $leadrs['data']['packing']    = 'packing';
            // $leadrs['data']['ship_to']    = 'ship_to';
            // $leadrs['data']['transport']    = 'N.A.';
            // $leadrs['data']['insurance']    = 'N.A.';
            // $leadrs['data']['freight']    = 'N.A.';
            $retorder['compDetails'] = $cmprs['data'];
            $retorder['branchDetails'] = $branchrs['data'];
            $retorder['leadDetails'] = $leadrs['data'];
            $retorder['itemsDetails'] = $ldrs['data']['items'];
            $retorder['itemTaxDetails'] = $ldrs['data']['item_tax'];
            return ["status" => true, "data" => $retorder];
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
        }
    }

    public function getPDF()
    {
        try {
            $rules = [
                'document_type' => array('rules' => 'required|max_length[50]', 'label' => "Document Type")
            ];
            if (!empty($this->input['document_type'])) {
                if (in_array(strtolower($this->input['document_type']), ['invoice', 'order_items', 'courier_label', 'courier_slip'])) {
                    $rules['order_id'] = array('rules' => 'required', 'label' => "Order ID");
                } else if (in_array(strtolower($this->input['document_type']), ['leads'])) {
                    $rules['lead_id'] = array('rules' => 'required', 'label' => "Lead ID");
                } else {
                    throw new \Exception("Invalid Document type provided to get PDF");
                }
            }
            $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']));
            }
            if (in_array(strtolower($this->input['document_type']), ['invoice', 'order_items', 'courier_label', 'courier_slip'])) {
                $order_id = is_array($this->input['order_id']) ? implode(",", $this->input['order_id']) : $this->input['order_id'];
                $docrs = $this->getDataForDocument($this->user_data->comp_id, $order_id);
            } else if (in_array(strtolower($this->input['document_type']), ['leads'])) {
                $docrs = $this->getLeadDataForDocument($this->user_data->comp_id, $this->input['lead_id']);
            }
            if (empty($docrs['status'])) {
                throw new \Exception($docrs['error']);
            }
            $req_id = time();
            switch (strtolower($this->input['document_type'])) {
                case 'invoice':
                    $file_name     = count($docrs['data']) > 1 ? 'multi_order_invoice_' . $req_id . '.pdf' : 'invoice_' . $docrs['data'][0]['order']['invoice_number'] . '.pdf';
                    $pdf_content   = '';
                    foreach ($docrs['data'] as $vars) {
                        $pdf_content .= view('pdf/order_invoice', $vars);
                        $pdf_content .= "<pagebreak />";
                    }
                    break;
                case 'order_items':
                    $file_name     = count($docrs['data']) > 1 ? 'multi_order_items_' . $req_id . '.pdf' : 'order_items_' . $docrs['data'][0]['order']['order_series'] . '.pdf';
                    $pdf_content   = '';
                    foreach ($docrs['data'] as $vars) {
                        $pdf_content .= view('pdf/order_items', $vars);
                        $pdf_content .= "<pagebreak />";
                    }
                    break;
                case 'courier_label':
                    $file_name     = count($docrs['data']) > 1 ? 'multi_order_courier_label_' . $req_id . '.pdf' : 'courier_label_' . $docrs['data'][0]['order']['order_series'] . '.pdf';
                    $pdf_content   = '';
                    foreach ($docrs['data'] as $vars) {
                        if (in_array($vars['order']['courier_api_type'], array('blue_dart', 'shiprocket'))) {
                            $pdf_content .= view('pdf/courier/blue_dart', $vars);
                            $pdf_content .= "<pagebreak />";
                        } else {
                            $pdf_content .= view('pdf/courier/speed_post', $vars);
                            $pdf_content .= "<pagebreak />";
                        }
                    }
                    break;
                case 'courier_slip':
                    $file_name     = count($docrs['data']) > 1 ? 'multi_order_courier_slip_' . $req_id . '.pdf' : 'courier_slip_' . $docrs['data'][0]['order']['order_series'] . '.pdf';
                    $pdf_content   = '';
                    foreach ($docrs['data'] as $vars) {
                        if (in_array($vars['order']['courier_api_type'], array('blue_dart', 'shiprocket'))) {
                            $pdf_content .= view('pdf/courier/blue_dart', $vars);
                            $pdf_content .= "<pagebreak />";
                        } else if ($vars['order']['courier_api_type'] == 'delhivery') {
                            $pdf_content .= view('pdf/courier/delhivery', $vars);
                            $pdf_content .= "<pagebreak />";
                        } else {
                            $pdf_content .= view('pdf/courier/blue_dart', $vars);
                            $pdf_content .= "<pagebreak />";
                        }
                    }
                    break;
                case 'leads':
                    $file_name     = 'lead_pdf_' . $docrs['data']['leadDetails']['id'] . '.pdf';
                    $view = view('pdf/lead_tax_nd_item', $docrs['data']);
                    $compFolder = $_ENV['SERVER_PATH'] . '/' . $_ENV['ATTACHMENT_DIR'] . '/comp-' . $docrs['data']['compDetails']['id'];
                    $pdf_name = $docrs['data']['leadDetails']['client_name'] . '-' . $docrs['data']['leadDetails']['pdf_title'] . '-' . $docrs['data']['leadDetails']['id']. '.pdf';
                    $this->sendResponse(array('code' => 200, 'message' => 'PDF generated successfully', 'data' => $_ENV['ATTACHMENT_DIR'] . '/comp-' . $docrs['data']['compDetails']['id'] . "/" . $pdf_name));
                    break;
                default:
                    break;
            }
            
            if (!empty($file_name) && !empty($pdf_content)) {
                $filepath = Utilities::getPdfDownloadPath($file_name);
                $pdf = new Pdf(null);
                $resp = $pdf->generate($pdf_content, $filepath, 'F');
                if (empty($resp)) {
                    throw new \Exception("Something went wrong while generating PDF");
                }
                $this->sendResponse(array('code' => 200, 'message' => 'PDF generated successfully', 'data' => $file_name));
            } else {
                $this->sendResponse(array('code' => 400, 'message' => "Invalid Document type provided to get PDF", 'data' => null));
            }
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            $this->sendResponse(array('code' => 400, 'message' => "Something went wrong while generating PDF", 'data' => $e->getMessage()));
        }
    }
}
