<?php

namespace App\Services\Parents;

use App\Models\Configuration;
use App\Services\ApplicationUrlService;
use App\Models\ReportCardAcknowledgement;
use App\Models\User;
use Illuminate\Support\Facades\DB;

/**
 * legacy {@see \App\Controllers\ParentReportCardController} parity (read + acknowledgement).
 */
class ParentReportCardService
{
    public function __construct(
        private PrimaryParentUserResolver $primaryParentResolver,
        private ApplicationUrlService $urls,
    ) {}

    /**
     * Resolve term from query string with configuration fallbacks (legacy index/view).
     *
     * @return array{0: string, 1: string}
     */
    public function termFromRequest(?string $schoolYearGet, ?string $semesterGet): array
    {
        $schoolYear = trim((string) ($schoolYearGet ?? ''));
        $semester = trim((string) ($semesterGet ?? ''));
        if ($schoolYear === '') {
            $schoolYear = trim((string) (Configuration::getConfigValueByKey('school_year') ?? ''));
        }
        if ($semester === '') {
            $semester = trim((string) (Configuration::getConfigValueByKey('semester') ?? ''));
        }

        return [$schoolYear, $semester];
    }

    /**
     * legacy sign() — current configuration term only (no GET overrides).
     *
     * @return array{0: string, 1: string}
     */
    public function termFromConfiguration(): array
    {
        $schoolYear = trim((string) (Configuration::getConfigValueByKey('school_year') ?? ''));
        $semester = trim((string) (Configuration::getConfigValueByKey('semester') ?? ''));

        return [$schoolYear, $semester];
    }

    public function resolvePrimaryParentUserId(?User $user): ?int
    {
        return $this->primaryParentResolver->resolveFromUser($user);
    }

    /**
     * legacy index() student rows for parent + optional student_class term filters.
     *
     * @return list<array<string, mixed>>
     */
    public function studentsForTerm(int $primaryParentUserId, string $schoolYear, string $semester): array
    {
        if ($primaryParentUserId <= 0) {
            return [];
        }

        $q = DB::table('students as s')
            ->select('s.id', 's.firstname', 's.lastname', 'cs.class_section_name')
            ->leftJoin('student_class as sc', 'sc.student_id', '=', 's.id')
            ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
            ->where('s.parent_id', $primaryParentUserId)
            ->orderBy('s.firstname', 'ASC')
            ->orderBy('s.lastname', 'ASC');

        if ($schoolYear !== '') {
            $q->where('sc.school_year', $schoolYear);
        }
        if ($semester !== '') {
            $q->where('sc.semester', $semester);
        }

        return $q->get()->map(static fn ($r) => (array) $r)->all();
    }

    /**
     * @param list<int> $studentIds
     * @return array<int, array<string, mixed>>
     */
    public function acknowledgementMap(int $primaryParentUserId, array $studentIds, string $schoolYear, string $semester): array
    {
        if ($primaryParentUserId <= 0 || $studentIds === []) {
            return [];
        }

        $rows = ReportCardAcknowledgement::query()
            ->where('parent_id', $primaryParentUserId)
            ->where('school_year', $schoolYear)
            ->where('semester', $semester)
            ->whereIn('student_id', $studentIds)
            ->get();

        $map = [];
        foreach ($rows as $row) {
            $map[(int) $row->student_id] = $row->toArray();
        }

        return $map;
    }

    public function studentBelongsToPrimaryParent(int $studentId, int $primaryParentUserId): bool
    {
        $pid = DB::table('students')->where('id', $studentId)->value('parent_id');

        return $pid !== null && (int) $pid === $primaryParentUserId;
    }

    /**
     * @param array<string, mixed> $values viewed_at, signed_at, signed_name, signer_ip, …
     */
    public function touchAcknowledgement(
        int $primaryParentUserId,
        int $studentId,
        string $schoolYear,
        string $semester,
        array $values,
    ): void {
        $criteria = [
            'parent_id' => $primaryParentUserId,
            'student_id' => $studentId,
            'school_year' => $schoolYear,
            'semester' => $semester,
        ];

        $existing = ReportCardAcknowledgement::query()->where($criteria)->first();
        if ($existing) {
            $existing->fill($values);
            $existing->save();

            return;
        }

        ReportCardAcknowledgement::query()->create(array_merge($criteria, $values));
    }

    public function reportCardUrl(int $studentId, string $schoolYear, string $semester): string
    {
        $query = [];
        if ($schoolYear !== '') {
            $query['school_year'] = $schoolYear;
        }
        if ($semester !== '') {
            $query['semester'] = $semester;
        }

        $base = $this->urls->studentReportCardUrl($studentId);

        return $query === [] ? $base : $base.'?'.http_build_query($query);
    }
}
