<?php
declare(strict_types=1);

namespace App\Modules\HR\Models;

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

class HrEmployeeLoan extends Model
{
    protected static string $table = 'hr_employee_loans';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = true;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'employee_profile_id', 'loan_type', 'loan_amount', 'installment_amount',
        'number_of_installments', 'remaining_amount', 'paid_installments',
        'request_date', 'start_deduction_date', 'reason',
        'status', 'workflow_instance_id',
        'approved_by', 'approved_at', 'disbursed_date', 'notes',
    ];

    public static function getLoanTypes(): array
    {
        return [
            'salary_advance'  => 'سلفة راتب',
            'personal_loan'   => 'قرض شخصي',
            'emergency_loan'  => 'سلفة طوارئ',
        ];
    }

    public static function getStatuses(): array
    {
        return [
            'pending'   => 'في الانتظار',
            'approved'  => 'معتمد',
            'disbursed' => 'تم الصرف',
            'repaying'  => 'جاري السداد',
            'settled'   => 'تم السداد',
            'rejected'  => 'مرفوض',
            'cancelled' => 'ملغى',
        ];
    }

    public static function getActiveForEmployee(int $profileId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM hr_employee_loans
             WHERE employee_profile_id = ?
               AND status IN ('disbursed', 'repaying')
               AND is_archived = 0
             ORDER BY start_deduction_date ASC",
            [$profileId]
        );
    }

    public static function getDueInstallments(int $profileId, int $year, int $month): array
    {
        $db = App::getInstance()->db();
        $periodDate = sprintf('%04d-%02d-01', $year, $month);

        return $db->select(
            "SELECT li.*, el.loan_type, el.loan_amount
             FROM hr_loan_installments li
             JOIN hr_employee_loans el ON el.id = li.loan_id
             WHERE el.employee_profile_id = ?
               AND li.due_date <= LAST_DAY(?)
               AND li.due_date >= ?
               AND li.status = 'pending'
             ORDER BY li.due_date ASC",
            [$profileId, $periodDate, $periodDate]
        );
    }

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

        if (!empty($filters['employee_profile_id'])) {
            $where .= ' AND el.employee_profile_id = ?';
            $params[] = (int) $filters['employee_profile_id'];
        }
        if (!empty($filters['status'])) {
            $where .= ' AND el.status = ?';
            $params[] = $filters['status'];
        }
        if (!empty($filters['loan_type'])) {
            $where .= ' AND el.loan_type = ?';
            $params[] = $filters['loan_type'];
        }

        $countRow = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM hr_employee_loans el
             JOIN hr_employee_profiles p ON p.id = el.employee_profile_id WHERE {$where}",
            $params
        );
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT el.*, CONCAT(p.first_name_ar, ' ', p.last_name_ar) as full_name_ar, p.employee_number
             FROM hr_employee_loans el
             JOIN hr_employee_profiles p ON p.id = el.employee_profile_id
             WHERE {$where}
             ORDER BY el.request_date DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

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