<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\CartService;
use App\Services\PaymentService;

class CartController extends Controller
{
    private CartService $cart;
    private PaymentService $payments;

    public function __construct()
    {
        $this->cart = new CartService();
        $this->payments = new PaymentService();
    }

    public function index(): string
    {
        return $this->view('cart/index', [
            'title' => 'Carrinho',
            'cart' => $this->cart->summary(auth_check() ? current_user() : null),
        ]);
    }

    public function add(Request $request): void
    {
        $this->guardCsrf($request);
        $result = $this->cart->add((int) $request->post('course_id'), auth_check() ? current_user() : null);

        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Curso adicionado ao carrinho.' : $result['error']);
        app()->response()->redirect('/cart');
    }

    public function remove(Request $request): void
    {
        $this->guardCsrf($request);
        $this->cart->remove((int) $request->post('course_id'));
        flash('success', 'Curso removido do carrinho.');
        app()->response()->redirect('/cart');
    }

    public function update(Request $request): void
    {
        $this->guardCsrf($request);
        $this->cart->updateMeta((string) $request->post('coupon_code', ''), (string) $request->post('affiliate_code', ''));
        flash('success', 'Carrinho actualizado.');
        app()->response()->redirect('/cart');
    }

    public function clear(Request $request): void
    {
        $this->guardCsrf($request);
        $this->cart->clear();
        flash('success', 'Carrinho limpo.');
        app()->response()->redirect('/cart');
    }

    public function checkout(Request $request): void
    {
        require_role('student');
        $this->guardCsrf($request);

        $summary = $this->cart->summary(current_user());

        if (!$summary['items']) {
            flash('error', 'Carrinho vazio.');
            app()->response()->redirect('/cart');
        }

        $created = [];
        $errors = [];

        foreach ($summary['items'] as $item) {
            if (!empty($item['already_owned'])) {
                continue;
            }

            $result = $this->payments->startCheckout(
                (int) $item['course']['id'],
                current_user(),
                (string) $summary['coupon_code'],
                (string) $summary['affiliate_code']
            );

            if ($result['ok']) {
                $created[] = $result['payment'];
            } else {
                $errors[] = $item['course']['title'] . ': ' . $result['error'];
            }
        }

        if (!$created && $errors) {
            flash('error', implode(' ', $errors));
            app()->response()->redirect('/cart');
        }

        $this->cart->clear();
        flash('success', count($created) . ' pagamento(s) criado(s). Envie os comprovativos para liberar acesso.');
        app()->response()->redirect(count($created) === 1 ? '/payments/show?id=' . $created[0]['id'] : '/payments');
    }

    private function guardCsrf(Request $request): void
    {
        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }
    }
}
