<?php

namespace V3\App\Services\Portal\ELearning;

use Exception;
use PDO;
use V3\App\Common\Enums\ContentType;
use V3\App\Models\Portal\ELearning\Content;

class SyllabusService
{
    private Content $content;

    public function __construct(PDO $pdo)
    {
        $this->content = new Content($pdo);
    }

    public function create(array $data)
    {
        $payload = [
            'title' => $data['title'],
            'description' => $data['description'],
            'type' => ContentType::SYLLABUS->value,
            'course_id' => $data['course_id'],
            'course_name' => $data['course_name'],
            'level' => $data['level_id'],
            'path_label' => json_encode($data['classes']),
            'author_id' => $data['creator_id'],
            'author_name' => $data['creator_name'],
            'term' => $data['term'],
            'upload_date' => date('Y-m-d H:i:s'),
        ];

        $newId = $this->content->insert($payload);
        if (!$newId) {
            throw new Exception("Failed to create syllabus.");
        }

        return $newId;
    }

    public function updateSyllabus($data): bool
    {
        $payload = [
            'title' => $data['title'],
            'description' => $data['description'],
            'path_label' => json_encode($data['classes'])
        ];

        return $this->content
            ->where('id', '=', $data['id'])
            ->update($payload);
    }

    /**
     * Retrieves syllabus content filtered by term, level, and type.
     *
     * @param array $filters Must include 'term', 'level_id', and 'course_id'.
     * @return array List of syllabus items with 'classes' decoded from path_label.
     */
    public function getSyllabus(array $filters): array
    {
        $results = $this->content
            ->select(columns: [
                'id',
                'title',
                'description',
                'path_label AS classes, author_name, term, upload_date'
            ])
            ->where('term', '=', $filters['term'])
            ->where('level', '=', $filters['level_id'])
            ->where('course_id', '=', $filters['course_id'])
            ->where('type', '=', ContentType::SYLLABUS->value)
            ->get();

        return array_map(function ($row) {
            $row['classes'] = json_decode($row['classes'], true);
            return $row;
        }, $results);
    }

    public function getSyllabusByStaff(array $filters): array
    {
        $results = $this->content
            ->select(columns: [
                'id',
                'title',
                'description',
                'course_id',
                'course_name',
                'path_label AS classes, author_name, term, upload_date'
            ])
            ->where('term', '=', $filters['term'])
            ->where('level', '=', $filters['level_id'])
            ->where('course_id', '=', $filters['course_id'])
            ->where('type', '=', ContentType::SYLLABUS->value)
            ->get();

        $items = [];
        foreach ($results as $row) {
            $classes = json_decode($row['classes'], true);
            $classIds = array_map(fn($item) => (int)$item['id'], $classes);

            if ($row['course_id'] != $filters['course_id']) {
                continue;
            }
            if (!in_array($filters['class_id'], $classIds)) {
                continue;
            }

            $row['classes'] = $classes;
            $items[] = $row;
        }

        return $items;
    }

    public function deleteSyllabus(int $id): bool
    {
        return $this->content
            ->where('id', '=', $id)
            ->delete();
    }
}
