package com.winsun.migration.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.netflix.discovery.converters.Auto;
import com.winsun.auth.model.user.Role;
import com.winsun.bean.HhrUser;
import com.winsun.bean.School;
import com.winsun.bean.SchoolPackage;
import com.winsun.bean.SysUser;
import com.winsun.bean.activity.HhrActivity;
import com.winsun.bean.activity.HhrActivityRecord;
import com.winsun.item.core.shiro.ShiroKit;
import com.winsun.item.modular.system.dao.RoleMapper;
import com.winsun.mapper.HhrUserMapper;
import com.winsun.mapper.SchoolPackageMapper;
import com.winsun.mapper.SysUserMapper;
import com.winsun.mapper.activity.ActivityMapper;
import com.winsun.mapper.activity.ActivityRecordMapper;
import com.winsun.migration.mapper.db1.NewDatabases;
import com.winsun.migration.mapper.db2.OldDatabases;
import com.winsun.migration.mapper.db3.YrymDatabases;
import com.winsun.migration.service.IMigrationService;
import com.winsun.smsUtils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("migrationService")
public class MigrationServiceImpl implements IMigrationService {

    @Autowired
    private NewDatabases newDatabases;

    @Autowired
    private OldDatabases oldDatabases;

    @Autowired
    private YrymDatabases yrymDatabases;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private HhrUserMapper hhrUserMapper;

    @Resource
    private ActivityMapper activityMapper;

    @Resource
    private ActivityRecordMapper activityRecordMapper;

    @Resource
    private RoleMapper roleMapper;

    @Autowired
    private SchoolPackageMapper schoolPackageMapper;

    /**
     * 移动卡和学校关联表(只有新增)
     */
    public void migrationSchoolPackage() {
        // 查询一人一码关联表
        List<Map<String, Object>> schoolPackages = yrymDatabases.getSchoolPackage();
        List<Map<String, Object>> schoolXbPackages = yrymDatabases.getSchoolXbPackage();
        schoolPackages.addAll(schoolXbPackages);
        SchoolPackage schoolPackage = null;
        for(Map<String, Object> map : schoolPackages) {
            schoolPackage = new SchoolPackage();
            if(map.get("school_id") == null || map.get("package_id") == null ) {
                this.insertLog("hhr_school_package", JSONObject.toJSONString(map), "error", "");
                continue;
            }
            if (StringUtils.isBlank(map.get("school_id").toString()) || StringUtils.isBlank(map.get("package_id").toString())) {
                this.insertLog("hhr_school_package", JSONObject.toJSONString(map), "error", "");
                continue;
            }
            schoolPackage.setPackageId(map.get("package_id").toString());
            schoolPackage.setSchoolId(map.get("school_id").toString());
            schoolPackageMapper.insert(schoolPackage);
        }
    }

    /**
     * 迁移用户数据
     */
    public void migrationUser() throws NoSuchAlgorithmException {
        // 更新合伙人用户
        List<Map<String, Object>> oldUserList = oldDatabases.getUser();
        log.info(JSON.toJSONString(oldUserList.get(0)));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        SysUser user = null;
        HhrUser hhrUser = null;
        List<String> hhrError = new ArrayList<>();
        List<String> sysError = new ArrayList<>();
        for(Map<String, Object> stringObjectMap : oldUserList) {
            try{
                user = new SysUser();
                user.setId(stringObjectMap.get("id").toString());
                user.setAccount(stringObjectMap.get("account") != null ? stringObjectMap.get("account").toString() : "");
                user.setName(stringObjectMap.get("name") != null ? stringObjectMap.get("name").toString() : "");
                user.setSalt(ShiroKit.getRandomSalt(6));
                user.setPassword(ShiroKit.md5("123456",user.getSalt()));
                user.setSex(stringObjectMap.get("sex") != null ? stringObjectMap.get("sex").toString() : "1");
                user.setPhone(stringObjectMap.get("account") != null ? stringObjectMap.get("account").toString() : "");
                user.setRoleid(stringObjectMap.get("role_id") != null ? stringObjectMap.get("role_id").toString() : "251");
                // 默认合伙人
                user.setDeptid(stringObjectMap.get("dept_id") != null ? stringObjectMap.get("dept_id").toString() : "1");
                user.setStatus(stringObjectMap.get("state") != null ? stringObjectMap.get("state").toString() : "");
                user.setCreatetime(stringObjectMap.get("register_time") != null ? sdf.parse(stringObjectMap.get("register_time").toString()) : new Date());
                user.setUpdateTime(new Date());
                try{
                    int insert = newDatabases.insert(user);
                    if (insert < 1) {
                        sysError.add(stringObjectMap.get("id").toString());
                    }
                }catch(Exception e) {
                    if(e instanceof DuplicateKeyException){
                        System.out.println("更新记录");
                        sysUserMapper.updateById(user);
                    }else{
                        throw e;
                    }
                }
            }catch(Exception e) {
                    sysError.add(stringObjectMap.get("id").toString());
                    log.info(e.getMessage());
                    this.insertLog("sys_user", user, "error", e.getMessage());
            }
            try {
                hhrUser = new HhrUser();
                hhrUser.setId(stringObjectMap.get("id").toString());
                hhrUser.setIdCard(stringObjectMap.get("id_card") != null ? stringObjectMap.get("id_card").toString() : "");
                hhrUser.setYsm("1");
                hhrUser.setWxHeadImgUrl(stringObjectMap.get("wx_head_img_url") != null ? stringObjectMap.get("wx_head_img_url").toString() : "");
                hhrUser.setWxNickName(stringObjectMap.get("wx_nick_name") != null ? stringObjectMap.get("wx_nick_name").toString() : "");
                hhrUser.setOpenId(stringObjectMap.get("open_id") != null ? stringObjectMap.get("open_id").toString() : "");
                hhrUser.setUploadState(0);
                hhrUser.setGrade(stringObjectMap.get("grade") != null ? stringObjectMap.get("grade").toString() : "");
                hhrUser.setPosition(stringObjectMap.get("position") != null ? stringObjectMap.get("position").toString() : "");
                hhrUser.setParentId(stringObjectMap.get("parent_user_id") != null ? stringObjectMap.get("parent_user_id").toString() : "");
                hhrUser.setParentIds(stringObjectMap.get("parent_ids") != null ? stringObjectMap.get("parent_ids").toString() : "");
                hhrUser.setIsActive(Integer.parseInt(stringObjectMap.get("is_active") != null ? stringObjectMap.get("is_active").toString() : ""));
                try{
                    int i = newDatabases.insertHhr(hhrUser);
                    if (i < 1) {
                        hhrError.add(stringObjectMap.get("id").toString());
                    }
                }catch(Exception e) {
                    if(e instanceof DuplicateKeyException){
                        hhrUserMapper.updateById(hhrUser);
                    }else{
                        throw e;
                    }
                }
            }catch(Exception e) {
                hhrError.add(stringObjectMap.get("id").toString());
                log.error(e.getMessage());
                this.insertLog("hhr_user", hhrUser, "error", e.getMessage());
            }
        }

        insertResult(oldUserList.size(), "sys_user", sysError);
        insertResult(oldUserList.size(), "hhr_user", hhrError);

        this.insertYRYMUser();

        // 此为新增（只要运行一次）
//        this.migrationSchoolPackage();
    }

    /**
     * 插入一人一码用户
     */
    public void insertYRYMUser() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 更新一人一码用户
        List<Role> roles = roleMapper.selectList(new EntityWrapper<>());
        List<String> insertAccount = new ArrayList<>();
        List<String> updateAccount = new ArrayList<>();

        // 查询 dzqd_user、dzqd_user_supervisor、dzqd_user_role
        List<Map<String, Object>> loginUserList = yrymDatabases.getLoginUserList();
        for(Map<String, Object> map : loginUserList) {
            try{

                if (map.get("login_name") != null && "admin".equals(map.get("login_name"))) {
                    continue;
                }
                SysUser sysUser = null;
                // 判断是否有合伙人id
                if (map.get("spervisor") == null) {

                    Wrapper<SysUser> wrapper = new EntityWrapper<>();
                    wrapper.eq("account", map.get("login_name").toString());
                    List<SysUser> sysUsers = sysUserMapper.selectList(wrapper);
                    if (sysUsers != null && sysUsers.size() != 0) {
                        sysUser = sysUsers.get(0);
                    }else{
                        // 无，则作为新用户添加到库中
                        sysUser = new SysUser();
                    }

                    // 自增
//                  sysUser.setId(map.get("id").toString());
                    sysUser.setAccount(map.get("login_name") != null ? map.get("login_name").toString() : "");
                    sysUser.setName(map.get("user_name") != null ? map.get("user_name").toString() : "");
                    sysUser.setSalt(ShiroKit.getRandomSalt(6));
                    sysUser.setPassword(ShiroKit.md5("123456",sysUser.getSalt()));
                    sysUser.setSex(map.get("sex") != null ? map.get("sex").toString() : "1");
                    sysUser.setPhone(map.get("mobilephone") != null ? map.get("mobilephone").toString() : "");
//                    sysUser.setRoleid(map.get("role_id") != null ? map.get("role_id").toString() : "");
                    // 默认合伙人部门
                    sysUser.setDeptid(map.get("dept_id") != null ? map.get("dept_id").toString() : "1");
                    sysUser.setStatus("1");
                    sysUser.setCreatetime(map.get("create_on") != null ? sdf.parse(map.get("create_on").toString()) : new Date());
                    sysUser.setUpdateTime(new Date());
                    int i = 0;

                    // 存在则更新
                    if (StringUtils.isNotBlank(sysUser.getId())) {
                        i = sysUserMapper.updateById(sysUser);
                    }else{
                        i = sysUserMapper.insert(sysUser);
                    }
                    if (i == 0) {
                        insertAccount.add(sysUser.getAccount());
                    }
                }else{
                    sysUser = sysUserMapper.selectById(map.get("spervisor").toString());
                }
                if (sysUser == null) {
                    insertLog("sys_user", JSONObject.toJSONString(map), "error", "sysUser信息为空");
                    continue;
                }

                // 获取用户权限名称
                String roleStr = null;
                String roleIds = "";
                if (map.get("roleName") != null) {
                    roleStr = map.get("roleName").toString();
                    // 添加权限
                    for(Role role : roles) {
                        if (sysUser.getRoleid() != null && sysUser.getRoleid().indexOf(role.getId() + "") > -1) {
                            continue;
                        }
                        if (role.getName().equals("县分管理员（订单）")) {
                            if (roleStr.indexOf("订单") > -1) {
                                roleIds += role.getId() + ",";
                            }
                        }else{
                            if (roleStr.indexOf(role.getName()) > -1) {
                                roleIds += role.getId() + ",";
                            }
                        }
                    }
                }

                if (StringUtils.isNotBlank(roleIds) && map.get("login_name") != null) {
                    SysUser updateUser = new SysUser();
                    updateUser.setRoleid(roleIds + (sysUser.getRoleid() == null ? "" : sysUser.getRoleid()));
                    Wrapper<SysUser> wrapper = new EntityWrapper<>();
                    wrapper.eq("account", sysUser.getAccount());
                    Integer update = sysUserMapper.update(updateUser, wrapper);
                    if (update == 0) {
                        updateAccount.add(map.get("login_name").toString());
                    }
                }
            }catch(Exception e) {
                e.printStackTrace();
                log.error(JSONObject.toJSONString(map));
                insertLog("sys_user", JSONObject.toJSONString(map), "error", e.getMessage());
            }
        }

        insertResult(loginUserList.size(), "sys_user insert", insertAccount);
        insertResult(loginUserList.size(), "sys_user update role", updateAccount);
    }

    /**
     * 迁移日志
     * @param tableName 迁移表名
     * @param object 迁移对象
     * @param status 迁移状态
     * @param message 迁移信息
     */
    public void insertLog(String tableName, Object object, String status, String message) {
        try {
            newDatabases.insertLog(tableName, JSON.toJSONString(object), status, message);
        }catch(Exception e) {
            log.error("插入日志失败:" + e.getMessage());
        }
    }

    /**
     * 迁移活动
     */
    public void migrationActivity() {
        List<Map<String, Object>> activityList = oldDatabases.getActivity();
        HhrActivity hhrActivity = null;
        log.info(JSON.toJSONString(activityList));
        List<String> list = new ArrayList<>();
        for(Map<String, Object> activity : activityList) {
            try{
                hhrActivity = new HhrActivity();
                hhrActivity.setId(getString(activity.get("id")));
                hhrActivity.setTitle(getString(activity.get("title")));
                hhrActivity.setDesc(getString(activity.get("activityDesc")));
                hhrActivity.setIntegral(Integer.valueOf(getString(activity.get("integral"))));
                hhrActivity.setImageUrl(getString(activity.get("imageUrl")));
                hhrActivity.setActivityType(getString(activity.get("activity_type")));
                hhrActivity.setSubclass(getString(activity.get("subclass")));
                hhrActivity.setRange(getString(activity.get("act_range")));
                hhrActivity.setStatus(getString(activity.get("status")));
                hhrActivity.setSort(activity.get("sort") != null ? Integer.valueOf(getString(activity.get("sort"))) : null);
                hhrActivity.setCreateTime(getDate(activity.get("createDate")));
                hhrActivity.setCreator(getString(activity.get("name")));
                hhrActivity.setDelFlag(activity.get("del_flag") != null ? Integer.valueOf(getString(activity.get("del_flag"))) : 0);
                try{
                    Integer insert = newDatabases.insertActivity(hhrActivity);
                    if (insert < 0) {
                        list.add(activity.get("id").toString());
                    }
                }catch(Exception e) {
                    if(e instanceof DuplicateKeyException){
                        activityMapper.updateById(hhrActivity);
                    }else{
                        throw e;
                    }
                }
            }catch(Exception e) {
                list.add(activity.get("id").toString());
                log.error(e.getMessage());
                this.insertLog("hhr_activity", hhrActivity, "error", e.getMessage());
            }
        }
        insertResult(activityList.size(), "hhr_activity", list);
    }

    /**
     * 迁移活动参与记录
     */
    public void migrationActivityRecord() {

        // 查询出所有记录
        List<Map<String, Object>> activityRecord = oldDatabases.getActivityRecord();
        HhrActivityRecord hhrActivityRecord = null;
        Map<String, Object> count = null;

        List<String> list = new ArrayList<>();

        for(Map<String, Object> map: activityRecord) {
            try{
                hhrActivityRecord = new HhrActivityRecord();
                // 判断是否有重复记录， 根据id  账号   活动id
                Integer id = Integer.valueOf(getString(map.get("id")));
                Integer activityId = Integer.valueOf(getString(map.get("activityId")));
                String account = getString(map.get("account"));
                count = oldDatabases.getActivityRecordCount(id, activityId, account);

                if (Integer.valueOf(getString(count.get("count"))) > 0) {
                    hhrActivityRecord.setIsRepeal(1);
                }else{
                    hhrActivityRecord.setIsRepeal(0);
                }

                hhrActivityRecord.setId(getString(map.get("id")));
                hhrActivityRecord.setActivityId(getString(map.get("activityId")));
                hhrActivityRecord.setCreateId(getString(map.get("create_id")));
                hhrActivityRecord.setCreator(getString(map.get("creator")));
                hhrActivityRecord.setCreateTime(getDate(map.get("createDate")));
                hhrActivityRecord.setImageUrl(getString(map.get("imageUrl_old")));
                hhrActivityRecord.setMessage(getString(map.get("messageInfo")));
                hhrActivityRecord.setRemark(getString(map.get("opinions")));
                hhrActivityRecord.setStatus(getString(map.get("state")));
                hhrActivityRecord.setUpdateTime(getDate(map.get("update_date")));
                hhrActivityRecord.setRecordIntegral(new BigDecimal(getString(map.get("Integral"))).intValue());
                try{
                    Integer insert = newDatabases.insertActivityRecord(hhrActivityRecord);
                    if (insert < 1) {
                        list.add(hhrActivityRecord.getId());
                    }
                }catch(Exception e) {
                    if (e instanceof DuplicateKeyException) {
                        activityRecordMapper.updateById(hhrActivityRecord);
                    }
                    else{
                        throw e;
                    }
                }
            }catch(Exception e) {
                list.add(map.get("id").toString());
                log.error(e.getMessage());
                this.insertLog("hhr_activity_record", hhrActivityRecord, "error", e.getMessage());
            }
        }
        insertResult(activityRecord.size(), "hhr_activity_record", list);
    }

    public Date getDate(Object object)  {
        if (object == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        try {
            date = sdf.parse((String)getString(object));
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    public String getString(Object object) {
        return object != null ? object.toString() : "";
    }

    /**
     * 插入迁移结果
     * @param total  迁移总数
     * @param tableName  表明
     * @param ids   插入错误id
     */
    public void insertResult(Integer total, String tableName, List<String> ids) {
        this.insertLog(tableName, ids , "result",
                "total:" + total + ", " + tableName +" fail num: " + ids.size());
        log.info("----------------------------------------------------");
        log.info(tableName + "插入失败个数：" + ids.size());
        log.info(JSON.toJSONString(ids));
        log.info("----------------------------------------------------");
    }
}
