<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;

class WhatsappGroupLink extends BaseModel
{
    protected $table = 'whatsapp_group_links';

    protected $fillable = [
        'class_section_id',
        'class_section_name',
        'school_year',
        'semester',
        'invite_link',
        'active',
        'created_at',
        'updated_at',
    ];

    public $timestamps = true; // requires created_at/updated_at

    protected $casts = [
        'class_section_id' => 'integer',
        'active'           => 'boolean',
        'created_at'       => 'datetime',
        'updated_at'       => 'datetime',
    ];

    /* ============================================================
     * Scopes
     * ============================================================
     */

    public function scopeForSection(Builder $q, int $sectionId): Builder
    {
        return $q->where('class_section_id', $sectionId);
    }

    public function scopeForYear(Builder $q, string $year): Builder
    {
        return $q->where('school_year', trim($year));
    }

    public function scopeForSemester(Builder $q, string $semester, bool $allowNullSemester = false): Builder
    {
        $sem = trim($semester);

        if ($sem === '') {
            return $q;
        }

        if ($allowNullSemester) {
            return $q->where(function (Builder $w) use ($sem) {
                $w->where('semester', $sem)
                  ->orWhereNull('semester');
            });
        }

        return $q->where('semester', $sem);
    }

    public function scopeActive(Builder $q): Builder
    {
        return $q->where('active', 1);
    }

    public function scopeInactive(Builder $q): Builder
    {
        return $q->where('active', 0);
    }

    public function scopeHasInviteLink(Builder $q): Builder
    {
        return $q->whereNotNull('invite_link')
                 ->where('invite_link', '!=', '');
    }

    /* ============================================================
     * Methods (CI-compatible behavior)
     * ============================================================
     */

    /**
     * Get the link for a specific section in a specific term.
     *
     * @param int    $sectionId          Class/section code (not PK).
     * @param string $year               School year, e.g. "2025-2026".
     * @param string $sem                Semester, e.g. "Fall".
     * @param bool   $onlyActive         If true, require active=1.
     * @param bool   $allowNullSemester  If true, accept rows with semester IS NULL as well.
     */
    public static function getLinkForSection(
        int $sectionId,
        string $year,
        string $sem,
        bool $onlyActive = true,
        bool $allowNullSemester = false
    ): ?self {
        $q = static::query()
            ->forSection($sectionId)
            ->forYear($year)
            ->forSemester($sem, $allowNullSemester)
            ->hasInviteLink();

        if ($onlyActive) {
            $q->active();
        }

        return $q->orderByDesc('updated_at')
            ->orderByDesc('id')
            ->first();
    }

    /**
     * Get all links for a term.
     *
     * @param string    $year
     * @param string    $sem
     * @param bool|null $onlyActive  true: active only, false: inactive only, null: both
     * @param bool      $allowNullSemester  If true, include rows with semester IS NULL.
     *
     * @return array<WhatsappGroupLink>
     */
    public static function getAllForTerm(
        string $year,
        string $sem,
        ?bool $onlyActive = null,
        bool $allowNullSemester = false
    ): array {
        $q = static::query()
            ->forYear($year)
            ->forSemester($sem, $allowNullSemester);

        if ($onlyActive === true) {
            $q->active();
        } elseif ($onlyActive === false) {
            $q->inactive();
        }

        return $q->orderByDesc('updated_at')
            ->orderByDesc('id')
            ->get()
            ->all();
    }

    /**
     * Convenience: upsert a link row for a section/term.
     * Returns the model after save.
     */
    public static function upsertLinkForSection(
        int $sectionId,
        string $sectionName,
        string $year,
        string $sem,
        string $inviteLink,
        bool $active = true
    ): self {
        $payload = [
            'class_section_name' => $sectionName,
            'invite_link'        => trim($inviteLink),
            'active'             => $active ? 1 : 0,
        ];

        // NOTE: semester is part of the uniqueness key like your CI version.
        return static::query()->updateOrCreate(
            [
                'class_section_id' => $sectionId,
                'school_year'      => trim($year),
                'semester'         => trim($sem),
            ],
            $payload
        );
    }

    /* ============================================================
     * Optional validation helper
     * ============================================================
     */

    public static function rules(bool $updating = false): array
    {
        $req = $updating ? 'sometimes' : 'required';

        return [
            'class_section_id'   => [$req, 'integer', 'min:1'],
            'class_section_name' => [$req, 'string', 'max:255'],
            'school_year'        => [$req, 'string', 'max:20'],
            'semester'           => ['nullable', 'string', 'max:20'],
            'invite_link'        => [$req, 'string', 'max:2000'],
            'active'             => ['nullable', 'boolean'],
        ];
    }
}