<?php


namespace App\Http\Services;

use App\Http\Controllers\Filter\SupplierFilter;
use App\Http\Transformers\SupplierTransformer;
use App\Http\Validators\SupplierValidator;
use App\Model\LogModel;
use App\Model\RedisModel;
use App\Model\SupplierAddressModel;
use App\Model\SupplierAttachmentsModel;
use App\Model\SupplierChannelModel;
use App\Model\SupplierContactModel;
use App\Model\SupplierReceiptModel;
use Illuminate\Support\Facades\DB;

class SupplierService
{

    public $newSupplierId = 0;

    public function getSupplier($supplierId)
    {
        $model = new SupplierChannelModel();
        $supplier = $model->where('supplier_id', $supplierId)->with('contact')->first();
        $transformer = new SupplierTransformer();
        $supplier = $transformer->transformInfo($supplier);
        return $supplier ? $supplier->toArray() : [];
    }


    public function saveSupplier($channel)
    {
        $supplierTransformer = new SupplierTransformer();
        //先处理下数据
        $channel = $supplierTransformer->transformPostData($channel);

        $logService = new LogService();
        $model = new SupplierChannelModel();

        //获取未修改前的供应商,做日志数据比较存储
        $oldSupplier = $newSupplier = [];
        if (!empty($channel['supplier_id'])) {
            $oldSupplier = $model->where('supplier_id', $channel['supplier_id'])->first();
            $oldSupplier = $supplierTransformer->transformInfo($oldSupplier);
        }
        //走事务
        $supplierId = DB::connection('web')->transaction(function () use ($channel, $model, $oldSupplier) {

            //是否直接申请审核
            $isDirectApply = request()->get('direct_apply');

            $tagService = new SupplierTagService();
            //获取附加税数据
            $extraFax = [
                'supplier_id' => $channel['supplier_id'],
                'supplier_code' => $channel['supplier_code'],
                'hk' => $channel['hk'],
                'cn' => $channel['cn'],
            ];
            unset($channel['hk'], $channel['cn']);

            //获取收发货地有关的数据
            $address = array_only($channel, [
                'supplier_id',
                'shipping_address',
                'return_address',
                'return_consignee',
                'return_phone'
            ]);
            $shippingAddress = array_get($channel, 'shipping_address');
            $attachment = $channel['attachment'];
            unset($channel['return_phone'], $channel['return_address'],
                $channel['return_consignee']);
            unset($channel['shipping_address'], $channel['cn_delivery_time_period'],
                $channel['us_delivery_time_period'], $channel['attachment']);

            //sku上传规则相关设置
            $skuAuditRulerService = new SupplierSkuAuditRulerService();
            $channel['sku_audit_ruler'] = $skuAuditRulerService->getSkuAuditRulerForDB($channel['sku_audit_ruler']);


            //新增供应商操作
            if (empty($channel['supplier_id'])) {
                //处理附件信息,新增的时候才会有附件信息提交过来
                $attachmentField = [
                    'file_name',
                    'file_url',
                    'field_name',
                    'field_name',
                    'validity_type',
                    'validity_period',
                    'description',
                ];
                $attachmentData = array_only($channel, $attachmentField);
                $channel = array_except($channel, $attachmentField);

                //处理银行信息,新增的时候才会有附件信息过来
                $receiptField = [
                    'receipt_type',
                    'bank_name',
                    'bank_adderss',
                    'account_no',
                    'account_name',
                    'account_adderss',
                    'certificate',
                    'swift_code',
                ];
                $receiptData = array_only($channel, $receiptField);
                $channel = array_except($channel, $receiptField);

                //先去插入到channel表
                $channel['create_uid'] = request()->user->userId;
                $channel['create_name'] = request()->user->name;
                $channel['create_time'] = time();
                $channel['update_time'] = time();
                $channel = array_map(function ($value) {
                    if ($value === null) {
                        $value = (strval($value));
                    }
                    return $value;
                }, $channel);
                //默认是待审核
                //判断是否是直接添加并且申请审核
                if ($isDirectApply) {
                    $channel['status'] = SupplierChannelModel::STATUS_IN_REVIEW;
                } else {
                    $channel['status'] = SupplierChannelModel::STATUS_PENDING;
                }
                //第一次新增的供应商,都需要进行复审
                $channel['need_review'] = 1;

                //构建联系人的数据,只有新增的时候才有联系人数据
                $contactField = [
                    'supplier_consignee',
                    'supplier_position',
                    'supplier_email',
                    'supplier_mobile',
                    'supplier_telephone',
                    'supplier_qq',
                    'supplier_fax',
                    'can_check_uids',
                ];
                $contact = array_only($channel, $contactField);
                $channel = array_except($channel, $contactField);
                $channel['channel_uid'] = $contact['can_check_uids'];

                //插入供应商返回供应商id
                $supplierId = $this->newSupplierId = $model->insertGetId($channel);

                //添加联系人
                //要有数据才新增,麻烦得要死
                if (!checkArrayAllValueNull($contact)) {
                    $contact['supplier_id'] = $supplierId;
                    $contact['add_time'] = time();
                    $contact['admin_id'] = request()->user->userId;
                    SupplierContactModel::insert($contact);
                }
                if (!checkArrayAllValueNull($attachmentData)) {
                    //添加附件
                    SupplierAttachmentService::addAttachmentFromAddPage($supplierId, $attachmentData);
                }
                //添加银行信息,也是有填一个表单域也要新增,排除receipt_type字段,因为这个肯定有的
                if (!checkArrayAllValueNull($receiptData, ['receipt_type'])) {
                    $receiptData['supplier_id'] = $supplierId;
                    SupplierReceiptModel::insert($receiptData);
                }

                //如果是临时供应商,要打上临时供应商的标签
                if ($channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY) {
                    $tagService->saveTags($supplierId, SupplierTagService::TAG_TYPE_SYSTEM, '临时供应商', '');
                }

                //保存生成的内部编码
                $this->saveSupplierCode($supplierId);

                //新增的时候也要去添加地址了
                $supplierAddressService = new SupplierAddressService();
                $supplierAddressService->saveShippingAddress($supplierId, $shippingAddress);

            } else {

                /**这里的是更新供应商的操作**/

                $supplierId = $this->newSupplierId = $channel['supplier_id'];

                //要做进一步判断,部分字段修改不需要审核
                $auditService = new SupplierAuditService();
                $needAudit = $auditService->checkNeedAudit($supplierId, $channel, $attachment);
                if ($needAudit) {
                    $channel['status'] = SupplierChannelModel::STATUS_PENDING;
                }

                $channel['update_time'] = time();

                //这里有个逻辑,就是如果供应商类型是临时,那么要打上临时供应商的标签,如果不是,那么就要去掉这个标签
                if ($channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY) {
                    $channel['system_tags'] = explode(',', $channel['system_tags']);
                    if (!in_array('临时供应商', $channel['system_tags'])) {
                        $channel['system_tags'][] = '临时供应商';
                    }
                } else {
                    $channel['system_tags'] = explode(',', $channel['system_tags']);
                    foreach ($channel['system_tags'] as $key => $tag) {
                        if ($tag == '临时供应商') {
                            unset($channel['system_tags'][$key]);
                        }
                    }
                }
                //还有个逻辑就是,如果是临时供应商修改成正式供应商,就又要走一次复审
                if ($channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_OFFICIAL &&
                    $oldSupplier['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY) {
                    $channel['need_review'] = 1;
                    if ($channel['level'] == 'E') {
                        $channel['level'] = '';
                    }
                }

                //只要是临时供应商类型,等级就是E
                if ($channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY) {
                    $channel['level'] = 'E';
                }

                $channel['system_tags'] = trim(implode(',', $channel['system_tags']), ',');

                $model->where('supplier_id', $supplierId)->update($channel);
                //保存地址
                $supplierAddressService = new SupplierAddressService();
                $supplierAddressService->saveAddress($address);
                //保存附加费
                $extraFaxService = new SupplierExtraFeeService();
                $extraFaxService->saveSupplierExtraFee($extraFax);
                //插入系数到redis
                $this->saveRatioToRedis($supplierId);
                //各种规则
                $this->saveSkuAuditRulerToRedis($supplierId, $channel['sku_audit_ruler']);
                $this->saveSkuUploadRulerToRedis($supplierId, $channel['sku_upload_ruler']);
                //判断是否要移出待跟进
                $this->updateIsFollowUp($supplierId);
                //保存标签到标签系统
                $oldCustomerTags = array_get($oldSupplier, 'customer_tags');
                $oldSystemTags = array_get($oldSupplier, 'system_tags');
                $tagService->saveTags($supplierId, SupplierTagService::TAG_TYPE_SYSTEM, $channel['system_tags'],
                    $oldSystemTags);
                $tagService->saveTags($supplierId, SupplierTagService::TAG_TYPE_CUSTOMER, $channel['customer_tags'],
                    $oldCustomerTags);

            }
            //重新生成外部显示的编码
            $this->generateSupplierSn($supplierId, $channel['supplier_group']);
            //保存和搜索相关的标签情况
            $supplierSearchTagService = new SupplierSearchTagService();
            $supplierSearchTagService->saveSupplierSearchTags($supplierId);

            return $supplierId;

        });

        //保存日志
        $newSupplier = $model->where('supplier_id', $this->newSupplierId)->first();
        $newSupplier = $supplierTransformer->transformInfo($newSupplier);
        $logType = !empty($channel['supplier_id']) ? LogModel::UPDATE_OPERATE : LogModel::ADD_OPERATE;
        $logAction = !empty($channel['supplier_id']) ? "修改供应商基本资料" : "新增供应商";
        $logContent = !empty($channel['supplier_id']) ? '修改供应商' : '新增供应商基础信息';
        //判断是不是申请重新入驻
        if (!empty($oldSupplier['status']) && $oldSupplier['status'] == -2) {
            $logAction = "申请重新入驻";
        }
        if (!empty($oldSupplier['status']) && $oldSupplier['status'] == -1) {
            $logType = 2;
            $logAction = '新增供应商';
            $logContent = '确认新增供应商';
        }

        //过滤掉没有修改的操作,但是需要记录一条更新记录(用于判断是否可以审核)
        if (!empty($oldSupplier) && !empty($newSupplier)) {
            $oldSupplier = $oldSupplier->toArray();
            $newSupplier = $newSupplier->toArray();
            unset($oldSupplier['update_time']);
            unset($newSupplier['update_time']);
            if ($oldSupplier == $newSupplier) {
                $logService->AddLog($this->newSupplierId, LogModel::UPDATE_OPERATE, '修改供应商基本资料', '没有内容变化');
                return $supplierId;
            }
        }

        $logService->AddLog($this->newSupplierId, $logType, $logAction, $logContent, json_encode([
            'old_supplier' => $oldSupplier,
            'new_supplier' => $newSupplier
        ]));
        return $supplierId;
    }


    //生成供应商编码(外部用,展示用),supplierCode是供应商的核心编码,内部使用,可以理解为唯一标识
    public function generateSupplierSn($supplierId, $supplierGroup)
    {
        $model = new SupplierChannelModel();
        $supplier = $model->where('supplier_id', $supplierId)->first()->toArray();
        $snMap = config('fixed.SupplierSnMap');
        $supplierCodeNumber = substr($supplier['supplier_code'], 1);
        $supplierSn = array_get($snMap, $supplierGroup, "ERR") . $supplierCodeNumber;
        $model->where('supplier_id', $supplierId)->update(['supplier_sn' => $supplierSn]);
    }

    //保存价格系数到redis
    public function saveRatioToRedis($supplierId)
    {
        $model = new SupplierChannelModel();
        $supplier = $model->where('supplier_id', $supplierId)->first()->toArray();
        $Redis = new RedisModel();
        $pre = config('fixed.SUPPLIER_RATION');
        $data = array_only($supplier, ['cn_delivery_time', 'us_delivery_time', 'cn_ratio', 'us_ratio', 'supplier_id']);
        $data['supplier_id'] = strval($data['supplier_id']);
        $Redis->hset($pre, $supplier['supplier_code'], json_encode($data));
    }

    //报错供应商编码,包括系统生成的和自定义规则生成的
    public function saveSupplierCode($supplierId)
    {
        $model = new SupplierChannelModel();
        $supplier = $model->where('supplier_id', $supplierId)->first();
        if (!empty($supplier)) {
            $supplierCode = 'L' . str_pad($supplierId, 7, "0", STR_PAD_LEFT);
            return $model->where('supplier_id', $supplierId)->update([
                'supplier_code' => $supplierCode,
            ]);
        } else {
            return false;
        }
    }

    public function saveSkuAuditRulerToRedis($supplierId, $ruler)
    {
        $redis = new RedisModel();
        $redis->hset('supplier_sku_audit_ruler', $supplierId, $ruler);
    }


    public function saveSkuUploadRulerToRedis($supplierId, $ruler)
    {
        $redis = new RedisModel();
        $redis->hset('supplier_sku_upload_ruler', $supplierId, $ruler);
    }


    public function getAddress($supplierId)
    {
        $model = new SupplierAddressModel();
        $address = $model->where('supplier_id', $supplierId)->limit(2)->get();
        $data = [
            'shipping_address' => '',
            'return_address' => '',
            'return_consignee' => '',
            'return_phone' => '',
        ];
        if ($address) {
            $address = $address->toArray();
            //区分发货还是退货,1是发货,2是退货
            foreach ($address as $key => $item) {
                if ($item['address_type'] == 1) {
                    $data['shipping_address'] = $item['address'];
                } else {
                    $data['return_address'] = $item['address'];
                    $data['return_consignee'] = $item['consignee'];
                    $data['return_phone'] = $item['phone'];
                }
            }
            return $data;
        }
        return [];
    }

    //分配开发员
    public function allocatePurchaseUser($supplierId, $purchaseUid)
    {
        $result = DB::connection('web')->transaction(function () use ($supplierId, $purchaseUid) {
            $model = new SupplierChannelModel();
            $supplier = $model->where('supplier_id', $supplierId)->first();
            $supplier = $supplier ? $supplier->toArray() : [];
            $prePurchaseUid = $supplier['purchase_uid'];
            $result = $model->where('supplier_id', $supplierId)->update([
                'update_time' => time(),
                'purchase_uid' => $purchaseUid,
            ]);
            if ($result) {
                //重新分配渠道开发并且开发人员有变更的时候,就去检查是否需要跟进
                if ($supplier['purchase_uid'] != $purchaseUid) {
                    $auditService = new SupplierAuditService();
                    //还要判断是否为待跟进供应商
                    if ($auditService->checkIsNeedToFollowUpSupplier($supplierId)) {
                        $model->where('supplier_id', $supplierId)->update([
                            'to_follow_up' => 1,
                        ]);
                    }
                    //判断是否是非正式供应商,如果是,自动转正,并且修改为待审核状态
                    $this->autoChangeIsType($supplier);
                }

                //还要去记录日志
                $adminUserService = new AdminUserService();
                $prePurchaseUser = $adminUserService->getAdminUserInfoByCodeId($prePurchaseUid);
                $prePurchaseUserName = array_get($prePurchaseUser, 'name', ' ');
                $purchaseUser = $adminUserService->getAdminUserInfoByCodeId($purchaseUid);
                $purchaseUserName = array_get($purchaseUser, 'name', '');
                $logService = new LogService();
                $content = "将渠道开发员由 [${prePurchaseUserName}] 改为 [${purchaseUserName}]";
                $logService->AddLog($supplierId, LogModel::UPDATE_OPERATE, '分配渠道开发员', $content);

            }
        });

        return $result;
    }

    //分配开发员
    public function batchAllocatePurchaseUser($supplierIds, $purchaseUid)
    {
        foreach ($supplierIds as $supplierId) {
            $this->allocatePurchaseUser($supplierId, $purchaseUid);
        }
        return true;
    }

    //分配采购员
    public function allocateChannelUser($supplierId, $channelUid, $logFlag = true)
    {
        $result = DB::connection('web')->transaction(function () use ($supplierId, $channelUid, $logFlag) {
            $model = new SupplierChannelModel();
            $supplier = $model->where('supplier_id', $supplierId)->first();
            $supplier = $supplier ? $supplier->toArray() : [];
            $preChannelUid = $supplier['channel_uid'];
            $preChannelUid = explode(',', $preChannelUid);
            $preChannelUid[] = $channelUid;
            $preChannelUid = array_unique($preChannelUid);
            $preChannelUid = implode(',', $preChannelUid);
            $preChannelUid = trim($preChannelUid, ',');
            if ($logFlag) {
                $result = $model->where('supplier_id', $supplierId)->update([
                    'update_time' => time(),
                    'channel_uid' => $preChannelUid,
                ]);
            } else {
                $result = $model->where('supplier_id', $supplierId)->update([
                    'channel_uid' => $preChannelUid,
                ]);
            }

            $contactResult = false;
            if ($result) {
                $contactModel = new SupplierContactModel();
                $contact = [
                    'supplier_id' => $supplierId,
                    'can_check_uids' => $channelUid,
                    'add_time' => time(),
                    'admin_id' => !empty(request()->user->userId) ? request()->user->userId : 1000,
                ];
                $contactResult = $contactModel->insert($contact);
            }
            if ($contactResult && $logFlag) {
                //判断是否是非正式供应商,如果是,自动转正,并且修改为待审核状态
                $this->autoChangeIsType($supplier);
                //记录日志
                $adminUserService = new AdminUserService();
                $channelUser = $adminUserService->getAdminUserInfoByCodeId($channelUid);
                $channelUserName = array_get($channelUser, 'name', ' ');
                $logService = new LogService();
                $content = "添加采购员 : " . $channelUserName;
                $logService->AddLog($supplierId, LogModel::UPDATE_OPERATE, '添加采购员', $content);
            }
            return $contactResult;
        });
        $syncService = new SyncSupplierService();
        $syncService->syncSupplierToErp($supplierId);
        return $result;
    }

    //判断并且修改待跟进
    private function updateIsFollowUp($supplierId)
    {
        $model = new SupplierChannelModel();
        $auditService = new SupplierAuditService();
        //还要判断是否为待跟进供应商
        if ($auditService->checkIsNeedToFollowUpSupplier($supplierId)) {
            $model->where('supplier_id', $supplierId)->update([
                'to_follow_up' => 1,
            ]);
        } else {
            $model->where('supplier_id', $supplierId)->update([
                'to_follow_up' => 0,
            ]);
        }
    }

    //修改is_type
    public function changeSupplierIsType($supplierId, $isType)
    {
        $model = new SupplierChannelModel();
        $result = $model->where('supplier_id', $supplierId)->update([
            'supplier_type' => 1,
            'update_time' => time(),
            'is_type' => $isType,
            'status' => SupplierChannelModel::STATUS_PENDING,
        ]);
        if ($result) {
            $logService = new LogService();
            $content = '转正供应商';
            $logService->AddLog($supplierId, LogModel::UPDATE_OPERATE, '转正供应商', $content);
        }
        return $result;
    }

    //获取打印需要的数据
    public function getSupplierPrintData($supplierId)
    {
        $supplierModel = new SupplierChannelModel();
        $supplier = $supplierModel->where('supplier_id', $supplierId)->first()->toArray();
        $transformer = new SupplierTransformer();
        $supplier = $transformer->transformInfo($supplier);
        $printData = $supplier;
        $printData['apply_name'] = request()->user->name;
        $printData['apply_time'] = date('Y-m-d H:i:s', time());
        $contactService = new SupplierContactService();
        $contact = $contactService->getContactForPrint($supplierId);
        $printData['contact'] = $contact;
        $attachmentModel = new SupplierAttachmentsModel();
        $hasAgreement = $attachmentModel->where('supplier_id', $supplierId)
            ->where('field_name', 'quality_assurance_agreement')->exists() ? '已签' : '未签';
        $printData['has_agreement'] = $hasAgreement;
        $adminUserService = new AdminUserService();
        $user = $adminUserService->getAdminUserInfo(request()->user->userId);
        $printData['department_name'] = $user['department_name'];
        return $printData;
    }

    //批量申请审核供应商
    public function batchApplyInReviewSupplier($auditData = [])
    {
        $model = new SupplierChannelModel();
        foreach ($auditData as $data) {
            $result = $model->where('supplier_id', $data['supplier_id'])->update([
                'update_time' => time(),
                'apply_audit_reason' => $data['apply_audit_reason'],
                'status' => SupplierChannelModel::STATUS_IN_REVIEW
            ]);
            if (!$result) {
                return $result;
            }
            //新增一条申请审核的日志
//            (new LogService())->AddLog($data['supplier_id'], LogModel::UPDATE_OPERATE, '申请审核', '申请审核供应商');
        }
        return true;
    }

    //判断是否自动转正,并且还要修改为待审核状态给相关人员进行补充资料
    public function autoChangeIsType($supplier)
    {
        if ($supplier['is_type'] == 1) {
            $model = new SupplierChannelModel();
            $model->where('supplier_id', $supplier['supplier_id'])->update([
                'update_time' => time(),
                'status' => SupplierChannelModel::STATUS_PENDING,
                'is_type' => 0
            ]);
        }
    }

    //搜索供应商
    public static function searchSupplier($params)
    {
        $filter = new SupplierFilter();
        $limit = array_get($params, 'limit', 10);
        $query = SupplierChannelModel::with('pay_type')->select([
            'supplier_id',
            'supplier_code',
            'supplier_name',
            'pay_type',
            'channel_uid'
        ]);
        $query = $filter->listFilter($params, $query);
        $suppliers = $query->paginate($limit);
        $suppliers = $suppliers->toArray();
        $suppliers['data'] = SupplierTransformer::transformSearch($suppliers['data']);
        return $suppliers;
    }

    //校验供应商是否必填都完整了
    public static function checkSupplierFieldCompleted($supplierId)
    {
        $supplier = SupplierChannelModel::where('supplier_id', $supplierId)->first()->toArray();
        //要将部分字段从0改成'',要不然表单验证会有问题
        $needChangeField = [
            'pay_type',
            'currency',
            'supplier_group',
            'supplier_type',
            'settlement_type',
        ];
        foreach ($supplier as $key => &$value) {
            if (in_array($key, $needChangeField) && empty($value)) {
                $value = '';
            }
        }
        unset($value);
        $validator = new SupplierValidator();
        return $validator->checkSave($supplier, true);
    }

}