<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\PackageModel;
use App\Models\RoleModel;
use App\Models\UserModel;
use App\Models\CustomerModel;
use App\Models\PaymentModel;
use App\Models\AreaModel;
use App\Models\OutModel;

class Dashboard extends BaseController
{

    private $CustomerModel;
    private $PackageModel;
    private $UserModel;
    private $RoleModel;
    private $PaymentModel;
    private $AreaModel;
    private $OutModel;

    public function __construct()
    {

        $this->RoleModel      = new RoleModel();   
        $this->PackageModel      = new PackageModel();
        $this->UserModel      = new UserModel();   
        $this->CustomerModel      = new CustomerModel();
        $this->PaymentModel      = new PaymentModel();
        $this->AreaModel      = new AreaModel();
        $this->OutModel      = new OutModel();
    }

    public function index()
    {

        $data   = [
            'title'         => "Dashboard",
            'masterData'    => $this->_getMasterData(),
            'chartPer'      => $this->_getChartPer(),
            'alert'         => getAlertDashboard()
        ];
        
        $prefixView = getDashboardPrefixName(session()->get('role_name'));

        return  view('app/dashboard/main/dashboard-'.$prefixView.'-css', $data) .
        view('app/dashboard/main/dashboard-'.$prefixView, $data) .
        view('app/dashboard/main/dashboard-'.$prefixView.'-js', $data);
    }

    private function _getChartPer()
    {

        $this->AreaModel->select('COUNT(tbl_customer.id) AS total, tbl_area.name AS name');
        $this->AreaModel->join('tbl_customer','tbl_customer.village_id=tbl_area.id');
        $this->AreaModel->where('UPPER(type)',strtoupper("VILLAGE"));
        $this->AreaModel->groupBy('tbl_area.id');
        $villages = $this->AreaModel->findAll();

        $this->PackageModel->select('COUNT(tbl_customer.id) AS total, tbl_package.name AS name');
        $this->PackageModel->join('tbl_customer','tbl_customer.package_id=tbl_package.id');
        $this->PackageModel->groupBy('tbl_package.id');
        $packages = $this->PackageModel->findAll();

        return (object) [
            'village'   => $villages,
            'package'   => $packages,
        ];



    }



    private function _getMasterData()
    {
        $user = $this->UserModel->select('id')->countAllResults();
        $role = $this->RoleModel->select('id')->countAllResults();
        $customer = $this->CustomerModel->select('id')->countAllResults();
        $package = $this->PackageModel->select('id')->countAllResults();

        return (object) [
            'user'  => $user,
            'role'  => $role,
            'customer'  => $customer,
            'package'  => $package,
        ];

    }


    public function getPaymentCount()
    {
        
        $request    = $this->request->getJSON();

        $this->CustomerModel->select('id');
        $customers = $this->CustomerModel->findAll();

        if(empty($customers)){
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => true,
                'message'   => "Customer is empty",
                'data'      => [
                        'has'   => 0,
                        'hasnt' => 0,
                ]
            ]);
        }

        $date   = $request->month ?? date("Y-m");
        $month  = date('m',strtotime($date));
        $year   = date('Y',strtotime($date));
        $has    = 0;
        $hasnt  = 0;
        foreach($customers AS $customer){
            
            $this->PaymentModel->select('id');
            $this->PaymentModel->where('customer_id',$customer->id);
            $this->PaymentModel->where('MONTH(date)',$month);
            $this->PaymentModel->where('YEAR(date)',$year);
            $this->PaymentModel->groupBy('customer_id');
            $pay = $this->PaymentModel->first();

            if(!empty($pay)){
                $has++;
            }else{
                $hasnt++;
            }

        }


        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Successfully",
            'data'      => [
                'has'   => $has,
                'hasnt' => $hasnt
            ]
        ]);





    }



    public function getOutInTotal()
    {

        $request    = $this->request->getJSON();

        $date   = $request->month ?? date("Y-m");
        $month  = date('m',strtotime($date));
        $year   = date('Y',strtotime($date));

        $totalIn    = 0;
        $totalOut  = 0;
        
        $this->PaymentModel->select('SUM(total) AS total');
        $this->PaymentModel->where('MONTH(created_at)',$month);
        $this->PaymentModel->where('YEAR(created_at)',$year);
        $in = $this->PaymentModel->first();

        if(!empty($in)){
            $totalIn = $in->total;
        }

        $this->OutModel->select('SUM(total) AS total');
        $this->OutModel->where('MONTH(date)',$month);
        $this->OutModel->where('YEAR(date)',$year);
        $out = $this->OutModel->first();

        if(!empty($out)){
            $totalOut = $out->total;
        }


        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Successfully",
            'data'      => [
                'totalIn'   => $totalIn ?? 0,
                'totalOut' => $totalOut ?? 0
            ]
        ]);



    }

    public function getLineOutIn()
    {


        $request    = $this->request->getJSON();
        $type       = $request->type ?? "WEEK";


        if(strtoupper($type)=="WEEK"){

            $in         = [
                'y'     => [],
                'x'     => [],
            ];
            $out        = [
                'y'     => [],
                'x'     => [],
            ];

            $firstDayOfWeek = new \DateTime('this week monday');
            $lastDayOfWeek = new \DateTime('this week sunday');

            $interval = new \DateInterval('P1D');
            $period = new \DatePeriod($firstDayOfWeek, $interval, $lastDayOfWeek->modify('+1 day')); 

            foreach ($period as $date) {

                $this->PaymentModel->select('SUM(total) AS total');
                $this->PaymentModel->where('DATE(created_at)',$date->format('Y-m-d'));
                $totalIn = $this->PaymentModel->first();


                if(!empty($totalIn)){
                    $in['y'][] = intval($totalIn->total) ?? 0;
                }else{
                    $in['y'][] = 0;
                }


                $this->OutModel->select('SUM(total) AS total');
                $this->OutModel->where('DATE(date)',$date->format('Y-m-d'));
                $totalOut = $this->OutModel->first();

                if(!empty($totalOut)){
                    $out['y'][] = intval($totalOut->total) ?? 0;
                }else{
                    $out['y'][] = 0;
                }


                $in['x'][] = $date->format('d');
                $out['x'][] = $date->format('d');
            }

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => true,
                'message'   => "Successfully",
                'data'      => [
                    'in'    => $in,
                    'out'   => $out,
                ]
            ]);

        }else if(strtoupper($type)=="MONTH"){


            $in         = [
                'y'     => [],
                'x'     => [],
            ];
            $out        = [
                'y'     => [],
                'x'     => [],
            ];

            $firstDayOfMonth = new \DateTime('first day of this month');
            $lastDayOfMonth = new \DateTime('last day of this month');

            $interval = new \DateInterval('P1D');
            $period = new \DatePeriod($firstDayOfMonth, $interval, $lastDayOfMonth->modify('+1 day'));

            foreach ($period as $date) {

                $this->PaymentModel->select('SUM(total) AS total');
                $this->PaymentModel->where('DATE(created_at)',$date->format('Y-m-d'));
                $totalIn = $this->PaymentModel->first();


                if(!empty($totalIn)){
                    $in['y'][] = intval($totalIn->total) ?? 0;
                }else{
                    $in['y'][] = 0;
                }


                $this->OutModel->select('SUM(total) AS total');
                $this->OutModel->where('DATE(date)',$date->format('Y-m-d'));
                $totalOut = $this->OutModel->first();

                if(!empty($totalOut)){
                    $out['y'][] = intval($totalOut->total) ?? 0;
                }else{
                    $out['y'][] = 0;
                }


                $in['x'][] = $date->format('d');
                $out['x'][] = $date->format('d');
            }

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => true,
                'message'   => "Successfully",
                'data'      => [
                    'in'    => $in,
                    'out'   => $out,
                ]
            ]);

        }else if(strtoupper($type)=="YEAR"){

            $in = [
                'y' => [],
                'x' => []
            ];
            
            $out = [
                'y' => [],
                'x' => []
            ];

            $currentDate = new \DateTime();
            $currentYear = $currentDate->format('Y');
            
            for ($month = 1; $month <= 12; $month++) {
                
                $firstDayOfMonth = new \DateTime("$currentYear-$month-01");
                $lastDayOfMonth = new \DateTime("$currentYear-$month-01");
                $lastDayOfMonth->modify('last day of this month');
                
                $monthName = $firstDayOfMonth->format('M');

                $this->PaymentModel->select('SUM(total) AS total');
                $this->PaymentModel->where('DATE(created_at) >=', $firstDayOfMonth->format('Y-m-d'));
                $this->PaymentModel->where('DATE(created_at) <=', $lastDayOfMonth->format('Y-m-d'));
                $totalIn = $this->PaymentModel->first();
                $in['y'][] = !empty($totalIn->total) ? intval($totalIn->total) : 0;
                $in['x'][] = $monthName;

                $this->OutModel->select('SUM(total) AS total');
                $this->OutModel->where('date >=', $firstDayOfMonth->format('Y-m-d'));
                $this->OutModel->where('date <=', $lastDayOfMonth->format('Y-m-d'));
                $totalOut = $this->OutModel->first();
                $out['y'][] = !empty($totalOut->total) ? intval($totalOut->total) : 0;
                $out['x'][] = $monthName;
            }

            return $this->response->setJSON([
                'code' => 200,
                'success' => true,
                'message' => "Successfully",
                'data' => [
                    'in' => $in,
                    'out' => $out
                ]
            ]);

        }


    }



























    public function loadData()
    {
        $this->AreaModel->select('id, name, latitude, longitude');
        $areas = $this->AreaModel->findAll();

        if (empty((array) $areas)) {
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => true,
                'message'   => "Empty area",
                'data'      => []
            ]);
        }


        $data = [];
        foreach ($areas as $area) {
            
            $this->GoodModel->select('id, name, latitude, longitude');
            $this->GoodModel->where('area_id',$area->id);
            $area->goods = $this->GoodModel->findAll();

            $data[] = $area;

        }

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Successfully",
            'data'      => $data
        ]);

        
    }


    public function add()
    {

        $data = [
            'title' => "Tambah Role"
        ];

        return  view('app/role/add/role-add-css', $data) .
        view('app/role/add/role-add', $data) .
        view('app/role/add/role-add-js', $data);
    }

    public function save()
    {

        $request;
        if ($this->request->hasHeader('Content-Type') && strpos($this->request->getHeaderLine('Content-Type'), 'application/json') !== false) {
            $request    = $this->request->getJSON();
        }else{
            $request    = $this->request->getPOST();
        }

        $request = json_decode(json_encode($request));

        if(empty($request->name)){
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => [
                    'name'      => "Nama tidak boleh kosong"
                ]
            ]);
        }

        if(strlen(trim($request->name))<3){
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => [
                    'name'      => "Nama tidak boleh kurang dari 3 karakter"
                ]
            ]);
        }


        $data = [
            'name'  => $request->name,
            'created_by'  => session()->id,
            'created_at'  => date('Y-m-d H:i:s'),
        ];

        if(!$this->RoleModel->insert($data)){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Data gagal disimpan. pastikan anda terkoneksi dengan internet"
            ]);
        }

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Data berhasil disimpan"
        ]);


    }


    public function getAllData()
    {
        
        $this->RoleModel->draw     = $this->request->getPOST('draw');
        $this->RoleModel->start    = $this->request->getPOST('start');
        $this->RoleModel->limit    = $this->request->getPOST('length');
        $this->RoleModel->search   = $this->request->getPOST('search')['value'];
        $this->RoleModel->columns  = $this->request->getPOST('columns');
        $this->RoleModel->order    = $this->request->getPOST('order');

        echo $this->RoleModel->getAllData();
    }

    public function delete()
    {

        $request;
        if ($this->request->hasHeader('Content-Type') && strpos($this->request->getHeaderLine('Content-Type'), 'application/json') !== false) {
            $request    = $this->request->getJSON();
        }else{
            $request    = $this->request->getPOST();
        }

        $request = json_decode(json_encode($request));


        $this->RoleModel->where('id', $request->id);
        if(!$this->RoleModel->delete()){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Data gagal dihapus. pastikan anda terkoneksi dengan internet"
            ]);
        }

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Data berhasil dihapus"
        ]);

    }


    public function edit($id = null)
    {


        $data = [
            'title' => "Edit Role",
            'row'   => $this->RoleModel->find($id)
        ];

        return  view('app/role/edit/role-edit-css', $data) .
        view('app/role/edit/role-edit', $data) .
        view('app/role/edit/role-edit-js', $data);
        
    }



    public function update()
    {

        $request;
        if ($this->request->hasHeader('Content-Type') && strpos($this->request->getHeaderLine('Content-Type'), 'application/json') !== false) {
            $request    = $this->request->getJSON();
        }else{
            $request    = $this->request->getPOST();
        }

        $request = json_decode(json_encode($request));

        if(empty($request->name)){
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => [
                    'name'      => "Nama tidak boleh kosong"
                ]
            ]);
        }

        if(strlen(trim($request->name))<3){
            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => [
                    'name'      => "Nama tidak boleh kurang dari 3 karakter"
                ]
            ]);
        }

        $data = [
            'name'  => $request->name,
            'updated_by'  => session()->id,
            'updated_at'  => date('Y-m-d H:i:s'),
        ];

        if(!$this->RoleModel->update($request->id,$data)){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Data gagal disimpan. pastikan anda terkoneksi dengan internet"
            ]);
        }

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Data berhasil disimpan"
        ]);


    }


    public function getAllRoleName()
    {
        $page  = $this->request->getPOST('page') ? $this->request->getPOST('page') - 1 : 0;
        $limit = $this->request->getPOST('limit') ? $this->request->getPOST('limit') : 30;

        $this->RoleModel->name          = $this->request->getPOST('name');
        $this->RoleModel->limit         = $limit;
        $this->RoleModel->start         = ($page * $limit);

        echo $this->RoleModel->getAllRoleName();
    }


    private function _getCountData()
    {

        $this->AreaModel->select('id');
        $area = count($this->AreaModel->findAll());

        $this->UserModel->select('id');
        $user = count($this->UserModel->findAll());

        $this->GoodModel->select('id');
        $good = count($this->GoodModel->findAll());

        // $this->goodModel->select('id');
        $inspector = 0;

        return (object) [
            'good'  => $good,
            'user'  => $user,
            'area'  => $area,
            'inspector'  => $inspector,
        ];


    }

}

