<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    protected $guarded = [];

    protected function casts(): array
    {
        return [
            'customer_fields' => 'array',
            'risk_snapshot' => 'array',
            'discount_snapshot' => 'array',
            'paid_at' => 'datetime',
            'completed_at' => 'datetime',
            'claimed_at' => 'datetime',
            'failed_at' => 'datetime',
            'info_requested_at' => 'datetime',
        ];
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function timelines()
    {
        return $this->hasMany(OrderTimeline::class);
    }

    public function paymentAttempts()
    {
        return $this->hasMany(PaymentAttempt::class);
    }

    public function coupon()
    {
        return $this->belongsTo(Coupon::class);
    }

    public function couponRedemption()
    {
        return $this->hasOne(CouponRedemption::class);
    }

    public function customerNotifications()
    {
        return $this->hasMany(CustomerNotification::class);
    }

    public function notificationDeliveries()
    {
        return $this->hasMany(NotificationDelivery::class);
    }

    public function manualPaymentSubmissions()
    {
        return $this->hasMany(ManualPaymentSubmission::class);
    }

    public function latestPaymentAttempt()
    {
        return $this->hasOne(PaymentAttempt::class)->latestOfMany();
    }

    public function assignee()
    {
        return $this->belongsTo(User::class, 'assigned_to');
    }

    public function maskedCustomerFields(): array
    {
        return collect($this->customer_fields ?? [])
            ->map(fn ($value) => is_string($value) ? $this->maskValue($value) : $value)
            ->all();
    }

    public function canRevealDigitalCodes(): bool
    {
        return $this->payment_status === 'paid' && $this->fulfillment_status === 'completed';
    }

    private function maskValue(string $value): string
    {
        if (mb_strlen($value) <= 4) {
            return str_repeat('*', mb_strlen($value));
        }

        return mb_substr($value, 0, 2).str_repeat('*', max(0, mb_strlen($value) - 4)).mb_substr($value, -2);
    }
}
