<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\common\model\dealer;

use cores\BaseModel;
use app\common\library\helper;
use app\common\model\Order as OrderModel;
use app\common\model\OrderGoods as OrderGoodsModel;
use app\common\enum\order\refund\RefundType as RefundTypeEnum;
use app\common\enum\order\refund\AuditStatus as AuditStatusEnum;
use think\model\relation\BelongsTo;

/**
 * 分销商订单模型
 * Class Order
 * @package app\common\model\dealer
 */
class Order extends BaseModel
{
    // 定义表名
    protected $name = 'dealer_order';

    // 定义主键
    protected $pk = 'id';

    /**
     * 订单所属用户
     * @return BelongsTo
     */
    public function user(): BelongsTo
    {
        $module = self::getCalledModule();
        return $this->belongsTo("app\\{$module}\\model\\User");
    }

    /**
     * 关联主商城订单记录
     * @return BelongsTo
     */
    public function order(): BelongsTo
    {
        $module = self::getCalledModule();
        return $this->belongsTo("app\\{$module}\\model\\Order");
    }

    /**
     * 一级分销商用户
     * @return BelongsTo
     */
    public function dealerFirst(): BelongsTo
    {
        return $this->belongsTo('User', 'first_user_id');
    }

    /**
     * 二级分销商用户
     * @return BelongsTo
     */
    public function dealerSecond(): BelongsTo
    {
        return $this->belongsTo('User', 'second_user_id');
    }

    /**
     * 三级分销商用户
     * @return BelongsTo
     */
    public function dealerThird(): BelongsTo
    {
        return $this->belongsTo('User', 'third_user_id');
    }

    /**
     * 订单详情 (自定义查询条件)
     * @param $where
     * @return static|array|null
     */
    public static function detail($where)
    {
        return static::get($where);
    }

    /**
     * 订单详情 (根据ID获取)
     * @param int $orderId
     * @return static|null
     */
    public static function getDetailByOrderId(int $orderId): ?Order
    {
        return static::detail(['order_id' => $orderId]);
    }

    /**
     * 计算订单分销佣金
     * @param OrderModel $order
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getCapitalByOrder(OrderModel $order): array
    {
        // 分销佣金设置
        $setting = Setting::getItem('commission', $order['store_id']);
        // 分销层级
        $level = Setting::getItem('basic', $order['store_id'])['level'];
        // 分销订单佣金数据
        $capital = [
            // 订单总金额(不含运费)
            'orderPrice' => helper::bcsub($order['pay_price'], $order['express_price']),
            // 一级分销佣金
            'first_money' => 0.00,
            // 二级分销佣金
            'second_money' => 0.00,
            // 三级分销佣金
            'third_money' => 0.00
        ];
        // 计算分销佣金
        foreach ($order['goods'] as $goods) {
            // 判断存在商品退款则不计算佣金
            if (static::checkExistRefunded($goods)) {
                continue;
            }
            // 商品实付款金额
            $goodsPrice = min($capital['orderPrice'], $goods['total_pay_price']);
            // 计算商品实际佣金
            $goodsCapital = static::calculateGoodsCapital($setting, $goods, (string)$goodsPrice);
            // 累积分销佣金
            $level >= 1 && $capital['first_money'] = helper::bcadd($capital['first_money'], $goodsCapital['first_money']);
            $level >= 2 && $capital['second_money'] = helper::bcadd($capital['second_money'], $goodsCapital['second_money']);
            $level == 3 && $capital['third_money'] = helper::bcadd($capital['third_money'], $goodsCapital['third_money']);
        }
        return $capital;
    }

    /**
     * 计算商品实际佣金
     * @param array $setting 分销设置(结算)
     * @param OrderGoodsModel $goods 商品信息
     * @param string $goodsPrice 商品实付款金额
     * @return array
     */
    private static function calculateGoodsCapital(array $setting, OrderGoodsModel $goods, string $goodsPrice): array
    {
        // 判断是否开启商品单独分销
        if (!$goods['is_ind_dealer']) {
            // 全局分销比例
            return [
                'first_money' => helper::bcmul($goodsPrice, helper::bcdiv($setting['first_money'], 100)),
                'second_money' => helper::bcmul($goodsPrice, helper::bcdiv($setting['second_money'], 100)),
                'third_money' => helper::bcmul($goodsPrice, helper::bcdiv($setting['third_money'], 100))
            ];
        }
        // 商品单独分销
        if ($goods['dealer_money_type'] == 10) {
            // 分销佣金类型:百分比
            return [
                'first_money' => $goodsPrice * helper::bcdiv($goods['first_money'], 100),
                'second_money' => $goodsPrice * helper::bcdiv($goods['second_money'], 100),
                'third_money' => $goodsPrice * helper::bcdiv($goods['third_money'], 100)
            ];
        } else {
            // 分销佣金类型:固定金额
            return [
                'first_money' => helper::bcmul($goods['total_num'], $goods['first_money']),
                'second_money' => helper::bcmul($goods['total_num'], $goods['second_money']),
                'third_money' => helper::bcmul($goods['total_num'], $goods['third_money'])
            ];
        }
    }

    /**
     * 验证商品是否存在售后退款(进行中)
     * @param OrderGoodsModel $goods 商品信息
     * @return bool
     */
    public static function checkExistRefunding(OrderGoodsModel $goods): bool
    {
        return !empty($goods['refund']) && $goods['refund']['type'] == RefundTypeEnum::RETURN
            && $goods['refund']['audit_status'] == AuditStatusEnum::WAIT;
    }

    /**
     * 验证商品是否存在售后退款(已退款)
     * @param OrderGoodsModel $goods 商品信息
     * @return bool
     */
    private static function checkExistRefunded(OrderGoodsModel $goods): bool
    {
        return !empty($goods['refund']) && $goods['refund']['type'] == RefundTypeEnum::RETURN
            && $goods['refund']['audit_status'] == AuditStatusEnum::REVIEWED;
    }
}