<?php

namespace Modules\MedBilling\Entities;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

/**
 * An insurance claim against an ERP invoice (SIFA P4-T1). Lifecycle transitions
 * are enforced by Modules\MedBilling\Services\ClaimService.
 */
class MedbillClaim extends Model
{
    protected $table = 'medbill_claims';

    protected $guarded = ['id'];

    protected $casts = [
        'total_claimed'  => 'decimal:4',
        'total_approved' => 'decimal:4',
        'total_denied'   => 'decimal:4',
        'patient_share'  => 'decimal:4',
        'payer_share'    => 'decimal:4',
        'submitted_at'   => 'datetime',
        'adjudicated_at' => 'datetime',
        'paid_at'        => 'datetime',
    ];

    public const STATUSES = [
        'draft', 'submitted', 'acknowledged', 'under_review',
        'approved', 'partially_approved', 'denied', 'paid', 'appealed',
    ];

    public function payer()
    {
        return $this->belongsTo(MedbillPayer::class, 'payer_id');
    }

    public function policy()
    {
        return $this->belongsTo(MedbillPatientPolicy::class, 'policy_id');
    }

    public function items()
    {
        return $this->hasMany(MedbillClaimItem::class, 'claim_id');
    }

    public function scopeForBusiness($query, $businessId)
    {
        return $query->where('business_id', $businessId);
    }

    /** Allocate the next claim reference: CLM-{biz}-{0000001}. */
    public static function nextClaimNo(int $businessId): string
    {
        return DB::transaction(function () use ($businessId) {
            $last = static::where('business_id', $businessId)
                ->lockForUpdate()->orderByDesc('id')->value('claim_no');
            $n = 1;
            if ($last && preg_match('/-(\d+)$/', $last, $m)) {
                $n = ((int) $m[1]) + 1;
            }

            return 'CLM-' . $businessId . '-' . str_pad((string) $n, 7, '0', STR_PAD_LEFT);
        });
    }
}
