<?php

namespace App\Models\SelfPaced;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * PaymentProof Model
 *
 * Stores cash payment proof uploads pending manager verification.
 * Used for enrollment, certificate, book, and re-sit fees.
 *
 * Requirements: 17.9, 17.11, 17.12, 17.13
 */
class PaymentProof extends Model
{
    protected $table = 'self_paced_payment_proofs';

    protected $fillable = [
        'enrollment_id',
        'user_id',
        'course_id',
        'fee_type',
        'proof_type',
        'file_path',
        'file_name',
        'file_size',
        'file_mime',
        'amount',
        'currency',
        'status',
        'rejection_reason',
        'reviewed_by',
        'reviewed_at',
    ];

    protected $casts = [
        'file_size' => 'integer',
        'amount' => 'decimal:2',
        'reviewed_at' => 'datetime',
    ];

    // =====================================================================
    // Relationships
    // =====================================================================

    public function enrollment(): BelongsTo
    {
        return $this->belongsTo(Enrollment::class, 'enrollment_id');
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(related: \App\Models\User::class, 'user_id');
    }

    public function course(): BelongsTo
    {
        return $this->belongsTo(Course::class, 'course_id');
    }

    public function reviewer(): BelongsTo
    {
        return $this->belongsTo(related: \App\Models\User::class, 'reviewed_by');
    }

    // =====================================================================
    // Scopes
    // =====================================================================

    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    public function scopeApproved($query)
    {
        return $query->where('status', 'approved');
    }

    // =====================================================================
    // Methods
    // =====================================================================

    /**
     * Check if proof is pending
     *
     * @return bool
     */
    public function isPending(): bool
    {
        return $this->status === 'pending';
    }

    /**
     * Check if proof is approved
     *
     * @return bool
     */
    public function isApproved(): bool
    {
        return $this->status === 'approved';
    }

    /**
     * Check if proof is rejected
     *
     * @return bool
     */
    public function isRejected(): bool
    {
        return $this->status === 'rejected';
    }

    /**
     * Approve this proof
     *
     * @param int $reviewerId User ID of reviewer
     * @return void
     */
    public function approve(int $reviewerId): void
    {
        $this->update([
            'status' => 'approved',
            'reviewed_by' => $reviewerId,
            'reviewed_at' => now(),
            'rejection_reason' => null,
        ]);
    }

    /**
     * Reject this proof with a reason
     *
     * @param int $reviewerId User ID of reviewer
     * @param string $reason Rejection reason
     * @return void
     */
    public function reject(int $reviewerId, string $reason): void
    {
        $this->update([
            'status' => 'rejected',
            'reviewed_by' => $reviewerId,
            'reviewed_at' => now(),
            'rejection_reason' => $reason,
        ]);
    }

    /**
     * Get formatted file size (e.g., "2.5 MB")
     *
     * @return string
     */
    public function getFileSizeFormatted(): string
    {
        $bytes = $this->file_size;
        $units = ['B', 'KB', 'MB', 'GB'];
        $size = $bytes;

        foreach ($units as $unit) {
            if ($size < 1024) {
                return round($size, 2) . ' ' . $unit;
            }
            $size /= 1024;
        }

        return round($size, 2) . ' TB';
    }
}
