<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------

namespace app\adminapi\service\order;

use app\common\enum\Order as OrderEnum;
use app\common\model\order\Order as OrderModel;
use app\common\model\order\OrderGoods as OrderGoodsModel;
use app\common\model\order\OrderShipping as OrderShippingModel;
use app\common\model\goods\Freight as FreightModel;
use think\facade\Request;

/**
 * @package app\adminapi\service\order
 * @class Shipping
 * @author xzncit 2024-02-28
 */
class Shipping {

    /**
     * 列表
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getList(){
        $array           = [];
        $array["total"]  = OrderShippingModel::count();
        $array["list"]   = OrderShippingModel::order("id","desc")->page($params["current"]??1,$params["size"]??10)->select()->toArray();
        return $array;
    }

    /**
     * @param $id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function detail($id){
        $freight = FreightModel::where("status",1)->select()->toArray();
        return $freight;
    }

    /**
     * 下载错误信息
     * @param $id
     * @return string
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function download($id){
        $row = OrderShippingModel::where("id",$id)->find();
        if(empty($row)){
            throw new \Exception("您要下载的内容为空",0);
        }

        if(!empty($row["error_path"])){
            return Request::domain() . "/" . $row["error_path"];
        }

        $array = json_decode($row["error_data"],true);
        if(empty($array)){
            throw new \Exception("生成失败，错误信息为空",0);
        }

        $title = ["订单号","错误原因"];
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        foreach ($title as $key => $value) {
            $sheet->setCellValueByColumnAndRow($key + 1, 1, $value);
        }

        $row = 2;
        foreach ($array as $item) {
            $column = 1;
            foreach ($item as $value) {
                $sheet->setCellValueByColumnAndRow($column, $row, ' ' . $value);
                $column++;
            }
            $row++;
        }

        $titCol = 'A';
        foreach ($title as $key => $value) {
            $sheet->setCellValue($titCol . '1', $value);
            $titCol++;
        }

        $row = 2;
        foreach ($array as $item) {
            $dataCol = 'A';
            foreach ($item as $value) {
                $sheet->setCellValue($dataCol . $row, ' ' . $value);
                $dataCol++;
            }
            $row++;
        }

        $file = public_path() . 'uploads/file/发货单错误信息-' . date("YmdHis") . '.xlsx';
        if(!file_exists(dirname($file))) mkdir($file,0777,true);
        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $writer->save($file);
        OrderShippingModel::where("id",$id)->save([
            "error_path"=>str_replace(public_path(),'',$file)
        ]);

        return Request::domain() . "/" . str_replace(public_path(),'',$file);
    }

    /**
     * 保存
     * @param array $params
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function save($params=[]){
        if(!empty($params["id"]) && $row = OrderShippingModel::where("id",$params["id"])->find()){
            $params["update_time"] = time();
            if(!empty($row["load_path"]) && !empty($params["load_path"])) unlink(public_path() . $row["load_path"]);
            OrderShippingModel::where("id",$params["id"])->save($params);
            return $params["id"];
        }else{
            if(isset($params["id"])) unset($params["id"]);
            $params["create_time"] = time();
            return OrderShippingModel::create($params)->id;
        }
    }

    public static function import($params=[]){
        $row = OrderShippingModel::where("id",$params["id"])->find();
        if(empty($row["load_path"])){
            throw new \Exception("请上传发货模板",0);
        }

        $freight = FreightModel::where("id",$params["express_id"])->find();
        if(empty($freight)){
            throw new \Exception("请选择物流公司",0);
        }

        $loadPath = explode(".",$row["load_path"]);
        $suffix   = end($loadPath);
        if('csv' == $suffix){
            $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
        }else if('xls' == $suffix){
            $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
        }else{
            $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
        }

        $spreadsheet = $reader->load(public_path() . $row["load_path"]);
        $sheetData = $spreadsheet->getActiveSheet()->ToArray();

        $shipping = [
            "order_sn"      => orderNo(), // 发货号
            "order_total"   => 0,         // 发货订单数
            "success_total" => 0,         // 成功发货数
            "error_data"    => [],        // 失败数据json
            "status"        => 1,         // 状态(1:进行中 2:成功 3:失败 4:未处理)
        ];

        $orderIndex = $expressIndex = 0;
        foreach($sheetData[0] as $key=>$value){
            if($value == "订单号"){
                $orderIndex = $key;
            }else if($value == "物流单号"){
                $expressIndex = $key;
            }
        }

        $data = [];
        foreach($sheetData as $key=>$item){
            if($key == 0){
                continue;
            }

            $item[$orderIndex]        = trim($item[$orderIndex]);
            $item[$expressIndex]      = trim($item[$expressIndex]);
            $shipping["order_total"] += 1;
            $order = OrderModel::where("order_no",$item[$orderIndex])->find();
            if(empty($order)){
                $shipping["error_data"][] = [
                    "order_no"  => $item[$orderIndex],
                    "error"     => "订单不存在"
                ];
                continue;
            }

            if(in_array($order["status"],[1,2,4,5,6,7,8])){
                $shipping["error_data"][] = [
                    "order_no"  => $item[$orderIndex],
                    "error"     => "导入失败,该订单状态：" . OrderEnum::activeText(OrderEnum::active($order))
                ];
                continue;
            }

            if(empty($item[$expressIndex])){
                $shipping["error_data"][] = [
                    "order_no"  => $item[$orderIndex],
                    "error"     => "请填写物流号"
                ];
                continue;
            }

            $shipping["success_total"] += 1;
            $data[$order["id"]] = [
                "express_id"        => $freight["id"],
                "express_name"      => $freight["title"],
                "express_no"        => $item[$expressIndex],
                "status"            => 4,
                "delivery_status"   => 2,
                "send_time"         => time()
            ];
        }

        $shipping["status"]      = 2;
        $shipping["update_time"] = time();
        try{
            if(!empty($data)){
                OrderModel::transaction(function () use($data){
                    foreach($data as $key=>$value){
                        OrderModel::where("id",$key)->save($value);
                        OrderGoodsModel::where("order_id",$key)->save(["is_send"=>1]);
                    }
                });
            }
        }catch (\Exception $ex){
            $shipping["status"] = 3;
            $shipping["error_data"][] = [
                "order_no"  => "系统信息",
                "error"     => $ex->getMessage() . '['.$ex->getFile().']['.$ex->getLine().']'
            ];
        }

        $shipping["error_data"]  = json_encode($shipping["error_data"],JSON_UNESCAPED_UNICODE);
        OrderShippingModel::where("id",$params["id"])->save($shipping);
        return true;
    }

    /**
     * 删除
     * @param $id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function delete($id){
        $shipping = OrderShippingModel::where("id",$id)->find();
        if(OrderShippingModel::where("id",$id)->delete()){
            $loadPath  = public_path() . $shipping["load_path"];
            $errorPath = public_path() . $shipping["error_path"];
            if(!empty($shipping["load_path"]) && file_exists($loadPath)) unlink($loadPath);
            if(!empty($shipping["error_path"]) && file_exists($errorPath)) unlink($errorPath);
        }
    }

}