<?php

declare(strict_types=1);

namespace App\Services;

class CartService
{
    private CourseService $courses;
    private PromotionService $promotions;
    private EnrollmentService $enrollments;

    public function __construct()
    {
        $this->courses = new CourseService();
        $this->promotions = new PromotionService();
        $this->enrollments = new EnrollmentService();
        $_SESSION['cart'] ??= ['items' => [], 'coupon_code' => '', 'affiliate_code' => ''];
    }

    public function add(int $courseId, ?array $user = null): array
    {
        $course = $this->courses->find($courseId);

        if (!$course || ($course['status'] ?? '') !== 'published') {
            return ['ok' => false, 'error' => 'Curso indisponivel.'];
        }

        if (!empty($course['is_free'])) {
            return ['ok' => false, 'error' => 'Cursos gratuitos nao entram no carrinho.'];
        }

        if ($user && ($user['role'] ?? '') === 'student' && $this->enrollments->hasAccess((int) $user['id'], $courseId)) {
            return ['ok' => false, 'error' => 'Ja tem acesso a este curso.'];
        }

        $_SESSION['cart']['items'][(string) $courseId] = [
            'course_id' => $courseId,
            'added_at' => date('c'),
        ];

        return ['ok' => true];
    }

    public function remove(int $courseId): void
    {
        unset($_SESSION['cart']['items'][(string) $courseId]);
    }

    public function clear(): void
    {
        $_SESSION['cart'] = ['items' => [], 'coupon_code' => '', 'affiliate_code' => ''];
    }

    public function updateMeta(string $couponCode, string $affiliateCode): void
    {
        $_SESSION['cart']['coupon_code'] = strtoupper(trim($couponCode));
        $_SESSION['cart']['affiliate_code'] = strtoupper(trim($affiliateCode));
    }

    public function count(): int
    {
        return count($_SESSION['cart']['items'] ?? []);
    }

    public function summary(?array $user = null): array
    {
        $items = [];
        $subtotal = 0.0;
        $promotionDiscount = 0.0;
        $couponDiscount = 0.0;
        $total = 0.0;
        $couponCode = (string) ($_SESSION['cart']['coupon_code'] ?? '');
        $affiliateCode = (string) ($_SESSION['cart']['affiliate_code'] ?? '');

        foreach ($_SESSION['cart']['items'] ?? [] as $item) {
            $course = $this->courses->find((int) $item['course_id']);

            if (!$course || ($course['status'] ?? '') !== 'published' || !empty($course['is_free'])) {
                continue;
            }

            $alreadyOwned = $user && ($user['role'] ?? '') === 'student' && $this->enrollments->hasAccess((int) $user['id'], (int) $course['id']);
            $pricing = $this->promotions->pricingForCourse($course, $couponCode ?: null);
            $items[] = [
                'course' => $course,
                'pricing' => $pricing,
                'already_owned' => $alreadyOwned,
            ];

            if (!$alreadyOwned) {
                $subtotal += (float) $pricing['base_price'];
                $promotionDiscount += (float) $pricing['promotion_discount'];
                $couponDiscount += (float) $pricing['coupon_discount'];
                $total += (float) $pricing['total'];
            }
        }

        return [
            'items' => $items,
            'count' => count($items),
            'coupon_code' => $couponCode,
            'affiliate_code' => $affiliateCode,
            'subtotal' => $subtotal,
            'promotion_discount' => $promotionDiscount,
            'coupon_discount' => $couponDiscount,
            'discount_total' => $promotionDiscount + $couponDiscount,
            'total' => $total,
        ];
    }
}
