<?php

namespace App\Services\Whatsapp;

use App\Models\ClassSection;
use App\Models\WhatsappGroupLink;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class WhatsappLinkService
{
    public function __construct(private WhatsappContextService $context)
    {
    }

    public function paginate(array $filters): LengthAwarePaginator
    {
        $query = WhatsappGroupLink::query();

        $schoolYear = trim((string) ($filters['school_year'] ?? ''));
        if ($schoolYear !== '') {
            $query->forYear($schoolYear);
        }

        if (array_key_exists('semester', $filters)) {
            $semester = trim((string) ($filters['semester'] ?? ''));
            if ($semester !== '') {
                $query->forSemester($semester);
            }
        }

        if (!empty($filters['class_section_id'])) {
            $query->forSection((int) $filters['class_section_id']);
        }

        if (array_key_exists('active', $filters) && $filters['active'] !== null && $filters['active'] !== '') {
            $query->where('active', (int) (bool) $filters['active']);
        }

        if (!empty($filters['search'])) {
            $search = trim((string) $filters['search']);
            $query->where(function ($q) use ($search) {
                $q->where('class_section_name', 'like', '%' . $search . '%')
                    ->orWhere('invite_link', 'like', '%' . $search . '%')
                    ->orWhere('class_section_id', $search);
            });
        }

        $sortBy = (string) ($filters['sort_by'] ?? 'updated_at');
        $sortDir = strtolower((string) ($filters['sort_dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';

        $allowedSorts = ['class_section_id', 'class_section_name', 'school_year', 'semester', 'active', 'updated_at'];
        if (!in_array($sortBy, $allowedSorts, true)) {
            $sortBy = 'updated_at';
        }

        $perPage = (int) ($filters['per_page'] ?? 20);
        $perPage = $perPage > 0 ? $perPage : 20;

        return $query->orderBy($sortBy, $sortDir)->paginate($perPage);
    }

    public function findOrFail(int $id): WhatsappGroupLink
    {
        $link = WhatsappGroupLink::query()->find($id);
        if (!$link) {
            throw new ModelNotFoundException('WhatsApp group link not found.');
        }

        return $link;
    }

    public function upsert(array $payload): WhatsappGroupLink
    {
        $schoolYear = trim((string) ($payload['school_year'] ?? '')) ?: $this->context->schoolYear();
        $semester = trim((string) ($payload['semester'] ?? ''));
        $sectionId = (int) ($payload['class_section_id'] ?? 0);

        $sectionName = trim((string) ($payload['class_section_name'] ?? ''));
        if ($sectionName === '' && $sectionId > 0) {
            $sectionName = $this->resolveSectionName($sectionId);
        }

        $link = WhatsappGroupLink::upsertLinkForSection(
            $sectionId,
            $sectionName !== '' ? $sectionName : ('Section ' . $sectionId),
            $schoolYear,
            $semester,
            (string) ($payload['invite_link'] ?? ''),
            (bool) ($payload['active'] ?? true)
        );

        return $link;
    }

    public function update(int $id, array $payload): WhatsappGroupLink
    {
        $link = $this->findOrFail($id);

        if (array_key_exists('class_section_name', $payload)) {
            $name = trim((string) ($payload['class_section_name'] ?? ''));
            if ($name === '' && !empty($payload['class_section_id'])) {
                $name = $this->resolveSectionName((int) $payload['class_section_id']);
            }
            $payload['class_section_name'] = $name;
        }

        $link->fill($payload);
        $link->save();

        return $link;
    }

    public function delete(int $id): void
    {
        $link = $this->findOrFail($id);
        $link->delete();
    }

    private function resolveSectionName(int $sectionId): string
    {
        $name = ClassSection::getClassSectionNameBySectionId($sectionId);
        return $name !== null && $name !== '' ? $name : ('Section ' . $sectionId);
    }
}
