<?php
namespace App\Controllers;

use App\Models\Hargamodel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

use CodeIgniter\API\ResponseTrait;
use App\Models\Takeawaymodel;
use App\Models\Takeawaydetailmodel;
use App\Models\Pajakmodel;
use App\Models\Transaksitakeawaymodel;

use Dompdf\Dompdf;
use Dompdf\Options;

class Takeaway extends BaseController
{
    use ResponseTrait;

    private $user;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) 
    {
        parent::initController($request, $response, $logger);
        $this->user = service("user_data");
    }

    private function check_access(){
        $user = service("user_data");
        if($user->data->group != 'admin'){
            return false;
        }else{
            return true;
        }
    }

    public function index(){
        $data['user'] = $this->user->data;
        $takeawaymodel = new Takeawaymodel();
        $builder = $takeawaymodel->builder("vtakeaway");
        $builder->where("status","open");
        $data['takeaway'] = $builder->get()->getResult();

        return view('admin/takeaway/index',$data);
    }

    public function add(){
        $data['user'] = $this->user->data;

        return view('admin/takeaway/add',$data);
    }

    public function add_save()
    {
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $request = [
            'tanggal' => $this->request->getPost('tanggal',FILTER_SANITIZE_ADD_SLASHES),
            'nama' => $this->request->getPost('nama',FILTER_SANITIZE_ADD_SLASHES)
        ];

        $validation = \Config\Services::validation();
        $validation->setRule('tanggal', 'Tanggal', 'required');
        $validation->setRule('nama', 'Nama', 'required');

        if (!$validation->run($request)) {
            return $this->fail($validation->getErrors(),400,null,'input');
        }else{
            $tmodel = new Takeawaymodel();
            $tmodel->db->transBegin();
            $request['id_operator'] = $user->id_user;

            $tahunbulan = date("Ym");
            $kode = $tmodel->getNewKode($tahunbulan);
            if(empty($kode)){
                return $this->fail(["error" => "Generate Kode Error!"],400,null,'db');
            }
            $request['kode_takeaway'] = $kode;

            $id = $tmodel->insert($request);
            if($tmodel->db->transStatus() === false){
                $tmodel->db->transRollback();
                return $this->fail($tmodel->errors(),400,null,'db');
            }else{
                $tmodel->db->transCommit();
                $data['id_takeaway'] = $id;
                return $this->respond($data,200);
            }
        }
    }

    public function pesanan($id){
        $data['user'] = $this->user->data;
        
        $takeawaymodel = new Takeawaymodel();
        $builder = $takeawaymodel->builder("vtakeaway");
        $builder->where("id_takeaway",$id);
        $takeaway = $builder->get()->getRow();
        if($takeaway){
            $data['emode'] = '1';
            $data['takeaway'] = $takeaway;
            $takeawaydetailmodel = new Takeawaydetailmodel();
            $builder = $takeawaydetailmodel->builder("vtakeawaydetail");
            $data['takeaway_detail'] = $builder->where("id_takeaway",$takeaway->id_takeaway)->get()->getResult();
        }else{
            $data['emode'] = '0';
        }

        return view('admin/takeaway/pesanan',$data);
    }

    public function list_products(){
        $db = db_connect();
        $q     = $this->request->getGet('q') ?? '';
        $page  = max(1, (int) $this->request->getGet('page'));
        $limit = max(1, (int) $this->request->getGet('limit'));
        $offset = ($page - 1) * $limit;
        
        $builder = $db->table('vproduk');
        if ($q !== '') {
            $builder->groupStart()
                    ->like('nama_produk', $q)
                    ->orLike('kode_produk', $q)
                    ->groupEnd();
        }

        $total = $builder->countAllResults(false); // tidak reset query
        $builder->orderBy('nama_produk', 'ASC')
                ->limit($limit, $offset);
        $query = $builder->get();

        $data = $query->getResultArray();

        return $this->response->setJSON([
            'data' => $data,
            'page' => $page,
            'per_page' => $limit,
            'total' => $total
        ]);
    }

    public function save_order()
    {
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $json_request = $this->request->getJson();

        $id_takeaway = $json_request->id_takeaway;
        $emode = $json_request->emode;
        $items = $json_request->items;
        $kode = $json_request->kode_takeaway;

        $request = [
            'nama' => $json_request->nama,
            'tanggal' => $json_request->tanggal,
        ];

        $validation = \Config\Services::validation();
        $validation->setRule('nama', 'Nama', 'required');

        if (!$validation->run($request)) {
            return $this->fail($validation->getErrors(),400,null,'input');
        }else{
            $takeawaymodel = new Takeawaymodel();
            $takeawaymodel->db->transBegin();

            $takeawaydetailmodel = new Takeawaydetailmodel();
            $takeawaydetailmodel->db->transBegin();

            $builder = $takeawaymodel->builder();
            $builder->where("id_takeaway", $id_takeaway);
            $builder->where("status", "open");
            $takeaway = $builder->get()->getRow();
            if(!$takeaway){
                return $this->fail(["error" => "Invalid Order!"],400,null,'db');
            }

            if(empty($kode)){
                $tahunbulan = date("Ym");
                $kode = $takeawaymodel->getNewKode($tahunbulan);
                if(empty($kode)){
                    return $this->fail(["error" => "Generate Kode Error!"],400,null,'db');
                }
            }
            $request['kode_takeaway'] = $kode;
            $takeawaymodel->update($id_takeaway, $request);

            $builder = $takeawaydetailmodel->builder();
            $builder->where("id_takeaway",$id_takeaway);
            $builder->delete();
            foreach($items as $item){
                $hargamodel = new Hargamodel();
                $builder = $hargamodel->builder();
                $harga = $builder->where("id_harga",$item->id_harga)->get()->getRow();
                if(!$harga){
                    $takeawaymodel->db->transRollback();
                    $takeawaydetailmodel->db->transRollback();
                    return $this->fail(["error" => "Invalid Harga!"],400,null,'db');
                }

                $q = [
                    "id_takeaway" => $id_takeaway,
                    "id_produk" => $item->id_produk,
                    "id_harga" => $item->id_harga,
                    "harga_modal" => $harga->harga_modal,
                    "harga_jual" => $harga->harga_jual,
                    "qty" => $item->qty,
                    "subtotal" => ($item->qty * $harga->harga_jual)
                ];

                $takeawaydetailmodel->insert($q);
                if($takeawaydetailmodel->db->transStatus() === false){
                    $takeawaymodel->db->transRollback();
                    $takeawaydetailmodel->db->transRollback();
                    return $this->fail(["error" => "Items Insert Failed!"],400,null,'db');
                }
            }

            $takeawaymodel->db->transCommit();
            $takeawaydetailmodel->db->transCommit();

            $data['id_takeaway'] = $id_takeaway;
            return $this->respond($data,200);
        }
    }

    public function cancel_order()
    {
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $json_request = $this->request->getJson();

        $id_takeaway = $json_request->id_takeaway;
        // $emode = $json_request->emode;
        $items = $json_request->items;

        $request = [
            'nama' => $json_request->nama,
            'tanggal' => $json_request->tanggal,
        ];

        $validation = \Config\Services::validation();
        $validation->setRule('nama', 'Nama', 'required');

        if (!$validation->run($request)) {
            return $this->fail($validation->getErrors(),400,null,'input');
        }else{
            $takeawaymodel = new Takeawaymodel();
            $takeawaymodel->db->transBegin();

            $builder = $takeawaymodel->builder();
            $builder->where("id_takeaway",$id_takeaway);
            $order = $builder->get()->getRow();
            if(!$order){
                return $this->fail(["error" => "Invalid Takeaway! Silahkan lakukan simpan takeaway terlebih dahulu..."],400,null,'db');
            }
            $takeawaymodel->update($order->id_order,["status" => "canceled"]);

            $transaksitakeawaymodel = new Transaksitakeawaymodel();
            $transaksitakeawaymodel->db->transBegin();
            $builder = $transaksitakeawaymodel->builder();
            $builder->where("id_takeaway",$order->id_order);
            $builder->where("status","closed");
            $transaksi = $builder->get()->getRow();
            if($transaksi){
                $transaksitakeawaymodel->update($transaksi->id_transaksi,["status" => "canceled"]);
                if($transaksitakeawaymodel->db->transStatus() === false){
                    $takeawaymodel->db->transRollback();
                    return $this->fail(["error" => "DB Error! Transaction update.."],400,null,'db');
                }
            }
            $takeawaymodel->db->transCommit();
            $transaksitakeawaymodel->db->transCommit();

            $data['id_takeaway'] = $id_takeaway;
            return $this->respond($data,200);
        }
    }

    public function checkout($id_takeaway){
        $data['user'] = $this->user->data;
        $takeawaymodel = new Takeawaymodel();
        $builder = $takeawaymodel->builder("vtakeaway");
        $builder->where("id_takeaway",$id_takeaway);
        $takeaway = $builder->get()->getRow();
        if(!$takeaway){
            die('Takeaway not found!');
            $data['error'] = "Takeaway not found!";
            return view('admin/takeaway/checkout_error',$data);
        }

        $pajakmodel = new Pajakmodel();
        $builder = $pajakmodel->builder();
        $builder->where("status","aktif");
        $builder->orderBy("updated_at","DESC");
        $builder->limit(1);
        $data['pajak'] = $builder->get()->getRow();

        $data['takeaway'] = $takeaway;

        return view('admin/takeaway/checkout',$data);
    }

    public function get_order_items($id_takeaway){
        $takeawaydetailmodel = new Takeawaydetailmodel();
        $builder = $takeawaydetailmodel->builder("vtakeawaydetail");
        $builder->where("id_takeaway", $id_takeaway);
        $takeawaydetail = $builder->get()->getResultArray();

        $transaksitakeawaymodel = new Transaksitakeawaymodel();
        $builder = $transaksitakeawaymodel->builder("vtransaksitakeaway");
        $builder->where("id_takeaway",$id_takeaway);
        $builder->where("status","closed");
        $transaksi = $builder->get()->getRow();
        
        $data_transaksi = [
            "id_transaksi_takeaway" => "0",
            "diskon_nominal" => 0,
            "diskon_persen" => 0,
            "pajak_persen" => 0,
            "service_persen" => 0,
            "pembulatan" => "0",
            "tunai" => 0,
            "metode" => "cash"
        ];

        if($transaksi){
            $data_transaksi = [
                "id_transaksi_takeaway" => $transaksi->id_transaksi_takeaway,
                "diskon_nominal" => $transaksi->diskon_nominal,
                "diskon_persen" => $transaksi->diskon_persen,
                "pajak_persen" => $transaksi->pajak_persen,
                "service_persen" => $transaksi->service_persen,
                "pembulatan" => $transaksi->pembulatan,
                "tunai" => $transaksi->tunai,
                "metode" => $transaksi->metode
            ];
        }else{
            $pajakmodel = new Pajakmodel();
            $builder = $pajakmodel->builder();
            $builder->where("status","aktif");
            $builder->orderBy("updated_at","DESC");
            $builder->limit(1);
            $pajak = $builder->get()->getRow();
            if($pajak){
                $data_transaksi['pajak_persen'] = $pajak->persen;
            }
        }
        return $this->response->setJSON([
            'items' => $takeawaydetail,
            'transaksi' => $data_transaksi
        ]);
    }

    public function checkout_submit()
    {
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $json_request = $this->request->getJson();

        $id_takeaway = $json_request->id_takeaway;
        $subtotal = $json_request->summary->subtotal;
        $diskon_persen = $json_request->summary->diskon_persen;
        $diskon_nominal = $json_request->summary->diskon_nominal;
        $diskon_total = $json_request->summary->diskon_total;
        $pajak_persen = $json_request->summary->pajak_persen;
        $pajak_nominal = $json_request->summary->pajak_nominal;
        $service_persen = $json_request->summary->service_persen;
        $service_nominal = $json_request->summary->service_nominal;
        $pembulatan = $json_request->summary->pembulatan_step;
        $grand_total = $json_request->summary->grand_total;

        $metode = $json_request->payment->method;
        $metode_ref = $json_request->payment->reference;
        $tunai = $json_request->payment->bayar_tunai;
        $kembalian = $json_request->payment->kembalian;

        if ($metode=="cash" && ($tunai<$grand_total)) {
            return $this->fail(["error" => "Jumlah bayar tidak sesuai!"],400,null,'data');
        }else{
            $takeawaymodel = new Takeawaymodel();
            $takeawaymodel->db->transBegin();

            $transaksitakeawaymodel = new Transaksitakeawaymodel();
            $transaksitakeawaymodel->db->transBegin();

            $builder = $takeawaymodel->builder("vtakeaway");
            $builder->where("id_takeaway",$id_takeaway);
            $builder->where("status","open");
            $order = $builder->get()->getRow();
            if(!$order){
                return $this->fail(["error" => "Order sudah di closed/canceled! Silahkan Periksa Kembali"],400,null,'data');
            }

            $builder = $transaksitakeawaymodel->builder("vtransaksitakeaway");
            $builder->where("id_takeaway",$id_takeaway);
            $builder->where("status","closed");
            $transaksi = $builder->get()->getRow();
            if($transaksi){
                return $this->fail(["error" => "Transaksi sudah di closed! Silahkan Periksa Kembali atau Batalkan Transaksi terlebih dahulu.."],400,null,'data');
            }

            $total_modal = 0;
            $total_jual = 0;
            $total_bayar = 0;

            $takeawaydetailmodel = new Takeawaydetailmodel();
            $builder = $takeawaydetailmodel->builder("vtakeawaydetail");
            $builder->where("id_takeaway", $id_takeaway);
            $orderdetail = $builder->get()->getResult();
            foreach($orderdetail as $detail){
                $total_modal += ($detail->harga_modal * $detail->qty);
                $total_jual += ($detail->harga_jual * $detail->qty);
                $total_bayar += (($detail->harga_jual * $detail->qty) - ($detail->harga_jual * $detail->qty));
            }

            $insert_transaksi = [
                "id_takeaway" => $id_takeaway,
                "tanggal_transaksi" => date("Y-m-d H:i:s"),
                "total_modal" => $total_modal,
                "total_jual" => $total_jual,
                "total_bayar" => $total_bayar,
                "tunai" => $tunai,
                "kembalian" => $kembalian,
                "metode" => $metode,
                "metode_ref" => $metode_ref,
                "id_operator" => $user->id_user,
                "diskon_persen" => $diskon_persen,
                "diskon_nominal" => $diskon_nominal,
                "diskon_total" => $diskon_total,
                "pajak_persen" => $pajak_persen,
                "pajak_nominal" => $pajak_nominal,
                "service_persen" => $service_persen,
                "service_nominal" => $service_nominal,
                "pembulatan" => $pembulatan,
                "grand_total" => $grand_total,
                "status" => "closed"
            ];

            $id_transaksi_takeaway = $transaksitakeawaymodel->insert($insert_transaksi);
            if($transaksitakeawaymodel->db->transStatus() === false){
                return $this->fail(["error" => "DB Error Transaksi"],400,null,'data');
            }

            $takeawaymodel->update($id_takeaway,["status" => "closed", "checkout_at" => date("Y-m-d H:i:s")]);
            if($takeawaymodel->db->transStatus() === false){
                return $this->fail(["error" => "DB Error Order"],400,null,'data');
            }

            $takeawaymodel->db->transCommit();
            $transaksitakeawaymodel->db->transCommit();
            
            $data['id_transaksi_takeaway'] = $id_transaksi_takeaway;
            return $this->respond($data,200);
        }
    }

    public function print_struk($id_takeaway){
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $takeawaymodel = new Takeawaymodel();
        $builder = $takeawaymodel->builder("vtakeaway");
        $builder->where("id_takeaway", $id_takeaway);
        $takeaway = $builder->get()->getRow();
        if(!$takeaway){
            die("Order not found!");
        }

        $transaksitakeawaymodel = new Transaksitakeawaymodel();
        $builder = $transaksitakeawaymodel->builder("vtransaksitakeaway");
        $builder->where("id_takeaway", $id_takeaway);
        $builder->where("status", "closed");
        $transaksi = $builder->get()->getRow();
        if(!$transaksi){
            die("Transaksi not found!");
        }

        $dibayar = 0;
        $kembalian = 0;
        if($transaksi->metode == 'cash'){
            $dibayar = $transaksi->tunai;
            $kembalian = $transaksi->kembalian;
        }else{
            $dibayar = $transaksi->grand_total;
        }

        $order = [
            'kode'   => $takeaway->kode_takeaway,
            'nama'   => $takeaway->nama,
            'tanggal'=> date('Y-m-d H:i:s'),
            'kasir'  => $takeaway->nama_operator,
            'metode' => $transaksi->metode,
            'dibayar'=> $dibayar,
            'kembalian'=> $kembalian,
        ];

        $items = [];

        $subtotal = 0;

        $takeawaydetailmodel = new Takeawaydetailmodel();
        $builder = $takeawaydetailmodel->builder("vtakeawaydetail");
        $builder->where("id_takeaway", $id_takeaway);
        $orderdetails = $builder->get()->getResult();
        foreach($orderdetails as $detail){
            $items[] = [
                'nama' => $detail->nama_produk,
                'qty' => $detail->qty,
                'harga' => $detail->harga_jual,
                'subtotal' => $detail->subtotal
            ];
            $subtotal += $detail->subtotal;
        }

        $total = [
            'subtotal'=>$subtotal,
            'diskon'=>$transaksi->diskon_total,
            'pajak'=>$transaksi->pajak_nominal,
            'grand_total'=>$transaksi->grand_total,
        ];

        $html = view('print/receipt_58mm_takeaway', compact('order','items','total'));

        $opt = new Options();
        $opt->set('isHtml5ParserEnabled', true);
        $opt->set('defaultFont', 'DejaVu Sans');
        $pdf = new Dompdf($opt);
        $pdf->loadHtml($html, 'UTF-8');
        $pdf->setPaper([0,0,164,1000], 'portrait'); // 58mm
        $pdf->render();
        return $pdf->stream('struk-'.$order['kode'].'.pdf', ['Attachment'=>false]);
    }

    public function cancel_transaksi()
    {
        $data = array();
        $data['status'] = 'success';
        $user = $this->user->data;

        $json_request = $this->request->getJson();

        $id_transaksi_takeaway = $json_request->id_transaksi_takeaway;
        
        $takeawaymodel = new Takeawaymodel();
        $takeawaymodel->db->transBegin();
        $transaksitakeawaymodel = new Transaksitakeawaymodel();
        $transaksitakeawaymodel->db->transBegin();

        $builder = $transaksitakeawaymodel->builder("vtransaksitakeaway");
        $builder->where("id_transaksi_takeaway",$id_transaksi_takeaway);
        $builder->where("status","closed");
        $transaksi = $builder->get()->getRow();
        if(!$transaksi){
            return $this->fail(["error" => "Invalid closed transaction! Silahkan Periksa Kembali"],400,null,'data');
        }

        $builder = $takeawaymodel->builder("vtakeaway");
        $builder->where("id_takeaway",$transaksi->id_takeaway);
        $builder->where("status","closed");
        $takeaway = $builder->get()->getRow();
        if(!$takeaway){
            return $this->fail(["error" => "Invalid closed order! Silahkan Periksa Kembali"],400,null,'data');
        }

        $takeawaymodel->update($transaksi->id_takeaway,["status" => "open", "checkout_at" => null]);
        if($takeawaymodel->db->transStatus() === false){
            return $this->fail(["error" => "DB Error Order"],400,null,'data');
        }

        $transaksitakeawaymodel->update($id_transaksi_takeaway,["status" => "canceled"]);
        if($transaksitakeawaymodel->db->transStatus() === false){
            return $this->fail(["error" => "DB Error Order"],400,null,'data');
        }

        $takeawaymodel->db->transCommit();
        $transaksitakeawaymodel->db->transCommit();
        
        return $this->respond($data,200);
    }

    public function riwayat()
    {
        $data['user'] = $this->user->data;
        return view('admin/takeaway/riwayat',$data);
    }

    public function ajax_dt(){
        $data_post = [
            'draw' => $this->request->getPost('draw'),
            'columns' => $this->request->getPost('columns'),
            'order' => $this->request->getPost('order'),
            'start' => $this->request->getPost('start'),
            'length' => $this->request->getPost('length'),
            'search' => $this->request->getPost('search'),
            'searchBuilder' => $this->request->getPost('searchBuilder'),
        ];
        $DataModel = new Takeawaymodel();
        return $DataModel->GetDT($data_post,"");
    }

    public function view_riwayat($id){
        $data['user'] = $this->user->data;
        $takeawayodel = new Takeawaymodel();
        $builder = $takeawayodel->builder("vtakeaway");
        $data['takeaway'] = $builder->where("id_takeaway",$id)->get()->getRow();
        
        if(!$data['takeaway']){
            die('<h4>Invalid Data!</h4>');
        }

        $takeawaydetailmodel = new Takeawaydetailmodel();
        $builder = $takeawaydetailmodel->builder("vtakeawaydetail");
        $data['takeaway_detail'] = $builder->where("id_takeaway",$data['takeaway']->id_takeaway)->get()->getResult();

        $data['emode'] = '1';
        return view('admin/takeaway/view_riwayat',$data);
    }
}
?>