<?php

namespace App\Models;

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

class ReportCardAcknowledgement extends BaseModel
{
    protected $table = 'report_card_acknowledgements';

    protected $fillable = [
        'parent_id',
        'student_id',
        'school_year',
        'semester',
        'viewed_at',
        'signed_at',
        'signed_name',
        'signer_ip',
        'created_at',
        'updated_at',
    ];

    public $timestamps = true;

    protected $casts = [
        'parent_id'   => 'integer',
        'student_id'  => 'integer',
        'viewed_at'   => 'datetime',
        'signed_at'   => 'datetime',
        'created_at'  => 'datetime',
        'updated_at'  => 'datetime',
    ];

    /* ============================================================
     * Relationships (optional)
     * ============================================================
     */

    public function parent(): BelongsTo
    {
        // Change to your actual parent model/table (often User/Parent/Guardian)
        return $this->belongsTo(ParentModel::class, 'parent_id');
    }

    public function student(): BelongsTo
    {
        return $this->belongsTo(Student::class, 'student_id');
    }

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

    public function scopeForParent(Builder $q, int $parentId): Builder
    {
        return $q->where('parent_id', $parentId);
    }

    public function scopeForStudent(Builder $q, int $studentId): Builder
    {
        return $q->where('student_id', $studentId);
    }

    public function scopeForTerm(Builder $q, string $schoolYear, string $semester): Builder
    {
        return $q->where('school_year', $schoolYear)
                 ->where('semester', $semester);
    }

    public function scopeSigned(Builder $q): Builder
    {
        return $q->whereNotNull('signed_at');
    }

    public function scopeViewed(Builder $q): Builder
    {
        return $q->whereNotNull('viewed_at');
    }

    /* ============================================================
     * Helpers
     * ============================================================
     */

    /**
     * Mark as viewed (idempotent).
     */
    public function markViewed(?string $ip = null): self
    {
        if ($this->viewed_at === null) {
            $this->viewed_at = now();
        }

        // optional: store IP even on view (only if signer_ip is empty)
        if ($ip !== null && empty($this->signer_ip)) {
            $this->signer_ip = $ip;
        }

        $this->save();

        return $this;
    }

    /**
     * Mark as signed (idempotent).
     */
    public function markSigned(string $signedName, ?string $ip = null): self
    {
        $this->signed_name = $signedName;

        if ($this->signed_at === null) {
            $this->signed_at = now();
        }

        if ($ip !== null) {
            $this->signer_ip = $ip;
        }

        // If they signed, it was definitely viewed.
        if ($this->viewed_at === null) {
            $this->viewed_at = now();
        }

        $this->save();

        return $this;
    }

    /* ============================================================
     * Optional validation helper (FormRequest/controller)
     * ============================================================
     */

    public static function rules(bool $updating = false): array
    {
        return [
            'parent_id'    => [$updating ? 'sometimes' : 'required', 'integer', 'min:1'],
            'student_id'   => [$updating ? 'sometimes' : 'required', 'integer', 'min:1'],
            'school_year'  => [$updating ? 'sometimes' : 'required', 'string', 'max:20'],
            'semester'     => [$updating ? 'sometimes' : 'required', 'string', 'max:20'],

            'viewed_at'    => ['nullable', 'date'],
            'signed_at'    => ['nullable', 'date', 'after_or_equal:viewed_at'],
            'signed_name'  => ['nullable', 'string', 'max:255'],
            'signer_ip'    => ['nullable', 'string', 'max:45'], // IPv4/IPv6
        ];
    }
}