<?php

namespace App\Controllers\Front\Billing;

use App\Controllers\Front\FrontController;
use App\Entities\BillingEntity;
use App\Models\BillingModel;
use App\Models\OrderBillingModel;
use App\Models\OrderModel;
use App\Models\UserModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

class BillingController extends FrontController
{
    const DEFAULT_CATEGORY = "billing";
    private $_userModel = null;
    private $_orderModel = null;
    private $_orderBillingModel = null;
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->_model                   = new BillingModel();
        $this->_viewDatas['className']  = 'Billing';
        $this->_viewPath .= strtolower($this->_viewDatas['className']);
        $this->_viewDatas['title'] = lang($this->_viewDatas['className'] . '.title');
        $this->_viewDatas['class_icon'] = CLASS_ICONS[strtoupper($this->_viewDatas['className'])];
        helper($this->_viewDatas['className']);
        //사용자정보
        $this->_viewDatas['user'] = $this->getUserModel()->getEntity([$this->getUserModel()->getPrimaryKey() => $this->_viewDatas['auth'][AUTH_FIELDS['ID']]]);
    }

    final protected function getUserModel(): UserModel
    {
        return $this->_userModel = $this->_userModel ?: new UserModel();
    }

    final protected function getOrderModel(): OrderModel
    {
        return $this->_orderModel = $this->_orderModel ?: new OrderModel();
    }
    final protected function getOrderBillingModel(): OrderBillingModel
    {
        return $this->_orderBillingModel = $this->_orderBillingModel ?: new OrderBillingModel();
    }

    public function getFields(string $action = ""): array
    {
        switch ($action) {
            case "insert":
                return ["price"];
                break;
            case "index":
            case "excel":
                return ["title", "price", "email", "phone", "type", "status", "created_at"];
                break;
            case "view":
                return ["title", "price", "email", "phone", "type", "status", "updated_at", "created_at", 'response'];
                break;
            default:
                return [];
                break;
        }
    }
    public function getFieldFilters(): array
    {
        return ["status"];
    }
    public function getFieldBatchFilters(): array
    {
        return ["status"];
    }

    //청구서용 Order정보 가져오기
    private function getOrdersByBillingEntity(BillingEntity $entity): array
    {
        $orderBillings = $this->getOrderBillingModel()->getEntitys(['billing_uid' => $entity->getPrimaryKey()]);
        $orders        = array();
        foreach ($orderBillings as $orderBilling) {
            array_push(
                $orders,
                $this->getOrderModel()->getEntity(
                    [$this->getOrderModel()->getPrimaryKey() => $orderBilling->order_uid],
                ),
            );
        }
        return $orders;
    }

    //Insert관련 (결제처리용)
    protected function insert_form_process()
    {
        parent::insert_form_process();
    }

    //청구서처리
    protected function insert_process()
    {
        //청구서 title지정하기
        $this->_viewDatas['fieldDatas']['title'] = date("Y년m월") . " 청구서입니다.";
        //청구서용 고객정보지정하기
        $user                                    = $this->getUserModel()->getData($this->_viewDatas['user']);
        $this->_viewDatas['fieldDatas']['email'] = $user->getEmail();
        $this->_viewDatas['fieldDatas']['phone'] = $user->getPhone();
        $entity                                  = parent::insert_process();

        //주문정보 가져오기
        $order_uids = $this->request->getVar('order_uids') ?: throw new \Exception("주문정보가 지정되지 않았습니다.");
        $orders     = array();
        foreach ($order_uids as $order_uid) {
            $order = $this->getOrderModel()->getEntity([$this->getOrderModel()->getPrimaryKey() => $order_uid]);
            $this->getOrderBillingModel()->create([
                "billing_uid" => $entity->getPrimaryKey(),
                'order_uid'   => $order->getPrimaryKey(),
            ]);
            $this->getOrderModel()->modify($order, ['status' => 'status']);
        }
        return $entity;
    }

    //Update관련
    protected function update_form_process($entity)
    {
        //청구서 연결 주문정보 가져오기
        $this->_viewDatas['orders'] = $this->getOrdersByBillingEntity($entity);
        if (!count($this->_viewDatas['orders'])) {
            throw new \Exception("해당하는 주문정보가 없습니다.");
        }
        return parent::update_form_process($entity);
    }

    //View 관련
    protected function view_process($entity)
    {
        $entity = parent::view_process($entity);
        //청구서 연결 주문정보 가져오기
        $this->_viewDatas['orders'] = $this->getOrdersByBillingEntity($entity);
        if (!count($this->_viewDatas['orders'])) {
            throw new \Exception("해당하는 주문정보가 없습니다.");
        }
        return $entity;
    }

    //Index관련
    protected function index_process()
    {
        //Category 확인
        $this->setCategory($this->request->getVar('category') ?: self::DEFAULT_CATEGORY);
        parent::index_process();
    }
    protected function index_condition()
    {
        //사용자정보(user_uid)에 맞는 Biiling정보 가져오기
        $this->_model->where('user_uid', $this->_session->get(SESSION_NAMES['AUTH'])[AUTH_FIELDS['ID']]);
        parent::index_condition();
    }

    //추가기능
    //메일발송
    final protected function sendMail(BillingEntity $entity): bool
    {
        $this->_viewDatas           = $this->action_init(['action' => __FUNCTION__]);
        $this->_viewDatas['entity'] = $entity;
        $this->_viewDatas['orders'] = $this->getOrdersByBillingEntity($entity);

        $mail = \Config\Services::email();
        $mail->setFrom(MALLS['support'], MALLS['title'], MALLS['master']);
        $mail->setTo($entity->email);
        $mail->setCC(MALLS['master']);
        $mail->setSubject($entity->getTitle());
        $mail->setMessage(
            view(
                $this->_viewPath . '/billing',
                ['viewDatas' => $this->_viewDatas],
            ),
        );
        return $mail->send();
    }
}
