<?php

namespace App\Services\PublicWinners;

use App\Models\ClassSection;
use App\Models\Competition;
use Illuminate\Support\Facades\DB;

/**
 * legacy {@see \App\Controllers\WinnersController} — public published winners pages.
 */
class PublicWinnersPortalService
{
    /**
     * @return list<array<string, mixed>>
     */
    public function publishedCompetitions(): array
    {
        return Competition::query()
            ->where('is_published', 1)
            ->orderByDesc('published_at')
            ->get()
            ->map(fn (Competition $c) => $this->normalizeCompetition($c))
            ->values()
            ->all();
    }

    /**
     * @return array{
     *   competition: array<string, mixed>,
     *   winners_by_class: array<int|string, list<array<string, mixed>>>,
     *   section_map: array<int, string>,
     *   question_counts: array<int, int>
     * }|null
     */
    public function competitionPayload(int $id): ?array
    {
        $competition = Competition::query()
            ->where('is_published', 1)
            ->find($id);

        if (! $competition) {
            return null;
        }

        $winnerRows = DB::table('competition_winners as cw')
            ->select('cw.*', 's.firstname', 's.lastname', 'cs.class_section_name')
            ->leftJoin('students as s', 's.id', '=', 'cw.student_id')
            ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'cw.class_section_id')
            ->where('cw.competition_id', $id)
            ->orderBy('cw.class_section_id', 'ASC')
            ->orderBy('cw.rank', 'ASC')
            ->get();

        $sectionMap = [];
        foreach (
            ClassSection::query()
                ->select(['class_section_id', 'class_section_name'])
                ->get() as $section
        ) {
            $sid = (int) ($section->class_section_id ?? 0);
            if ($sid > 0) {
                $sectionMap[$sid] = (string) ($section->class_section_name ?? (string) $sid);
            }
        }

        $winnersByClass = [];
        foreach ($winnerRows as $row) {
            $arr = (array) $row;
            $classId = (int) ($arr['class_section_id'] ?? 0);
            $fname = (string) ($arr['firstname'] ?? '');
            $lname = (string) ($arr['lastname'] ?? '');
            $name = trim($fname.' '.$lname);
            $arr['name'] = $name !== '' ? $name : ('Student #'.($arr['student_id'] ?? ''));
            $winnersByClass[$classId][] = $arr;
        }

        $questionCounts = [];
        $qRows = DB::table('competition_class_winners')
            ->select(['class_section_id', 'question_count'])
            ->where('competition_id', $id)
            ->get();

        foreach ($qRows as $row) {
            $arr = (array) $row;
            $classId = (int) ($arr['class_section_id'] ?? 0);
            if ($classId > 0 && isset($arr['question_count']) && $arr['question_count'] !== null) {
                $questionCounts[$classId] = (int) $arr['question_count'];
            }
        }

        return [
            'competition' => $this->normalizeCompetition($competition),
            'winners_by_class' => $winnersByClass,
            'section_map' => $sectionMap,
            'question_counts' => $questionCounts,
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function normalizeCompetition(Competition $c): array
    {
        $arr = $c->toArray();
        foreach ($arr as $key => $value) {
            if ($value instanceof \Carbon\CarbonInterface) {
                $arr[$key] = $value->format('Y-m-d H:i:s');
            }
        }

        return $arr;
    }
}
