<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class Payment extends Model
{
    use HasFactory;
    use SoftDeletes;

    protected $guarded = [
        'id',
        'created_at',
        'updated_at',
    ];

    protected $appends = [];

    protected $with = ['model'];

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope('order', function (Builder $builder): void {
            $builder->orderByDesc('created_at');
        });
        static::creating(function (Payment $item): void {
            $item->token = $item->token ?: self::createToken($item->price, $item->user_id);
            if ($item->user_id && ! $item->cellphone) {
                $user = $item->user ?? User::find($item->user_id);
                if ($user) {
                    $item->cellphone = $user->cellphone;
                    $item->email = $user->email;
                }
            }
            if ($item->model_type === \App\Models\Order::class && $item->model_id && ! $item->project_id) {
                $order = \App\Models\Order::find($item->model_id);
                if ($order?->project_id) {
                    $item->project_id = $order->project_id;
                }
            }
        });
    }

    protected function code(): Attribute
    {
        return Attribute::make(get: function () {
            return Str::random(3) . $this->id;
        });
    }

    protected function url(): Attribute
    {
        return Attribute::make(get: function () {
            if ($this->token) {
                return url('/api/payment/pay/?token=' . $this->token);
            }

            return null;
        });
    }

    protected function formattedType(): Attribute
    {
        return Attribute::make(get: function ($value) {
            return self::getType()[$this->model_type] ?? [];
        });
    }

    protected function formattedGateway(): Attribute
    {
        return Attribute::make(get: function ($value) {
            if (isset($this->gateway)) {
                return self::getGatewayType()[$this->gateway];
            }

            return 'درگاه ملت';
        });
    }

    public static function getType()
    {
        return [
            'App\Models\Purchase' => 'خرید',
            'App\Models\Charge' => 'شارژ حساب',
        ];
    }

    public static function getGatewayType()
    {
        return [
            1 => 'درگاه به پرداخت',
            2 => 'در محل - کیوسک یک',
            3 => 'در محل - کیوسک دو',
            4 => 'در محل - کیوسک سه',
        ];
    }

    /*
    * Relations
    */
    public function createdBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updatedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

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

    public function project(): BelongsTo
    {
        return $this->belongsTo(Project::class, 'project_id');
    }

    public function model(): MorphTo
    {
        return $this->morphTo('model');
    }

    private static function createToken($price, $user_id)
    {
        $crypt_price = Hash::make($price);
        $crypt_user_id = Hash::make($user_id);

        return $crypt_user_id . Str::random(10) . $crypt_price;
    }
}
