<?php

class LogNotificationController extends BaseController {
    public function index()
    {
        $this->checkScopes(['admin.view']);
        $rawParams = $this->request->get();
        $rawParams['limit'] = $this->getDefaultLimit($rawParams);
        $rawParams['offset'] = array_key_exists('offset', $rawParams) ? $rawParams['offset'] : 0;
        $rawParams['order_by'] = array_key_exists('order_by', $rawParams) ? $rawParams['order_by'] : 'created_at';
        $rawParams['order_direction'] = array_key_exists('order_direction', $rawParams) ? $rawParams['order_direction'] : 'desc';

        $validatedParams = $this->validate($rawParams, [
            'limit' => ['validators' => [
                'required', 'digit', ['name' => 'max', 'params' => 1000]
            ]],
            'offset' => ['validators' => [
                'required', 'digit'
            ]],
            'status' => ['validators' => [
                [
                    'name' => 'inclusion_in',
                    'params' => array_merge([NULL], LogNotification::STATUSES),
                ]
            ]],
            'notif_to' => ['validators' => [
                [
                    'name' => 'max_string',
                    'params' => 30
                ]
            ]],
            'created_at_from' => ['validators' => [
                'date'
            ]],
            'created_at_to' => ['validators' => [
                'date'
            ]],
            'sent_at_from' => ['validators' => [
                'date'
            ]],
            'sent_at_to' => ['validators' => [
                'date'
            ]],
            'order_by' => ['validators' => [
                [
                    'name' => 'inclusion_in',
                    'params' => ['created_at', 'sent_at', 'status']
                ]
            ]],
            'order_direction' => ['validators' => [
                [
                    'name' => 'inclusion_in',
                    'params' => ['asc', 'desc']
                ]
            ]]
        ]);

        $conditions = [];
        $bind = [];

        if (!is_null($validatedParams["status"])) {
            $conditions[] = "LogNotification.status ILIKE :status:";
            $bind["status"] = "%" . $validatedParams["status"] . "%";
        }

        if (!is_null($validatedParams["notif_to"])) {
            $conditions[] = "LogNotification.um_id = :notif_to:";
            $bind["notif_to"] = $validatedParams["notif_to"];
        }

        if (!is_null($validatedParams['created_at_from'])) {
            $conditions[] = "CAST(LogNotification.created_at as date) >= :created_at_from:";
            $bind['created_at_from'] = $validatedParams['created_at_from'];
        }

        if (!is_null($validatedParams['created_at_to'])) {
            $conditions[] = "CAST(LogNotification.created_at as date) <= :created_at_to:";
            $bind["created_at_to"] = $validatedParams['created_at_to'];
        }

        if (!is_null($validatedParams['sent_at_from'])) {
            $conditions[] = "CAST(LogNotification.sent_at as date) >= :sent_at_from:";
            $bind["sent_at_from"] = $validatedParams['sent_at_from'];
        }

        if (!is_null($validatedParams['sent_at_to'])) {
            $conditions[] = "CAST(LogNotification.sent_at as date) <= :sent_at_to:";
            $bind["sent_at_to"] = $validatedParams['sent_at_to'];
        }

        $conditions = implode(" AND ", $conditions);
        $total = LogNotification::count([
            "conditions" => $conditions,
            "bind" => $bind
        ]);
        $rows = LogNotification::query()
            ->columns("LogNotification.id, LogNotification.device_token, LogNotification.title, LogNotification.body, 
            LogNotification.created_at, LogNotification.sent_at, LogNotification.status, 
            UmUser.um_id as user_id, UmUser.um_user_name, UmUser.nama")
            ->leftJoin(UmUser::class, "UmUser.um_id = LogNotification.um_id")
            ->where($conditions)
            ->bind($bind)
            ->orderBy($validatedParams["order_by"] . " " . $validatedParams["order_direction"])
            ->limit($validatedParams["limit"], $validatedParams["offset"])
            ->execute();
        return new PaginatedResponse($rows, $total, $validatedParams["limit"], $validatedParams["offset"]);
    }

    /**
     * @throws CustomErrorException
     */
    public function detail($id)
    {
        $this->checkScopes(['admin.view']);
        return new SimpleResponse(LogNotification::retrieve($id));
    }

    public function statusReference()
    {
        $this->checkScopes(['admin.view']);

        return new SimpleResponse(LogNotification::STATUSES);
    }

    public function markResend(){
        $this->checkScopes(['admin.view']);

        $params = $this->request->getJsonRawBody(true);
        $notifications = LogNotification::find([
            'conditions' => 'id IN ({params:array})',
            'bind' => [
                'params' => $params
            ]
        ]);

        $count = 0;
        foreach ($notifications as $notification) {
            /** @var $notification LogNotification */
            if ($notification->status != LogNotification::STATUS_SUCCESS) {
                $notification->status = LogNotification::STATUS_NEW;
                $notification->save();
                $count++;
            }
        }
        return new SimpleResponse($count);
    }

    public function batchSend() {
        $this->checkScopes(['admin.view']);

        $params = $this->request->getJsonRawBody(true);
        $notifications = LogNotification::find([
            'conditions' => 'id IN ({params:array})',
            'bind' => [
                'params' => $params
            ]
        ]);
        $result = ['success' => 0, 'failed' => 0];
        foreach ($notifications as $notification) {
            /** @var $notification LogNotification */
            if ($notification->status != LogNotification::STATUS_SUCCESS) {
                $notification->send();
                if ($notification->status == LogNotification::STATUS_SUCCESS) {
                    $result['success']++;
                } else {
                    $result['failed']++;
                }
            }
        }
        return new SimpleResponse($result);
    }
}
