<?php

namespace Kylin\Payment\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 支付记录模型
 */
class PaymentRecord extends Model
{
    /**
     * 表名
     */
    protected $table = 'payment_records';

    /**
     * 可填充字段
     */
    protected $fillable = [
        'payment_type',
        'payment_name',
        'out_trade_no',
        'trade_no',
        'amount',
        'currency',
        'status',
        'payload',
        'result',
        'callback_data',
        'paid_at',
        'refunded_at',
        'closed_at',
        'remark',
    ];

    /**
     * 类型转换
     */
    protected $casts = [
        'amount' => 'decimal:2',
        'payload' => 'json',
        'result' => 'json',
        'callback_data' => 'json',
        'paid_at' => 'datetime',
        'refunded_at' => 'datetime',
        'closed_at' => 'datetime',
    ];

    /**
     * 支付状态常量
     */
    const STATUS_PENDING = 'pending';
    const STATUS_SUCCESS = 'success';
    const STATUS_FAILED = 'failed';
    const STATUS_REFUNDED = 'refunded';
    const STATUS_CLOSED = 'closed';

    /**
     * 标记为支付成功
     */
    public function markAsSuccess(array $data = []): bool
    {
        return $this->update([
            'status' => self::STATUS_SUCCESS,
            'trade_no' => $data['trade_no'] ?? $this->trade_no,
            'paid_at' => now(),
            'callback_data' => $data['callback_data'] ?? $this->callback_data,
        ]);
    }

    /**
     * 标记为支付失败
     */
    public function markAsFailed(string $reason = ''): bool
    {
        return $this->update([
            'status' => self::STATUS_FAILED,
            'remark' => $reason,
        ]);
    }

    /**
     * 标记为已退款
     */
    public function markAsRefunded(array $data = []): bool
    {
        return $this->update([
            'status' => self::STATUS_REFUNDED,
            'refunded_at' => now(),
            'remark' => $data['remark'] ?? $this->remark,
        ]);
    }

    /**
     * 标记为已关闭
     */
    public function markAsClosed(string $reason = ''): bool
    {
        return $this->update([
            'status' => self::STATUS_CLOSED,
            'closed_at' => now(),
            'remark' => $reason,
        ]);
    }

    /**
     * 根据商户订单号查找记录
     */
    public static function findByOutTradeNo(string $outTradeNo, ?string $paymentType = null): ?self
    {
        $query = self::where('out_trade_no', $outTradeNo);

        if ($paymentType) {
            $query->where('payment_type', $paymentType);
        }

        return $query->first();
    }

    /**
     * 根据支付平台订单号查找记录
     */
    public static function findByTradeNo(string $tradeNo, ?string $paymentType = null): ?self
    {
        $query = self::where('trade_no', $tradeNo);

        if ($paymentType) {
            $query->where('payment_type', $paymentType);
        }

        return $query->first();
    }

    /**
     * 获取指定状态的记录
     */
    public static function getByStatus(string $status, array $where = []): \Illuminate\Database\Eloquent\Builder
    {
        $query = self::where('status', $status);

        foreach ($where as $key => $value) {
            $query->where($key, $value);
        }

        return $query;
    }
}
