<?php
declare(strict_types=1);

namespace App\Modules\Fines\Models;

use App\Core\Model;
use App\Core\App;
use App\Core\Pagination;

class Fine extends Model
{
    protected static string $table = 'fines';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = false;
    protected static bool $dispatchEvents = true;

    protected static array $fillable = [
        'member_id', 'violation_id', 'fine_type', 'amount', 'penalty_type',
        'suspension_from', 'suspension_to', 'appeal_submitted', 'appeal_date',
        'appeal_notes', 'appeal_decision', 'appeal_decided_by', 'appeal_decided_at',
        'status', 'paid_amount', 'payment_id', 'paid_at', 'notes',
    ];

    public static function getForMember(int $memberId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT f.*, v.description as violation_desc FROM fines f LEFT JOIN violations v ON v.id = f.violation_id WHERE f.member_id = ? ORDER BY f.created_at DESC",
            [$memberId]
        );
    }

    public static function getUnpaidForMember(int $memberId): string
    {
        $db = App::getInstance()->db();
        $row = $db->selectOne("SELECT COALESCE(SUM(amount - paid_amount), 0) as total FROM fines WHERE member_id = ? AND status IN ('imposed','appeal_upheld')", [$memberId]);
        return $row['total'] ?? '0.00';
    }

    public static function isSuspended(int $memberId): bool
    {
        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM fines WHERE member_id = ? AND penalty_type IN ('suspension','ban') AND status IN ('imposed','appeal_upheld') AND suspension_from <= CURDATE() AND (suspension_to IS NULL OR suspension_to >= CURDATE())",
            [$memberId]
        );
        return (int) ($row['cnt'] ?? 0) > 0;
    }

    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (!empty($filters['status'])) { $where .= ' AND f.status = ?'; $params[] = $filters['status']; }
        if (!empty($filters['penalty_type'])) { $where .= ' AND f.penalty_type = ?'; $params[] = $filters['penalty_type']; }
        if (!empty($filters['search'])) {
            $where .= ' AND (m.full_name_ar LIKE ? OR m.membership_number LIKE ?)';
            $s = '%' . $filters['search'] . '%'; $params[] = $s; $params[] = $s;
        }

        $countRow = $db->selectOne("SELECT COUNT(*) as cnt FROM fines f JOIN members m ON m.id = f.member_id WHERE {$where}", $params);
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT f.*, m.full_name_ar as member_name, m.membership_number, v.description as violation_desc
             FROM fines f JOIN members m ON m.id = f.member_id LEFT JOIN violations v ON v.id = f.violation_id
             WHERE {$where} ORDER BY f.created_at DESC LIMIT {$perPage} OFFSET {$offset}", $params
        );

        return ['data' => $rows, 'pagination' => Pagination::paginate($total, $perPage, $page)];
    }

    public static function getPenaltyTypeLabel(string $type): string
    {
        return match ($type) {
            'warning'     => 'لفت نظر',
            'caution'     => 'إنذار',
            'fine'        => 'غرامة مالية',
            'suspension'  => 'إيقاف نشاط',
            'ban'         => 'منع دخول',
            'termination' => 'إنهاء عضوية',
            default       => $type,
        };
    }
}