package com.sunxung.factoring.service.customerinformation.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.ResponseJson;
import com.sunxung.factoring.entity.ValidatorEntity;
import com.sunxung.factoring.entity.acceptance.CAcceptancePriceAdjustInfo;
import com.sunxung.factoring.entity.customerinformation.Customer;
import com.sunxung.factoring.entity.customerinformation.SupplierBankCardInfo;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.sys.*;
import com.sunxung.factoring.entity.tradingPlatform.Platform;
import com.sunxung.factoring.entity.vo.ConditionVo;
import com.sunxung.factoring.mapper.customerinformation.CustomerMapper;
import com.sunxung.factoring.mapper.sys.UserMapper;
import com.sunxung.factoring.service.customerinformation.CustomerService;
import com.sunxung.factoring.service.customerinformation.SupplierBankCardInfoService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.sys.OrgService;
import com.sunxung.factoring.service.sys.RoleService;
import com.sunxung.factoring.service.sys.UserOrgRelService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liutao
 */
@Service
@PropertySource("classpath:config.properties")
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private UserService userService;

    @Value("${config.enterprise.url}")
    private String enterpriseUrl;

    @Value("${sop.getFlushUrl}")
    private String flushUrl;

    @Autowired
    private OrgService orgService;

    @Autowired
    private UserOrgRelService userOrgRelService;

    @Autowired
    private SupplierBankCardInfoService supplierBankCardInfoService;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private IEnterpriseService iEnterpriseService;

    @Autowired
    private PlatformService platformService;

    @Override
    public GridPage<Customer> findList(ConditionVo conditionVo) {
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("synchronize_time");
        String enterpriseName = conditionVo.getCondition();
        if (StringUtil.isNotEmpty(enterpriseName)) {
            queryWrapper.like("enterprise_name", enterpriseName);
        }
        queryWrapper.eq("supplier", conditionVo.isJudge());
        //如果是供应商登录
        String userName = ThreadLocalUtil.getUser().getName();
        Customer supplier = getOne(new QueryWrapper<Customer>().eq("enterprise_name", userName).eq("supplier", 1));
        if (supplier != null) {
            queryWrapper.eq("id", supplier.getId());
        }
        Page<Customer> page = new Page<>(conditionVo.getPage(), conditionVo.getRows());
        List<Customer> customers = page(page, queryWrapper).getRecords();
        //TODO
//        customers.stream().forEach(c -> autoButtonFlag(c));
        return new GridPage<>(conditionVo.getRows(), conditionVo.getPage(), page.getTotal(), customers);
    }

    @Override
    public List<Customer> findCoreBusiness(boolean supplier) {
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("gmt_create");
        queryWrapper.eq("supplier", supplier);
        return list(queryWrapper);
    }

    @Override
    public List<Customer> findEnterpriseBySop(ConditionVo conditionVo) {

        ResponseEntity<Customer[]> responseEntity = null;
        if (conditionVo == null || conditionVo.getCondition() == null) {
            responseEntity = restTemplate.getForEntity(enterpriseUrl, Customer[].class);
        } else if (conditionVo.getCondition() != null) {
            responseEntity = restTemplate.getForEntity(enterpriseUrl + "?keyValue=" + conditionVo.getCondition(), Customer[].class);
        }
        if (responseEntity.getBody() != null) {
            return Arrays.asList(responseEntity.getBody());
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Customer customer) throws Exception {
        //是否存在该社会信用代码所表示的供应商
        List<Customer> list = list(new QueryWrapper<Customer>().eq("socialCreditCode", customer.getSocialCreditCode()).eq("supplier", customer.getSupplier()));
        if (!list.isEmpty()) {
            throw new BusinessException(CodeUtil.FAIL, "企业已添加，勿重复操作");
        }
//        loginName为供应商账号
        String loginName = customer.getAccount();
//        判断该账号是否存在
        if (userService.getByLoginName(loginName) != null) {
            throw new BusinessException(CodeUtil.FAIL, "loginName重复，请重新输入");
        }
//        添加供应商或者核心企业
//        判断是否是供应商
        if (customer.getSupplier()) {//供应商
            if (StringUtil.isEmpty(customer.getAccount())) {
                throw new BusinessException(CodeUtil.FAIL, "供应商账号不能为空");
            }
        }
        ValidatorUtil.validator(ValidatorEntity.ValidatorType.ADD, customer);
        save(customer);
        if (customer.getSupplier()) {
//            创建账号
            User user = new User();
            user.setLoginName(loginName);
//            启用
            user.setEnabled(true);
            user.setName(customer.getEnterpriseName());
            user.setPassword(ConstantUtil.PASSWORD);
            user.setEnterpriseCustomerId(customer.getId());
            userService.addCustomerUser(user);
            UserOrgRel userOrgRel = new UserOrgRel();
            userOrgRel.setUserId(user.getId());

            Org org = orgService.getByCode(ConstantUtil.SUPPLIER);
            if (org == null) {
                throw new BusinessException(CodeUtil.FAIL, "获取不到名称为供应商的组织机构");
            }
            userOrgRel.setOrgId(org.getId());
            userOrgRel.setOrgCode(org.getInternalCode());
            userOrgRel.setGradation(0);
            userOrgRel.setUserIdentity(false);
            userOrgRelService.save(userOrgRel);

            Role role = roleService.getByRoleName(ConstantUtil.SUPPLIER_ROLE);
            if (role==null){
                throw new BusinessException(CodeUtil.FAIL,"获取不到供应商角色");
            }
            UserRoleRel userRoleRel = new UserRoleRel();
            userRoleRel.setRoleId(role.getId());
            userRoleRel.setUserId(user.getId());
            userService.addUserRoleRel(userRoleRel);
        }
//        法大大认证
//        String customerId = ElectronicSignatureUtil.registerAccount(customer.getSocialCreditCode(), "2");
        String authResult = ElectronicSignatureUtil.getAuthUrl("2", customer.getSocialCreditCode(), null);
        JSONObject authJson = (JSONObject) JSONObject.parse(authResult);
        String authUrl = authJson.getString("authUrl");
        String customerId = authJson.getString("customerId");
        String shortUrl = ElectronicSignatureUtil.shortUrl(null, authUrl);
        customer.setShortAuthUrl(shortUrl);
        customer.setShortAuthUrlCreate(new Date());
        customer.setFddCustomerId(customerId);
        customer.setAuthUrl(authUrl);
        customer.setAuthStatus(0);
        customer.setSynchronizeTime(new Date(System.currentTimeMillis()));
        updateById(customer);
    }

    @Override
    public Customer findDetail(long id) {
        Customer customer = getById(id);
        User user = userService.selectByEnterpriseCustomerId(id);
        customer.setAccount(user.getLoginName());
        customer.setPassword(user.getPassword());
        return customer;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void flush() {
        //从sop获取所有的企业信息
        List<Customer> enterpriseBySop = findEnterpriseBySop(null);
        //查询出已存在的所有企业信息
        List<Customer> customers = list();
        //循环对比
        for (Customer customer : customers) {
            for (Customer customerSop : enterpriseBySop) {
                if (customer.getSocialCreditCode().equals(customerSop.getSocialCreditCode())) {
                    if (!customer.getEnterpriseName().equals(customerSop.getEnterpriseName())) {
                        User user = userService.selectByEnterpriseCustomerId(customer.getId());
                        user.setName(customerSop.getEnterpriseName());
                        userService.updateCustomerUser(user);
                        customer.setEnterpriseName(customerSop.getEnterpriseName());
                        customer.setSynchronizeTime(new Date(System.currentTimeMillis()));
                        updateById(customer);
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyAccount(Customer customer) {
        ValidatorUtil.validator(ValidatorEntity.ValidatorType.UPDATE, customer);
        updateById(customer);
        User user = userService.selectByEnterpriseCustomerId(customer.getId());
        user.setLoginName(customer.getAccount());
        userService.updateCustomerUser(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyPassword(Customer customer) {
        updateById(customer);
        User user = userService.selectByEnterpriseCustomerId(customer.getId());
        user.setPassword(ConstantUtil.PASSWORD);
        userService.updateCustomerUser(user);
    }

    @Override
    public void modifyBankDetail(Customer customer, long supplierId) {
        List<SupplierBankCardInfo> oldBankInfos = supplierBankCardInfoService.list(new QueryWrapper<SupplierBankCardInfo>().eq("supplier_id", supplierId));
        List<SupplierBankCardInfo> banks = customer.getBanks();
        banks.forEach(r -> {
            if (r.getId() == null) {
                r.setSupplierId(supplierId);
                supplierBankCardInfoService.save(r);
            }
        });
        List<SupplierBankCardInfo> deleteBankInfos = oldBankInfos.stream().filter(oldBankInfo -> !banks.stream().filter(newBank -> newBank.getId() != null).anyMatch(r -> r.getId().equals(oldBankInfo.getId()))).collect(Collectors.toList());
        deleteBankInfos.forEach(r -> {
            supplierBankCardInfoService.updateById(r);
        });

    }

    @Override
    public List<Customer> getLocalUserSuppliers() {
        Long userId = ThreadLocalUtil.getUserId();
        User user = ThreadLocalUtil.getUser();
        List<Long> orgIdList = user.getOrgIdList();
        List<Customer> list = new ArrayList<>();
        list.add(new Customer("请选择供应商"));
        //供应商登录  只有自己一个选项
        if (orgIdList.contains(orgService.getByCode(ConstantUtil.SUPPLIER).getId())) {
            list.add(customerMapper.selectById(userId));

        } else {
            list.addAll(customerMapper.getLocalUserSuppliers(userId));
        }
        return list;
    }

    @Override
    public List<Customer> getLocalUserCustomers(Long supplierId) {
        Long userId = ThreadLocalUtil.getUserId();
        User user = ThreadLocalUtil.getUser();
        List<Long> orgIdList = user.getOrgIdList();
        List<Customer> list = new ArrayList<>();
        list.add(new Customer("请选择核心企业"));
        //供应商登录  只有自己一个选项
        if (orgIdList.contains(orgService.getByCode(ConstantUtil.SUPPLIER).getId())) {
            list.addAll(customerMapper.getLocalSupplierCustomers(supplierId));
        } else {
            List<Customer> localUserCustomers = customerMapper.getLocalUserCustomers(userId, supplierId);
            list.addAll(localUserCustomers);
        }
        return list;
    }

    @Override
    public User getUserBySupplierId(Long supplierId) {
        List<User> userList = userMapper.getUserByEnterpriseCustomerId(supplierId);
        if (userList == null || userList.size() == 0) {
            return null;
        }
        if (userList.size() != 1) {
            throw new BusinessException(CodeUtil.FAIL, "数据库信息异常");
        }
        return userList.get(0);
    }

    @Override
    public List<Customer> getCustomersByUser() {
        Long managerId = ThreadLocalUtil.getUserId();
        ArrayList<Customer> result = new ArrayList<>();
        result.add(new Customer("请选择核心企业"));
        List<Customer> customers = baseMapper.getCustomersByUser(managerId);
        result.addAll(customers);
        return result;
    }

    @Override
    public List<Customer> getSuppliersByUser(String businessNumber) {
        ArrayList<Customer> result = new ArrayList<>();
        result.add(new Customer("请选择供应商"));
        List<Customer> suppliersByUser = baseMapper.getSuppliersByUser(businessNumber);
        result.addAll(suppliersByUser);
        return result;
    }


    @Override
    public void updateShortUrl(Date date) {
        List<Customer> list = list();
        if (list != null && list.size() > 0) {
            for (Customer customer : list) {
                if (customer.getAuthStatus().equals(0)) {
                    Date shortContractLinkCreate = customer.getShortAuthUrlCreate();
                    long between = DateUtil.between(shortContractLinkCreate, date, DateUnit.DAY);
                    if (between >= 6) {
                        String newShortUrl = ElectronicSignatureUtil.shortUrl(null, customer.getAuthUrl());
                        customer.setShortAuthUrl(newShortUrl);
                        customer.setShortAuthUrlCreate(date);
                        updateById(customer);
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCustomer(Long id) {
//        removeById(id);
        iEnterpriseService.removeById(id);
        User user = userService.selectByEnterpriseCustomerId(id);
        if (user != null) {
            userService.delete(user.getId());
        }
    }

    @Override
    public void flushUrl(Long id) {
//        Customer customer = customerMapper.selectById(id);
        Enterprise enterprise = iEnterpriseService.getById(id);
        //删除中间服务的认证信息
        String message = ElectronicSignatureUtil.removeAuthInfo(enterprise.getSocialCreditCode());
//        法大大重新认证生成新的认证链接
        String authResult = ElectronicSignatureUtil.getAuthUrl("2", enterprise.getSocialCreditCode(), null);
        JSONObject authJson = (JSONObject) JSONObject.parse(authResult);
        String authUrl = authJson.getString("authUrl");
        String customerId = authJson.getString("customerId");
        String shortUrl = ElectronicSignatureUtil.shortUrl(null, authUrl);
        enterprise.setShortAuthUrl(shortUrl);
        enterprise.setFddCustomerId(customerId);
        enterprise.setAuthUrl(authUrl);
        enterprise.setAuthStatus(false);
        iEnterpriseService.updateById(enterprise);
    }

    @Override
    public void flushUrlByCompany(Long id) {
        Enterprise enterprise = iEnterpriseService.getById(id);
        ResponseJson forObject = restTemplate.getForObject(flushUrl+"?code="+enterprise.getSocialCreditCode(), ResponseJson.class);
        Map<String,String> data = (Map) forObject.getData();
        enterprise.setAuthUrl(data.get("authUrl"));
        enterprise.setShortAuthUrl(data.get("shortAuthUrl"));
        enterprise.setAuthStatus(false);
        enterprise.setCertificateSignUrl(data.get("certificateSignUrl"));
        enterprise.setCertificateShortSignUrl(data.get("certificateShortSignUrl"));
        enterprise.setCertificateSignStatus(0);
        enterprise.setFddCustomerId(data.get("fddCustomerId"));
        enterprise.setCertificateContractId(data.get("certificateContractId"));
        enterprise.setCertificateTransactionId(data.get("certificateTransactionId"));
        //更新自动签链接
        enterprise.setAutoSignUrl(data.get("autoSignUrl"));
        enterprise.setShortAutoSignUrl(data.get("shortAutoSignUrl"));
        enterprise.setAutoSignStatus(0);
        iEnterpriseService.updateById(enterprise);
    }

    @Override
    public void flushStatusBySop(String code, Integer type) {
        Enterprise enterprise = iEnterpriseService.getOne(new QueryWrapper<Enterprise>().eq("fdd_customer_id", code)
                .orderByDesc("gmt_create").last("limit 1"));
        if (enterprise != null){
            if (type == 1){
                enterprise.setAutoSignStatus(1);
            }else if (type == 2){
                enterprise.setCertificateSignStatus(1);
            }
            iEnterpriseService.updateById(enterprise);
        }
        Platform platform = platformService.getOne(new QueryWrapper<Platform>().eq("fdd_customer_id", code)
                .orderByDesc("gmt_create").last("limit 1"));
        if (platform != null && type == 1){
            platform.setAutoSignStatus(true);
            platformService.updateById(platform);
        }
    }

    /**
     * 填充是否能够删除
     *
     * @param customer
     */
//    public void autoButtonFlag(Customer customer) {
//        customer.setDeleteFlag(true);
//        List<BusinessBasicInfo> businessBasicInfos = null;
//        List<BusinessSupplierInfo> businessSupplierInfos = null;
//        if (!customer.getSupplier()) {
//            //核心企业
//            businessBasicInfos = businessBasicInfoService.list(new QueryWrapper<BusinessBasicInfo>().eq("enterprise_customer_info_id", customer.getId()));
//        } else {
//            //供应商
//            businessSupplierInfos = businessSupplierInfoService.list(new QueryWrapper<BusinessSupplierInfo>().eq("supplier_id", customer.getId()));
//        }
//        if ((businessBasicInfos != null && businessBasicInfos.size() > 0) || (businessSupplierInfos != null && businessSupplierInfos.size() > 0)) {
//            customer.setDeleteFlag(false);
//        }
//
//    }
}
