<?php


namespace App\Http\Services;

//后台用户相关信息服务
use App\Model\LogModel;
use App\Model\RedisModel;
use App\Model\SupplierAccountModel;
use App\Model\SupplierAttachmentsModel;
use App\Model\SupplierChannelModel;
use App\Model\SupplierContactModel;
use App\Model\SupplierReceiptModel;
use App\Model\SupplierSyncModel;
use App\Model\UserInfoModel;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class SyncSupplierService
{
    //同步供应商到erp
    public function syncSupplierToErp($supplierId, $conn = null)
    {
        //先去获取供应商的信息
        $supplierModel = new SupplierChannelModel();
        $supplier = $supplierModel->where('supplier_id', $supplierId)->first();
        if (empty($supplier)) {
            return false;
        }

        if (!$supplier['group_code']) {
            return true;
        }

        //先去sync表查询记录是否存在,不存在新增,存在修改
        $supplierSyncModel = new SupplierSyncModel();
        $exist = $supplierSyncModel->where('supplier_id', $supplierId)->count();
        if (!empty($exist)) {
            $supplierSyncModel->where('supplier_id', $supplierId)->update([
                'erp_sync_status' => 0,
                'update_time' => time(),
                'last_update_source' => 2,
            ]);
        } else {
            $supplierSyncModel->insert([
                'erp_sync_status' => 0,
                'supplier_id' => $supplierId,
                'add_time' => time(),
                'last_update_source' => 2,
            ]);
        }
        $contactModel = new SupplierContactModel();
        $contact = $contactModel->where('supplier_id', $supplier['supplier_id'])->orderBy('contact_id', 'asc')->first();
        $purchases = $this->getUserCodeSn($supplier['channel_uid']);
        $message = [
            'name' => $supplier['supplier_name'],
            'PTID' => $supplier['supplier_code'],
            'STATUS' => $supplier['status'] == 2 ? 1 : 2,
        ];

        if (!empty($supplier['supplier_group'])) {
            $message['groupNumber'] = array_get(config('sync.SyncSupplierType'), $supplier['supplier_group'], '');
        }

        if (!empty($supplier['tax_number'])) {
            $message['taxRegisterNo'] = $supplier['tax_number'];
        }
        if (!empty($purchases)) {
            $message['personName'] = $purchases;
        }
        if (!empty($supplier['supplier_address'])) {
            $message['address'] = $supplier['supplier_address'];
        }
        if (!empty(array_get($contact, 'supplier_consignee'))) {
            $message['contactPerson'] = array_get($contact, 'supplier_consignee');
        }
        if (!empty(array_get($contact, 'supplier_telephone'))) {
            $message['phone'] = array_get($contact, 'supplier_telephone');
        }
        if (!empty($supplier['currency'])) {
            $message['currencyNumber'] = array_get(config('sync.SyncCurrencyType'), $supplier['currency']);
        }
        $supplierIds = SupplierChannelModel::where('supplier_name', $supplier['supplier_name'])
            ->where('is_type', 0)->where('group_code', '!=', '')
            ->pluck('supplier_id')->toArray();
        //银行信息
        $receipts = SupplierReceiptModel::with(['nation'])->whereIn('supplier_id', $supplierIds)->get()->toArray();
        //->where('bank_name', '!=', '')->where('account_no', '!=', '')->get()->toArray();
        if (!empty($receipts)) {
            $message['bankinfo'] = [];
            foreach ($receipts as $receipt) {
                $address = !empty($receipt['nation']['name_cn']) ? $receipt['nation']['name_cn'] . $receipt['account_adderss'] : $receipt['account_adderss'];
                $message['bankinfo'][] = [
                    "bank" => $receipt['bank_adderss'],
                    'bankaccount' => $receipt['account_no'],
                    'supplier' => $receipt['bank_name'],
                    'swiftCode' => $receipt['swift_code'],
                    'beneficiary' => $receipt['account_name'],
                    'bankAddress' => $address,
                    'infoEvidence' => $receipt['certificate'],
                    'recid' => $receipt['receipt_id'],
                    'intermediaryBank' => $receipt['intermediary_bank'],
                    'remark' => $receipt['remark'],
                ];
            }
        }

        //审核流程
        $updateLogs = (new LogService())->getLogs($supplierId, LogModel::UPDATE_OPERATE);
        $reviewProcess = [];
        if ($updateLogs) {
            foreach ($updateLogs as $log) {
                $content = is_array($log['content']) && !empty($log['content']) ? $log['content'][0] : $log['content'];
                $reviewProcess[] = [
                    'operator' => $log['admin_name'],
                    'operateDate' => $log['add_time'],
                    'operate' => mb_substr($content, 0, 200) . '...',
                ];
            }
        }
        $message['reviewProcess'] = $reviewProcess;
        if ($conn) {

        } else {
            $conn = new AMQPStreamConnection(config('database.connections.rabbitmq.host'),
                config('database.connections.rabbitmq.port'),
                config('database.connections.rabbitmq.login'),
                config('database.connections.rabbitmq.password'));
        }
        $channel = $conn->channel();
        $channel->queue_declare('supplier_sync', false, true, false, false);
        Log::warning(json_encode($message));
        $msg = new AMQPMessage(json_encode($message),
            array('content_type' => 'text/plain'));
        $result = $channel->basic_publish($msg, '', 'supplier_sync');
//        $result = $channel->basic_publish($msg);
    }

    //获取采购人员列表
    private function getUserCodeSn($purchaseUid)
    {
        $purchaseUid = explode(',', $purchaseUid);
        if (empty($purchaseUid)) {
            return [];
        }
        $adminIds = DB::connection()->table('lie_intracode')->whereIn('code_id', $purchaseUid)->pluck('admin_id');
        return DB::connection()->table('user_info')->whereIn('userId', $adminIds)->pluck('code_sn');
    }

    /**
     * 推送参数:
     * {
     * "system_id": "1",//来源系统id  1猎芯科技,2猎芯供应链,3crm
     * "source_sn": "1", //源编码 各个系统标识公司的标识号
     * "company_type": "1",//公司类型,1客户,2供应商
     * "company_name": "测试公司", //公司名称
     * "company_tax_no": "1234567",//公司税号
     * "init_nature": "1234567",//来源公司初鉴性质
     * "region": "1",//地区,1大陆,2海外
     * "pi_file_url": "dasdsa"  //pi附件地址
     * }
     */
    //同步供应商信息到一体化中心
    public function syncSupplierToUnited($supplierId)
    {
        $supplier = SupplierChannelModel::where('supplier_id', $supplierId)->first()->toArray();
        $fileUrl = SupplierAttachmentsModel::where('supplier_id', $supplierId)
            ->where('field_name', 'registration_certificate')
            ->value('file_url');
        //构建需要同步的数据
        $syncData = [
            'system_id' => 1,
            'source_sn' => (string)$supplier['supplier_id'],
            'company_type' => 2,
            'company_name' => $supplier['supplier_name'],
            'company_tax_no' => $supplier['tax_number'],
            'init_nature' => Arr::get(config('fixed.SupplierGroup'), $supplier['supplier_group']),
            'region' => $supplier['region'] == SupplierChannelModel::REGION_CN ? 1 : 2,
            'pi_file_url' => $fileUrl ?: '',
        ];
        (new QueueDeliveryService())->push(QueueDeliveryService::PUSH_TYPE_SYNC_HTTP, '/sync/Company/syncCompany',
            $syncData);
    }

    /**
     * 推送参数为:
     * {
     * "group_code":"K0000013", //集团编码
     * "source_sn":"1",//来源id,其实就是供应商id,因为新增的时候丢过去的就是供应商id
     * "company_name":"\u6d4b\u8bd5\u516c\u53f8",//公司名
     * "init_nature":"1234567",//初鉴性质
     * "company_nature":"1234567"//公司真实性质
     * "company_category":"普通供应商"//公司类别,只要不是普"通供应商",就是要拉黑的
     * }
     **/
    //接收一体化系统处理好的供应商数据,可能是第一次新增返回的数据,也可能是一体化那边修改的数据需要同步到供应商
    public function syncSupplierToUnitedResult($syncResult)
    {
        Log::warning(json_encode($syncResult));
        $redis = new RedisModel();
        $groupCode = array_get($syncResult, 'group_code');
        $sourceSn = array_get($syncResult, 'source_sn');
        $companyCategory = array_get($syncResult, 'company_category', '');
        $supplier = SupplierChannelModel::where('supplier_id', $sourceSn)->orWhere('group_code', $groupCode)->first();
        $supplier = !empty($supplier) ? $supplier->toArray() : [];
        $supplierId = $supplier['supplier_id'];
        //$supplier = SupplierChannelModel::where('supplier_id', $supplierId)->first()->toArray();
        //if ($companyCategory != '') {
        //    //实体名单和黑名单都要拉黑,如果不属于黑名单,那么就要将状态改成审核中
        //    if ($companyCategory == '黑名单供应商') {
        //        $data['status'] = SupplierChannelModel::STATUS_BLOCK;
        //        $data['block_reason'] = '一体化系统黑名单供应商';
        //    } else if ($companyCategory == '实体名单供应商') {
        //        $this->receiveEntityResult($supplier['supplier_name'], -1);
        //    } else {
        //        $preIsEntity = $supplier['is_entity'];
        //        //判断原来是拉黑状态,才变成审核中,因为有可能不是修改公司类型,只是修改公司性质
        //        if ($supplier['status'] == SupplierChannelModel::STATUS_BLOCK) {
        //            $data['status'] = SupplierChannelModel::STATUS_IN_REVIEW;
        //        }
        //        //如果之前是禁用,并且是实体名单,那么就要恢复之前的状态
        //        if ($supplier['status'] === SupplierChannelModel::STATUS_DISABLE && $preIsEntity == SupplierChannelModel::IS_ENTITY_TRUE) {
        //            $this->receiveEntityResult($supplier['supplier_name'], 1);
        //        }
        //    }
        //}
        $data['sync_united_status'] = SupplierChannelModel::SYNC_UNITED_STATUS_OK;
        $data['group_code'] = $groupCode;
        $data['company_nature'] = $syncResult['company_nature'];
        $data['company_category'] = $companyCategory;
        //$sourceSn不为空的话,就是代表这是第一次新增的供应商,所以会回传供应商id过来
        if ($sourceSn) {
            $data['supplier_name'] = $syncResult['company_name'];
            $result = SupplierChannelModel::where('supplier_id', $supplierId)
                ->update($data);
            if ($result) {
                //再次同步供应商到金蝶
                $this->syncSupplierToErp($supplierId);
            }
            return $result;
        } else {
            return SupplierChannelModel::where('group_code', $groupCode)
                ->update($data);
        }
    }

    //接收一体化的广播信息,对供应商进行实体名单操作
    //加入实体名单后,要做很多事情,比如禁用供应商,也要禁用供应商账号等等,还要记录禁用之前的状态,等到移除实体名单以后,要恢复之前的状态
    public function receiveEntityResult($resultData)
    {
        $supplierName = $resultData['company_name'];
        $result = $resultData['result'];
        $tagList = $resultData['tag_list'];
        Log::warning('一体化拉黑结果 : ' . ($supplierName . '---' . $result));

        //根据result,修改供应商的是否是实体名单字段
        $isEntity = ($result == 1) ? false : true;
        $isEntityResult = SupplierChannelModel::IS_ENTITY_FALSE; //默认不是实体名单
        $warningType = array_get($resultData, 'warning_type') == 1 ? '供应商名称' : '地址';
        $warningKeyword = array_get($resultData, 'warning_keyword', '无');
        $warningData = array_get($resultData, 'warning_data', '无');
        //我这里的状态和一体化的结果判断有点对不上,因为我这把是(是否实体名单),而一体化那边是实体名单是否通过,所以要转换
        if ($result == 1) {
            $isEntityResult = SupplierChannelModel::IS_ENTITY_FALSE;
            $logContent = $reason = '移除实体名单';
        } else {
            if ($result == -1) {
                $isEntityResult = SupplierChannelModel::IS_ENTITY_TRUE;
                $logContent = $reason = "属于实体名单,系统自动拉入黑名单. 风险类型 : $warningType 风险词 : $warningKeyword 风险数据 : $warningData";
            }
            if ($result == 0) {
                $isEntityResult = SupplierChannelModel::IS_ENTITY_NEED_CONFIRM;
                $logContent = $reason = "待确认实体名单,系统自动拉入禁止交易,请联系“运营合规部门”进行确认. 风险类型 : $warningType 风险词 : $warningKeyword 风险数据 : $warningData";
            }
            if ($result == -3) {
                $handleReason = array_get($resultData, 'handle_result', '无');
                $isEntityResult = SupplierChannelModel::IS_ENTITY_REJECT;
                $logContent = $reason = "被驳回供应商,系统自动拉入禁止交易,处理说明 : $handleReason . 风险类型 : $warningType 风险词 : $warningKeyword 风险数据 : $warningData";
            }
        }
        //去修改供应商入驻相关的数据
        (new ChainService())->changeChainIsEntity($supplierName, $isEntityResult);

        //先找到对应的供应商(草稿的跳过),如果没有那跳过
        $suppliers = SupplierChannelModel::where('supplier_name', $supplierName)->get()->toArray();
        if (empty($suppliers)) {
            Log::error('供应商不存在');
            return true;
        }

        foreach ($suppliers as $supplier) {
            //判断是否是同名多供应商,如果是的话,如果是之前已经禁用的,则直接跳过
            if (count($suppliers) > 1) {
                if ($supplier['status'] == SupplierChannelModel::STATUS_DISABLE) {
                    Log::warning("检测到同名供应商并且属于禁用状态,跳过,供应商id为 : " . $supplier['supplier_id']);
                    continue;
                }
            }

            $originIsEntity = $supplier['is_entity'];
            //$supplier = $supplier->toArray();
            $supplierId = $supplier['supplier_id'];
            //先把修改之前的状态给记录下来
            $status = $supplier['status'];
            $preStatus = null;
            $redis = new RedisModel();
            if ($isEntity) {
                $cachedExists = $redis->hexists('supplier_status_before_disable', $supplierId);
                if (!$cachedExists) {
                    $redis->hset('supplier_status_before_disable', $supplierId, $status);
                }
            } else {
                $preStatus = $redis->hget('supplier_status_before_disable', $supplierId);
                if ($preStatus === null) {
                    $preStatus = $status;
                }

                $redis->hdel('supplier_status_before_disable', $supplierId);
            }

            //如果是移除实体名单,但是得到之前的状态还是禁止交易,那么强行改成审核中
            if (!$isEntity && $preStatus == SupplierChannelModel::STATUS_DISABLE) {
                $preStatus = SupplierChannelModel::STATUS_IN_REVIEW;
            }
            //修改供应商的状态
            SupplierChannelModel::where('supplier_id', $supplierId)->update([
                'is_entity' => $isEntityResult,
                'update_time' => time(),
                //这里的逻辑是,因为取消实体名单以后,如果之前的状态是黑名单的话,直接变成待提审
                'status' => $isEntity ? SupplierChannelModel::STATUS_DISABLE : ($preStatus == SupplierChannelModel::STATUS_BLOCK ? SupplierChannelModel::STATUS_IN_REVIEW : $preStatus),
                'disable_reason' => $reason,
                'united_tags' => !empty($tagList) ? implode(',', $tagList) : '',
            ]);
            $isYunxinSupplier = false;
            //还要去修改对应的供应商账号,也是要记录禁用前的状态
            $supplierAccount = SupplierAccountModel::where('supplier_id', $supplierId)->first();
            //如果是待确认,那么不需要去操作供应商账号
            if (!empty($supplierAccount) && $result != 0) {
                $isYunxinSupplier = true;
                $supplierAccount = $supplierAccount->toArray();
                $accountPreStatus = $supplierAccount['a_status'];
                if ($isEntity) {
                    $redis->hset('supplier_account_status_before_disable', $supplierId, $accountPreStatus);
                } else {
                    $accountPreStatus = $redis->hget('supplier_account_status_before_disable', $supplierId);
                    $redis->hdel('supplier_account_status_before_disable', $supplierId);
                }
                SupplierAccountModel::where('supplier_id', $supplierId)->update([
                    'update_time' => time(),
                    'a_status' => $isEntity ? SupplierAccountModel::STATUS_DISABLE : SupplierAccountModel::STATUS_ENABLE,
                ]);
            }

            //还要去打日志
            $logService = new LogService();
            $logService->AddAdminLog($supplierId, LogModel::UPDATE_OPERATE, '实体名单设置', $logContent);

            //原始状态一定要是实体或者非实体才要发邮件
            if (!in_array($originIsEntity, [1, -1])) {
                continue;
            }

            //不属于加入实体名单和移除实体名单不去发邮件
            if (!in_array($result, [1, -1])) {
                return true;
            }


            //判断是否有实体化状态变化,没有的话就跳过
            if ($originIsEntity == $isEntityResult) {
                continue;
            }

            //本地
            if (isDevEnvironment()) {
                continue;
            }


            //return true;
            //还要去发送邮箱给采购员,线上采购员,采购总
            $data['data']['supplier_code'] = $supplier['supplier_code'];
            $data['data']['supplier_name'] = $supplier['supplier_name'];
            $data['data']['supplier_group_name'] = array_get(config('fixed.SupplierGroup'), $supplier['supplier_group']);
            $data['data']['operation'] = $isEntity ? '确认' : '移除';
            $data['data']['content'] = $isEntity ? ' 注意:实体名单的供应商已自动拉入禁止交易,无法使用!' : '注意:已移除实体名单的供应商,状态自动返回到前一个状态!';
            $data['data']['ps_content'] = $isEntity ? 'PS:如果该供应商为芯链商家,该供应商的芯链账号无法登录芯链系统!' : 'PS:如果该供应商为芯链商家,该供应商的芯链账号可正常登录芯链系统!';
            if ($isYunxinSupplier) {
                $data['data']['supplier_name'] .= ' (芯链商家) ';
            }
            if (!empty($supplier['yunxin_channel_uid'])) {
                $yunxinChannelUser = (new AdminUserService())->getAdminUserInfoByCodeId($supplier['yunxin_channel_uid']);
                if (!empty($yunxinChannelUser['email'])) {
                    //先发送邮件给线上采购员
                    (new MessageService())->sendMessage('supplier_entity_notice_purchase', $data, $yunxinChannelUser['email'], true);
                }
                //再找出线上采购员对应的采购总监
                $supervisorDepartmentId = $yunxinChannelUser['department_id'];
                $positionId = \DB::table('user_position')->where('department_id', $supervisorDepartmentId)
                    ->where('position_name', '采购总监')->value('position_id');
                if (!empty($positionId)) {
                    $supervisor = UserInfoModel::where('position_id', $positionId)->first()->toArray();
                    if (!empty($supervisor['email'])) {
                        (new MessageService())->sendMessage('supplier_entity_notice_purchase', $data, $supervisor['email'], true);
                    }
                }
            }

            if (!empty($supplier['channel_uid'])) {
                $supplier['channel_uid'] = explode(',', $supplier['channel_uid']);
                $channelUserList = (new AdminUserService())->getAdminUserListByCodeIds($supplier['channel_uid']);
                foreach ($channelUserList as $channelUser) {
                    if (!empty($channelUser['email'])) {
                        (new MessageService())->sendMessage('supplier_entity_notice_purchase', $data, $channelUser['email'], true);
                    }
                }
            }
        }
    }
}