<?php
namespace PPLCZ\Admin\RestController;
defined("WPINC") or die();

use PPLCZ\Admin\CPLOperation;
use PPLCZ\Admin\Cron\RefreshAboutCron;
use PPLCZ\Data\AddressData;
use PPLCZ\Admin\Errors;
use PPLCZ\Admin\RestResponse\RestResponse400;
use PPLCZ\Data\ShipmentData;
use PPLCZ\Model\Model\GlobalSettingModel;
use PPLCZ\Model\Model\MyApi2;
use PPLCZ\Model\Model\ParcelPlacesModel;
use PPLCZ\Model\Model\SenderAddressModel;
use PPLCZ\Model\Model\ShipmentPhaseModel;
use PPLCZ\Model\Model\SyncPhasesModel;
use PPLCZ\Model\Model\UpdateSyncPhasesModel;
use PPLCZ\Serializer;
use PPLCZ\Setting\ApiSetting;
use PPLCZ\Setting\MethodSetting;
use PPLCZ\Setting\PhaseSetting;
use PPLCZ\Setting\PrintSetting;
use PPLCZ\Validator\Validator;

class SettingV1RestController extends  PPLRestController
{
    protected $namespace = "ppl-cz/v1";

    protected $base = "setting";

    public function register_routes()
    {

        register_rest_route($this->namespace, "/". $this->base . "/api", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_api"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_api"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/". $this->base . "/parcelplaces", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_parcelplaces"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_parcelplaces"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/". $this->base . "/parcelcountries", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_parcelcountries"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_parcelcountries"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/". $this->base . "/sender-addresses", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_addresses"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_addresses"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/" . $this->base . "/print", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_print"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_print"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/" . $this->base . "/print-order-statuses", [
            [
                "methods"=>\WP_REST_Server::EDITABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "update_print_statuses"],
            ], [
                "methods"=>\WP_REST_Server::READABLE,
                "callback" => [$this, "get_print_statuses"],
                "permission_callback"=>[$this, "check_permission"],
            ]
        ]);

        register_rest_route($this->namespace, "/" . $this->base . "/available-printers", [
            [
                "methods"=>\WP_REST_Server::READABLE,
                "permission_callback"=>[$this, "check_permission"],
                "callback" => [$this, "available_printers"],
            ]
        ]);

        register_rest_route($this->namespace, '/' . $this->base. "/shipment-phases", [
                "methods" => \WP_REST_Server::READABLE,
                "callback" => [$this, "get_phases"],
                "permission_callback"=>[$this, "check_permission"],

        ]);

        register_rest_route($this->namespace, '/' . $this->base. "/shipment-phases", [
            "methods" => \WP_REST_Server::EDITABLE,
            "callback" => [$this, "set_phase"],
            "permission_callback"=>[$this, "check_permission"],
        ]);

        register_rest_route($this->namespace, '/' . $this->base. "/global-settings", [
            "methods" => \WP_REST_Server::READABLE,
            "callback" => [$this, "get_globalsettings"],
            "permission_callback"=>[$this, "check_permission"],

        ]);

        register_rest_route($this->namespace, '/' . $this->base. "/global-settings", [
            "methods" => \WP_REST_Server::EDITABLE,
            "callback" => [$this, "update_globalsettings"],
            "permission_callback"=>[$this, "check_permission"],
        ]);
    }

    public function available_printers()
    {
        $items = array_map(function ($item) {
            return pplcz_normalize($item);
        }, (new CPLOperation())->getAvailableLabelPrinters());
        $resp = new \WP_REST_Response();
        $resp->set_data($items);
        return $items;
    }


    public function get_phases()
    {

        $response = new \WP_REST_Response();

        $response->set_data(pplcz_normalize(PhaseSetting::getPhases()));

        return $response;
    }

    public function set_phase(\WP_REST_Request $request)
    {


        /**
         * @var UpdateSyncPhasesModel $value
         */
        $params = $request->get_json_params();
        $value = pplcz_denormalize($request->get_json_params(), UpdateSyncPhasesModel::class);

        if ($value->isInitialized("phases")) {
            foreach ($value->getPhases() as $phase) {
                PhaseSetting::setPhase($phase->getCode(), $phase->getWatch(), $phase->getOrderState());
            }
        }
        if ($value->isInitialized("maxSync"))
        {
            PhaseSetting::setMaxSync($value->getMaxSync());
        }

        $resp = new \WP_REST_Response();
        $resp->set_status(204);
        return $resp;
    }

    public function update_print(\WP_REST_Request $request)
    {
        $content = json_decode($request->get_body(), true);
        if ($content && isset($content['format']) && PrintSetting::setFormat($content['format']))
        {
            return new \WP_REST_Response(null, 204);
        }
        return new \WP_REST_Response(null, 400);
    }

    public function get_print(\WP_REST_Request $request)
    {
        $setting = PrintSetting::getPrintSetting();
        $resp = new \WP_REST_Response();
        $resp->set_data($setting->getFormat());
        return $resp;

    }

    public function get_print_statuses()
    {
        $setting = PrintSetting::getPrintSetting();
        $resp = new \WP_REST_Response();
        $resp->set_data(array_values($setting->getOrderStatuses()));
        return $resp;
    }

    public function update_print_statuses(\WP_REST_Request $request)
    {
        $content = $request->get_json_params();
        if (PrintSetting::setOrderStatuses($content))
        {
            return new \WP_REST_Response(null, 204);
        }
        return new \WP_REST_Response(null, 400);
    }

    public function get_addresses()
    {
        $sender = AddressData::get_default_sender_addresses();
        foreach ($sender as $key => $value)
        {
            $sender[$key] = pplcz_denormalize($value, SenderAddressModel::class);
            $sender[$key] = pplcz_normalize($sender[$key], "array");
        }
        $response = new \WP_REST_Response();
        $response->set_data($sender);
        return $response;
    }

    public function update_addresses(\WP_REST_Request $request)
    {
        $sender = $request->get_json_params();
        $errors = new Errors();

        foreach ($sender as $key => $value)
        {
            $sender[$key] = pplcz_denormalize($value, SenderAddressModel::class);
            pplcz_validate($sender[$key], $errors, "$key");
        }
        if ($errors->errors)
            return new RestResponse400($errors);

        foreach ($sender as $key => $value) {
            $addressId = $sender[$key]->getId();
            $address = new AddressData($addressId);
            $sender[$key] = pplcz_denormalize($sender[$key], AddressData::class, ["data" => $address]);
            $sender[$key]->save();
        }

        AddressData::set_default_sender_addresses($sender);

        $response = new \WP_REST_Response();
        $response->set_status(204);
        return $response;

    }


    public function update_api(\WP_REST_Request $request)
    {
        delete_transient(pplcz_create_name("validate_cpl_connect"));

        $data = $request->get_json_params();
        /**
         * @var MyApi2 $setting
         */
        $setting = pplcz_denormalize($data, MyApi2::class);

        $wp_error = new Errors();

        pplcz_validate($setting, $wp_error);

        if ($wp_error->errors)
        {
            return new RestResponse400($wp_error);
        }

        ApiSetting::setApi($setting);

        $cpl = new CPLOperation();
        $cpl->clearAccessToken();
        $accessToken = $cpl->getAccessToken();

        if (!$accessToken) {
            $wp_error = new Errors();
            $wp_error->add("", "PPL Plugin nebude fungovat, protože přihlašovací údaje nejsou správně nastaveny! Ujistěte se, že jsou zadány správně. Pokud je nemáte, prosím kontaktujte ithelp@ppl.cz");
            return new RestResponse400($wp_error);
        }

        $response = new \WP_REST_Response();
        $response->set_status(204);
        RefreshAboutCron::refresh_setting();
        return $response;
    }

    public function get_api(\WP_REST_Request $request)
    {

        $myapi2 = ApiSetting::getApi();

        $myapi2 = pplcz_normalize($myapi2);

        $response = new \WP_REST_Response();
        $response->set_data($myapi2);
        return $response;
    }

    public function get_parcelplaces(\WP_REST_Request $request)
    {

        $places = MethodSetting::getGlobalParcelboxesSetting();

        $places = pplcz_normalize($places);

        $response = new \WP_REST_Response();
        $response->set_data($places);


        return $response;
    }

    public function update_parcelplaces(\WP_REST_Request $request)
    {
        $data = $request->get_json_params();
        /**
         * @var ParcelPlacesModel $setting
         */
        $setting = pplcz_denormalize($data, ParcelPlacesModel::class);

        MethodSetting::setGlobalParcelboxesSetting($setting);

        pplcz_set_update_setting();

        $response = new \WP_REST_Response();
        $response->set_status(204);
        return $response;
    }

    public function get_globalsettings(\WP_REST_Request $request)
    {

        $places = MethodSetting::getGlobalSetting();

        $places = pplcz_normalize($places);

        $response = new \WP_REST_Response();
        $response->set_data($places);


        return $response;
    }

    public function update_globalsettings(\WP_REST_Request $request)
    {
        $data = $request->get_json_params();
        /**
         * @var GlobalSettingModel $setting
         */
        $setting = pplcz_denormalize($data, GlobalSettingModel::class);

        MethodSetting::setGlobalSetting($setting);

        pplcz_set_update_setting();

        $response = new \WP_REST_Response();
        $response->set_status(204);
        return $response;
    }
}