<?php

declare(strict_types=1);

namespace App\Modules\Administration\Controllers;

use App\Controllers\Controller;
use App\Modules\Administration\Services\AuthenticationService;
use App\Modules\Administration\Services\AuthorizationService;
use App\Modules\Administration\Services\PayamService;
use RuntimeException;
use System\Http\Request;
use System\View\View;

final class PayamController extends Controller
{
    public function __construct(
        private AuthenticationService $authentication,
        private AuthorizationService $authorization,
        private PayamService $payamService,
        private Request $request,
        View $view
    ) {
        parent::__construct($view);
    }

    private function protect(): void
    {
        if (!$this->authentication->check()) {
            header('Location: /public/login');
            exit;
        }
    }

    private function requireAdministrator(): void
    {
        if (!$this->authorization->isAdministrator()) {
            header('Location: /public/403');
            exit;
        }
    }

    public function index(): void
    {
        $this->protect();
        $this->requireAdministrator();

        $this->render(
            'payams/index',
            [
                'title' => 'Payam Management',
                'payams' => $this->payamService->all(),
                'created' => $this->request->input('created'),
                'updated' => $this->request->input('updated'),
                'statusChanged' =>
                    $this->request->input('status_changed'),
                'error' =>
                    $this->request->input('error')
            ]
        );
    }

    public function create(): void
    {
        $this->protect();
        $this->requireAdministrator();

        $this->render(
            'payams/create',
            [
                'title' => 'Create Payam',
                'states' => $this->payamService->states(),
                'counties' => $this->payamService->counties()
            ]
        );
    }

    public function store(): void
    {
        $this->protect();
        $this->requireAdministrator();

        try {
            $this->payamService->create(
                $this->request->all()
            );

            header(
                'Location: /public/payams?created=1'
            );

            exit;
        } catch (\Throwable $exception) {
            $this->render(
                'payams/create',
                [
                    'title' => 'Create Payam',
                    'states' =>
                        $this->payamService->states(),
                    'counties' =>
                        $this->payamService->counties(),
                    'error' =>
                        $exception->getMessage(),
                    'old' =>
                        $this->request->all()
                ]
            );
        }
    }

    public function edit(): void
    {
        $this->protect();
        $this->requireAdministrator();

        $id = (int) $this->request->input(
            'id',
            0
        );

        $payam = $this->payamService->find($id);

        if ($payam === null) {
            throw new RuntimeException(
                'Payam not found.'
            );
        }

        $this->render(
            'payams/edit',
            [
                'title' => 'Edit Payam',
                'payam' => $payam,
                'states' =>
                    $this->payamService->states(),
                'counties' =>
                    $this->payamService->counties()
            ]
        );
    }

    public function update(): void
    {
        $this->protect();
        $this->requireAdministrator();

        $id = (int) $this->request->input(
            'id',
            0
        );

        try {
            $this->payamService->update(
                $id,
                $this->request->all()
            );

            header(
                'Location: /public/payams?updated=1'
            );

            exit;
        } catch (\Throwable $exception) {
            $this->render(
                'payams/edit',
                [
                    'title' => 'Edit Payam',
                    'payam' =>
                        $this->payamService->find($id),
                    'states' =>
                        $this->payamService->states(),
                    'counties' =>
                        $this->payamService->counties(),
                    'error' =>
                        $exception->getMessage()
                ]
            );
        }
    }

    public function toggleStatus(): void
    {
        $this->protect();
        $this->requireAdministrator();

        $id = (int) $this->request->input(
            'id',
            0
        );

        try {
            $this->payamService->toggleStatus($id);

            header(
                'Location: /public/payams?status_changed=1'
            );
        } catch (\Throwable $exception) {
            header(
                'Location: /public/payams?error='
                . urlencode(
                    $exception->getMessage()
                )
            );
        }

        exit;
    }
}