<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */


namespace app\api\logic\Order;

use app\common\enum\DeliveryEnum;
use app\common\enum\FreightEnum;
use app\common\enum\YesNoEnum;
use app\common\logic\BaseLogic;
use app\common\model\Freight;
use app\common\service\ConfigService;

/**
 * 运费逻辑
 * Class FreightLogic
 * @package app\api\logic
 */
class FreightLogic extends BaseLogic
{
    /**
     * @notes 计算运费
     * @param $goods
     * @param $userAddress
     * @return float|int|mixed
     */
    public static function calculateFreight($goods, $userAddress)
    {
        $expressPrice = 0;
        $templateList = [];

        // 配送方式配置, 如果配送方式-快递配送已关闭则不参与运费计算
        $expressConfig = ConfigService::get('delivery_type', 'is_express', 1);

        if (empty($userAddress) || $expressConfig == YesNoEnum::NO) {
            return $expressPrice;
        }

        foreach ($goods as $good) {
            //统一邮费
            if ($good['express_type'] == 2) {
                $expressPrice += round($good['express_money'] * $good['goods_num'], 2);
            }
            //指定运费模板
            if ($good['express_type'] == 3 && $good['express_template_id'] > 0) {
                $templateList[$good['express_template_id']][] = $good;
            }
        }

        foreach ($templateList as $templateId => $templateGoods) {
            $temp = [];
            $temp['template_id'] = $templateId;
            $temp['total_volume'] = 0;
            $temp['total_weight'] = 0;
            $temp['goods_num'] = 0;
            foreach ($templateGoods as $goods) {
                $temp['total_volume'] += $goods['volume'] * $goods['goods_num'];
                $temp['total_weight'] += $goods['weight'] * $goods['goods_num'];
                $temp['goods_num'] += $goods['goods_num'];
            }
            $expressPrice += self::calculate($temp, $userAddress);
        }
        return $expressPrice;
    }


    /**
     * @notes 计算运费
     * @param $data
     * @param $userAddress
     * @return float|int|mixed
     */
    public static function calculate($data, $userAddress)
    {
        $expressPrice = 0;

        $freight = FreightLogic::getFreightsByAddress($data['template_id'], $userAddress);

        if (empty($freight)) {
            return $expressPrice;
        }
        $unit = 0;
        //按重量计算
        if ($freight['charge_way'] == FreightEnum::CHARGE_WAY_WEIGHT) {
            $unit = $data['total_weight'];
        }

        //按件数计算
        if ($freight['charge_way'] == FreightEnum::CHARGE_WAY_PIECE) {
            $unit = $data['goods_num'];
        }

        //按体积计算
        if ($freight['charge_way'] == FreightEnum::CHARGE_WAY_VOLUME) {
            $unit = $data['total_volume'];
        }

        if ($unit > $freight['first_unit'] && $freight['continue_unit'] > 0) {
            $left = ceil(($unit - $freight['first_unit']) / $freight['continue_unit']);//取整
            return $freight['first_money'] + $left * $freight['continue_money'];
        } else {
            return $freight['first_money'];
        }
    }


    /**
     * @notes 通过用户地址获取运费模板
     * @param $templateId
     * @param $address
     * @return mixed
     */
    public static function getFreightsByAddress($templateId, $address)
    {
        $districtId = $address['district_id'];
        $cityId = $address['city_id'];
        $provinceId = $address['province_id'];

        $freights = Freight::alias('f')
            ->join('freight_config c', 'c.freight_id = f.id')
            ->where('f.id', $templateId)
            ->order(['f.id' => 'desc', 'c.id' => 'desc'])
            ->select();
        $nationalFreight = [];
        foreach ($freights as $freight) {
            $regionIds = explode(',', $freight['region_id']);
            if (in_array($districtId, $regionIds)) {
                return $freight;
            }

            if (in_array($cityId, $regionIds)) {
                return $freight;
            }

            if (in_array($provinceId, $regionIds)) {
                return $freight;
            }
            //全国统一运费
            if (100000 == $freight['region_id']) {
                $nationalFreight = $freight;
            }
        }
        //会员的省市区id在商家的运费模板(指定地区)中找不到,查一下商家的全国运费模板
        return $nationalFreight;
    }

    /**
     * @notes 模板中指定地区id是否存在
     * @param $freights
     * @param $regionId
     * @return bool
     */
    public static function isExistRegionId($freights, $regionId)
    {
        foreach ($freights as $freight) {
            $regionIds = explode(',', $freight['region_id']);
            if (in_array($regionId, $regionIds)) {
                return $freight;
            }
        }
        return false;
    }
}