<?php


namespace App\Http\Validators;

use App\Http\Services\CompanyService;
use App\Http\Services\SupplierPayTypeService;
use App\Model\SupplierAttachmentsModel;
use App\Model\SupplierChannelModel;
use App\Model\SupplierContactModel;
use App\Model\SupplierReceiptModel;
use Carbon\Carbon;
use Validator;

class SupplierValidator
{
    //保存相关的验证,别问我为什么不用laravel自带的form-request类
    //因为控制器那边已经被之前的人魔改的难用的一比,而且控制器那边还接收了一大堆统一变量
    public function checkSave($validateData, $isAudit)
    {
        //整理下请求数据
        $validateData = $this->transformRequestData($validateData);

        //这里还有个很特殊的校验,就是如果是代购供应商,就直接跳过校验
        if (in_array($validateData['supplier_name'], config('field.SkipChangeSupplierTypeNames'))) {
            return null;
        }

        $isAdd = empty($validateData['supplier_id']) ? true : false;

        if (!$validateData['supplier_name']) {
            return '供应商名称不能为空';
        }

        //新增的时候要先去检验下一体化的数据,如果是实体黑名单用户,那么就不允许新增
        $regionType = $validateData['region'] == SupplierChannelModel::REGION_CN ? 1 : 2;
        //还要校验提交上来的公司是否有合法信息
        $unitedCompanyInfo = (new CompanyService())->getUnitedCompanyInfo($validateData['supplier_name'],
            $validateData['tax_number'],
            $regionType);
        $unitedInfo = $unitedCompanyInfo['united_company_info'];
        if ($unitedInfo && $isAdd) {
            if ($unitedInfo['is_entity'] == 1) {
                return '该供应商已经被一体化系统加入黑名单,不能新增';
            }

            if ($unitedInfo['company_category'] != '') {
                if ($unitedInfo['company_category'] != '普通供应商') {
                    return '该供应商已经被一体化系统加入黑名单,不能新增';
                }
            }
        }

        //没有忽略校验的权限并且供应商地区属于内地和港台才会去校验天眼查
        if (!checkPerm('IgnoreCompanyCheck') && in_array($validateData['region'], [2])) {
            $needCheckFlag = false;
            //新增的校验,然后修改的话,如果没有集团编码,并且是标准添加(非标准添加,即是特殊权限添加,不需要校验),也要去校验
            if ($isAdd) {
                $needCheckFlag = true;
            }

            if (!$isAdd) {
                $supplier = SupplierChannelModel::where('supplier_id', $validateData['supplier_id'])
                    ->first()->toArray();
                if (empty($supplier['group_code']) && $supplier['is_standard_add'] == 1) {
                    $needCheckFlag = true;
                }
            }
            if ($needCheckFlag) {
                $companyInfo = $unitedCompanyInfo['company'];
                if (empty($companyInfo)) {
                    return '公司未进行工商注册,请修改后重新提交';
                }
            }
        }

        //这个supplierId是用来判断是新增还是修改的
        $supplierId = array_get($validateData, 'supplier_id');
        //如果是修改直接提交,不是点申请审核的,只需要校验供应商名称和采购员是否完整即可
        if (!$isAudit) {
            if (empty($validateData['supplier_name'])) {
                return '供应商名称 不能为空';
            }

            if (empty($supplierId)) {
                //新增的时候,必须要设置采购员
                if (empty($validateData['can_check_uids'])) {
                    return '第一次新增供应商,必须设置联系人的采购员';
                }
                $count = SupplierChannelModel::where('supplier_name', $validateData['supplier_name'])->count();
            } else {
                //对接一体化以后,名称不能修改了,所以直接为0
                $count = 0;
            }
            if ($count) {
                return "该供应商名称已经存在,请核验后再提交";
            }

            return null;
        }

        $rules = [
            'supplier_type' => 'required',
            'supplier_name' => 'required',
            'legal_representative' => 'required',
            'supplier_address' => 'required',
            'stockup_type' => 'required',
            'main_brands' => 'required',
            'pay_type' => 'required',
            'settlement_type' => 'required',
            'established_time' => 'required',
            'currency' => 'required',
            'supplier_group' => 'required',
            'main_customers' => 'max:100',
            'registered_capital' => 'required|numeric|min:50',
            'ticket_time' => 'max:20',
            'region' => 'required',
            'cn_delivery_time' => 'regex:/^\d+\-\d$/',
            'us_delivery_time' => 'regex:/^\d+\-\d$/',
            'shipping_address' => 'max:100',
            'return_address' => 'max:100',
            'return_consignee' => 'max:50',
            'return_phone' => 'max:50',
            'cn_ratio' => 'min:1',
            'us_ratio' => 'min:1',
            'is_business_abnormal' => 'required',
            'phone' => 'required',
        ];
        //2022年6月30日(含)之前新建的供应商,在修改供应商信息时,可跳过“注册资金”这一必填项
        if (!$isAdd) {
            $supplier = SupplierChannelModel::where('supplier_id', $validateData['supplier_id'])
                ->first()->toArray();
            if ($supplier['create_time'] < Carbon::createFromDate(2022, 6, 30)->timestamp) {
                $rules['registered_capital'] = '';
            }
        }

        $contactRuler = [
            'supplier_consignee' => 'required|max:50',
            'supplier_mobile' => 'required|max:30',
            'supplier_telephone' => 'required|max:30',
            'supplier_email' => 'required|email',
            'supplier_position' => 'required|max:30',
            'can_check_uids' => 'required',
        ];

        $errorMessageList = [];

        //判断供应商类型,如果类型为临时,而且名字属于不能修改为临时的代购供应商列表里面,就要报错
        if (empty($validateData['supplier_type'])) {
            return '请选择供应商类型';
        }
        if ($validateData['supplier_type'] == 2 && in_array($validateData['supplier_name'],
                config('field.SkipChangeSupplierTypeNames'))) {
            $errorMessageList[] = '该供应商是代购供应商,不能修改为临时供应商';
        }


        //只有在提交供应商是正式的时候,才会去校验附件
        //校验附件这块,新增和修改判断的逻辑不一样
        if ($isAdd) {
            $attachmentFields = array_unique(array_get($validateData, 'field_name', []));
        } else {
            $attachmentFields = SupplierAttachmentsModel::where('supplier_id',
                $supplierId)->get()->pluck('field_name')->toArray();
        }

        if (!$attachmentFields) {
            $errorMessageList[] = '请上传附件';
        } else {
            $attachmentFields = array_unique($attachmentFields);
            //fixed.php FileNameMapping 可以知道所有对应关系
            if (!in_array('business_license', $attachmentFields)
                && $validateData['region'] == SupplierChannelModel::REGION_CN) {
                $errorMessageList[] = '国内供应商必须上传营业执照';
            }

            if ($validateData['region'] != SupplierChannelModel::REGION_CN) {
                if (!in_array('registration_certificate', $attachmentFields)) {
                    $errorMessageList[] = '海外供应商必须上传商业登记证/PI';
                }
            }

            if ($validateData['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_OFFICIAL && !in_array($validateData['supplier_group'],
                    [SupplierChannelModel::SUPPLIER_TYPE_OFFICIAL, SupplierChannelModel::SUPPLIER_GROUP_PROXY])) {
                if (!in_array('quality_assurance_agreement', $attachmentFields)) {
                    $errorMessageList[] = '供应商为正式供应商,品质保证协议必须上传 (代理商跟原厂类型除外) ';
                }
            }

            if ($validateData['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_OFFICIAL && $validateData['supplier_group'] == 1) {
                if (!in_array('proxy_certificate', $attachmentFields)) {
                    $errorMessageList[] = '供应商为正式供应商,供应商性质为代理商,代理证必须上传';
                }
            }

            //如果选择有法人身份证,那么附件上传必须要要有法人身份证
            if ($validateData['has_legal_ID_card'] == 1) {
                if (!in_array('legal_ID_card', $attachmentFields)) {
                    $errorMessageList[] = '请上传法人身份证';
                }
            }

            if ($isAdd) {
                //附件信息校验
                foreach ($validateData['validity_type'] as $key => $type) {
                    //最后一个跳过,因为是模板里的数据
                    if ($key == (count($validateData['validity_type']) - 1)) {
                        continue;
                    }
                    if ($type == 2 && !$validateData['validity_period'][$key]) {
                        $errorMessageList[] = '附件有效期为自定义的时候,必须选择时间区间';
                        break;
                    }
                }
            }

        }


        //银行信息校验
        $receiptValidator = new ReceiptValidator();
        if (empty($supplierId)) {
            $receiptData = array_only($validateData, [
                'receipt_type',
                'bank_name',
                'bank_adderss',
                'account_no',
                'account_name',
                'account_adderss',
                'certificate',
                'swift_code',
            ]);
            $receiptValidateResult = $receiptValidator->checkSave($receiptData, true);
            if ($receiptValidateResult) {
                $errorMessageList = array_merge($errorMessageList, $receiptValidateResult);
            }
        } else {
            $receipts = SupplierReceiptModel::where('supplier_id', $supplierId)->get()->toArray();
            if (!$receipts) {
                $errorMessageList[] = '供应商至少有一个财务信息,请补全';
            } else {
                foreach ($receipts as $receipt) {
                    $receiptValidateResult = $receiptValidator->checkSave($receipt);
                    if ($receiptValidateResult) {
                        $errorMessageList[] = $receiptValidateResult;
                    }
                }
            }

        }


        //联系人校验
        if ($isAdd) {
            $rules = array_merge($rules, $contactRuler);
        } else {
            //修改的时候,还要去判断联系人是否有
            //至少要有一个联系方式
            $contactCount = SupplierContactModel::where('supplier_id', $supplierId)->count();
            if (!$contactCount) {
                $errorMessageList[] = "供应商至少要有一个联系人,请补全";
            }
        }
        //币种为人民币的话需要验证税号
        if ($validateData['currency'] == 1) {
            $rules['tax_number'] = 'required';
        }

        //如果付款方式为账期,那么月结天数一定要选
        if ($validateData['pay_type'] == 1) {
            if (!array_get($validateData, 'pay_type_value')) {
                $errorMessageList[] = '付款方式选择账期,月结天数必须设置';
            }
        }

        //新增的时候,渠道开发 不能为空
        $rules['purchase_uid'] = 'required';

        $messages = $this->messages();
        $validator = Validator::make($validateData, $rules, $messages);
        if ($validator->fails()) {
            $errors = $validator->errors()->all();
            $errorMessageList = array_merge($errors, $errorMessageList);
        }

        //检验名称是否已经存在数据库
        if (!empty($validateData['supplier_name'])) {
            $companyNameCount = 0;
            if (empty($supplierId)) {
                $count = SupplierChannelModel::where('supplier_name', $validateData['supplier_name'])->count();
                $companyNameCount = SupplierChannelModel::where('register_company_name',
                    $validateData['register_company_name'])->where('register_company_name', '!=', '')->count();
            } else {
                //对接一体化以后,名称不能修改了,所以直接为0
                $count = 0;
            }
            if ($count) {
                $errorMessageList[] = "该供应商名称已经存在,请核验后再提交";
            }
            if ($companyNameCount) {
                $errorMessageList[] = "该注册公司名已经存在,请核验后再提交";
            }
        }

        if (!$isAdd) {
            //还要去判断当前提交人是否存在与其关联的联系人没有完善
            $codeId = request()->user->codeId;
            $notCompleteContacts = (new SupplierContactModel())->getNotCompletedContacts($supplierId, $codeId);
            if ($notCompleteContacts) {
                $errorMessageList[] = "存在和你相关的联系人没有完善,请先去完善相关联系人";
            }
        }

        return implode('|', $errorMessageList);
    }

    private function messages()
    {
        return [
            'supplier_type.required' => '供应商类别 不能为空',
            'supplier_name.required' => '供应商名称 不能为空',
            'currency.required' => '结算币种 不能为空',
            'legal_representative.required' => '法人代表 不能为空',
            'stockup_type.required' => '合作类型 不能为空',
            'pay_type.required' => '付款周期 不能为空',
            'settlement_type.required' => '结算方式 不能为空',
            'register_company_name.required' => '注册公司名 不能为空',
            'supplier_group.required' => '公司性质 不能为空',
            'supplier_address.required' => '注册地址 不能为空',
            'region.required' => '所在区域 不能为空',
            'purchase_uid.required' => '渠道开发员 不能为空',
            'cn_ratio.min' => '人民币系数必须是大于1的浮点数',
            'business_license.required' => '营业执照 不能为空',
            'established_time.required' => '成立时间 不能为空',
            'us_ratio.min' => '美金系数必须是大于1的浮点数',
            'us_delivery_time.regex' => '香港货期格式不正确',
            'cn_delivery_time.regex' => '大陆货期格式不正确',
            'tax_number.required' => '如果选择币种为人民币,则公司税号 不能为空',
            'supplier_consignee.required' => '联系方式的联系人 不能为空',
            'supplier_consignee.max' => '联系方式的联系人不能超过50个字符',
            'supplier_position.required' => '联系方式的职称 不能为空',
            'phone.required' => '公司电话 不能为空',
            'supplier_position.max' => '联系方式的职称不能超过30个字符',
            'supplier_telephone.required' => '联系方式的座机号 不能为空',
            'supplier_mobile.required' => '联系方式的手机号 不能为空',
            'supplier_mobile.max' => '联系方式的手机号不能超过30个字符',
            'supplier_email.required' => '联系方式的邮箱 不能为空',
            'supplier_email.email' => '联系方式的邮箱格式不对',
            'can_check_uids.required' => '联系方式对应的采购员 不能为空',
            'shipping_address.required' => '发货地址 不能为空',
            'shipping_address.max' => '发货地址不能超过100个字符',
            'return_address.max' => '退货地址不能超过100个字符',
            'return_consignee.max' => '退货收货人不能超过50个字符',
            'return_phone.max' => '退货收货人电话不能超过50个字符',
            'main_brands.required' => '主营品牌 不能为空',
            'main_customers.max' => '3-5家客户描述不能超过100个字符',
            'ticket_time.max' => '到票时间不能超过20个字符',
            'billing_period_detail.required' => '账期详情 不能为空',
            'billing_period_detail.max' => '账期详情不能超过100个字符',
            'registered_capital.required' => '注册资金 不能为空(单位为万)',
            'registered_capital.min' => '注册资金至少50万(单位为万)',
            'registered_capital.numeric' => '注册资金填纯数字即可,默认单位是万',
            'is_business_abnormal.required' => '是否历史经营异常必选,请补充选择'
        ];
    }

    public function transformRequestData($validateData)
    {
        foreach ($validateData as &$item) {
            if (!is_array($item)) {
                $item = trim($item);
            }
        }
        return $validateData;
    }
}