package com.blueland.render.rest;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blueland.annotation.ApiVersion;
import com.blueland.annotation.Log;
import com.blueland.constant.RedisConstant;
import com.blueland.core.util.RedisUtils;
import com.blueland.bo.*;

import com.blueland.core.util.StringUtil;
import com.blueland.core.util.UserUtils;
import com.blueland.dao.OrgDao;
import com.blueland.enums.Version;
import com.blueland.model.TUcOrg;
import com.blueland.result.R;
import com.blueland.service.ITucOrgService;
import com.blueland.service.ITucStaffService;
import com.blueland.service.SysRedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.blueland.constant.Constant;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;

import static com.blueland.constant.CommonConstant.*;


@Slf4j
@RestController
@RequestMapping(value = "/org")
public class OrgRest {
    @Autowired
    private ITucOrgService iTucOrgService;
    @Autowired
    private ITucStaffService iTucStaffService;

    @Autowired
    private SysRedisService sysRedisService;

    @Resource
    OrgDao orgDao;

    /**
     * 搜索对象
     **/
    @ApiOperation(value = "分页查询组织", notes = "分页查询组织")
    @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Page<Org>> list(Org org) {
        Page<Org> page = iTucOrgService.findPage(org);
        return R.ok(page);
    }

    /**
     * 搜索对象
     **/
    @ApiOperation(value = "查询组织", notes = "查询组织")
    @RequestMapping(value = "findlist", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<List<Org>> findlist(Org org) {
        org.setAppId(UserUtils.getTenantId());
        List<Org> list = iTucOrgService.findList(org);
        return R.ok(list);
    }

    /**
     * 查看对象
     **/
    @ApiOperation(value = "根据orgId查询组织", notes = "根据orgId查询组织")
    @RequestMapping(value = "/{orgId}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Org> view(@PathVariable String orgId) {
        Org org = iTucOrgService.getByOgId(orgId);
        return R.ok(org);
    }


    /**
     * 查看对象（支持多条件查询）
     **/
    @ApiOperation(value = "查看组织（支持多条件查询）", notes = "查看对象（支持多条件查询）")
    @RequestMapping(value = "get", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Org> get(Org model) {
        Org tucOrgEntity = BeanUtil.copyProperties(model, Org.class);
        Field[] field = model.getClass().getDeclaredFields();
        Map<?, ?> map = BeanUtil.beanToMap(model);
        boolean result = false;
        for (int i = 0; i < field.length; i++) {
            String name = field[i].getName();
            if (map.get(name) != null) {
                result = true;
                break;
            }
        }
        if (result) {
            tucOrgEntity = iTucOrgService.get(model);
        }
        return R.ok(tucOrgEntity);
    }


    /**
     * 新增对象
     **/
    @ApiOperation(value = "新增组织", notes = "新增组织")
    @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Org> save(@RequestBody Org model) {
        String deptcode = model.getDeptId();
        if (deptcode == null) {
            throw new RuntimeException("没有部门编码!");
        }
        if (deptcode.startsWith("A01A01A08A05") || deptcode.startsWith("A01A01A15")) {
            if (deptcode.length() > 15) {
                deptcode = deptcode.substring(0, deptcode.length() - 3);
                Org parentOrg = new Org();
                parentOrg.setDeptId(deptcode);
                Org org = iTucOrgService.getByAppId(parentOrg);
                model.setOrgFullName(org.getOrgFullName());
            }
            model.setOrgWorkType(Constant.ORGWORKTYPE_SELL);
            iTucOrgService.syncDept2CRM(model);
        } else {
            model.setOrgWorkType("other");
        }
        List<TUcOrg> list = iTucOrgService.handleOrg(model);
        if (ObjectUtil.isNotEmpty(list)) {
            for (TUcOrg org : list) {
                orgDao.insert(org);
            }
            // 更新缓存
            sysRedisService.flushDept(list);
        }
        return R.ok(model, "成功");
    }

    /**
     * 批量新增对象
     **/
    @ApiOperation(value = "批量新增组织", notes = "批量新增组织")
    @RequestMapping(value = "/batch", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Boolean> batchSave(@RequestBody List<Org> model) {
        for (Org org : model) {
            List<TUcOrg> list = iTucOrgService.handleOrg(org);
            if (ObjectUtil.isNotEmpty(list)) {
                iTucOrgService.saveBatch(list);
                // 更新缓存
                sysRedisService.flushDept(list);
            }
        }
        return R.ok();
    }


    /**
     * 更新对象
     *
     * @return
     **/
    @ApiOperation(value = "更新组织", notes = "更新组织")
    @RequestMapping(value = "", method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Boolean> update(@RequestBody Org model) {
        String deptcode = model.getDeptId();
        if (ObjectUtil.isEmpty(deptcode)) {
            throw new RuntimeException("没有部门编码!");
        }
        TUcOrg org = BeanUtil.copyProperties(model, TUcOrg.class);
        QueryWrapper<TUcOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TUcOrg:: getDeptId, deptcode);
        orgDao.update(org, queryWrapper);
        // 更新部门名称
        UpdateDeptName(model);
        // 更新缓存
        sysRedisService.saveOrUpdateDept(model);
        // 判断部门id是否发生过变化
//        if (!Objects.equals(old.getDeptId(), model.getDeptId())) {
//            List<TUcOrg> list = iTucOrgService.handleOrg(model);
//            if (ObjectUtil.isNotEmpty(list)) {
//                for (TUcOrg org : list) {
//                    if (iTucOrgService.countOrgById(org.getOrgId(), org.getAppId()) > 0) {
//                        // 更新
//                        QueryWrapper<TUcOrg> queryWrapper = new QueryWrapper<>();
//                        queryWrapper.lambda().eq(TUcOrg:: getDeptId, deptcode);
//                        orgDao.update(org, queryWrapper);
//                        // 更新部门名称
//                        UpdateDeptName(model);
//                    } else {
//                        // 新增
//                        orgDao.insert(org);
//                    }
//                }
//                // 更新缓存
//                sysRedisService.flushDept(list);
//            }
//        } else {
//            TUcOrg org1 = BeanUtil.copyProperties(model, TUcOrg.class);
//            QueryWrapper<TUcOrg> queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().eq(TUcOrg:: getDeptId, deptcode);
//            orgDao.update(org1, queryWrapper);
//            // 更新部门名称
//            UpdateDeptName(model);
//            // 更新缓存
//            sysRedisService.saveOrUpdateDept(model);
//        }
        return R.ok(true,"成功");
    }

    private void UpdateDeptName(Org model) {
        String deptcode = model.getDeptId();
        String parentdeptcode = deptcode.substring(0, deptcode.length() - 3);
        Org parentOrg = new Org();
        parentOrg.setOrgSpells(model.getOrgSpells());
        parentOrg.setDeptId(parentdeptcode);
        Org org = iTucOrgService.getByAppId(parentOrg);
        if (org != null) {
            model.setOrgFullName(org.getOrgFullName());
        }
        if (ObjectUtil.isNotEmpty(model.getOrgName())) {
            iTucStaffService.updateDeptnameByDeptid(model.getOrgName(), deptcode);
        }
    }

    /**
     * 删除对象
     *
     * @return
     **/
    @ApiOperation(value = "根据orgId删除组织", notes = "根据orgId删除组织")
    @RequestMapping(value = "/{orgId}", method = RequestMethod.DELETE, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<Boolean> delete(@PathVariable String orgId) {
        QueryWrapper<TUcOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TUcOrg:: getDeptId, orgId);
        orgDao.delete(queryWrapper);
        // 删除缓存
        sysRedisService.flushDept();
        return R.ok();
    }

    /**
     * 子组织列表-内部抵用
     **/
    @ApiOperation(value = "获取子组织列表", notes = "获取子组织列表")
    @RequestMapping(value = "/suborgs", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Page<Org> getSubOrgs(Org org) {
        if (StringUtils.isEmpty(org.getOrgType())) {
            throw new RuntimeException("非法参数");
        }
        org.setSortColumns("org_sort");
        Page<Org> pageInfo = iTucOrgService.getOrgSubs(org);
        return pageInfo;
    }

    /**
     * 组织列表-内部调用
     **/
    @ApiOperation(value = "分页获取组织列表", notes = "分页获取组织列表")
    @RequestMapping(value = "listorg", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Page<Org> listOrg(Org org) {
        if (StringUtils.isEmpty(org.getOrgType())) {
            throw new RuntimeException("非法参数");
        }
        return iTucOrgService.getOrgPage(org);
    }

    @ApiOperation(value = "不分页获取组织列表", notes = "不分页获取组织列表")
    @PostMapping("/listorgNew")
    public R<List<Org>> selectOrgList(@RequestBody Org org) {
        List<Org> list = iTucOrgService.getListNoPage(org);
        return R.ok(list);
    }


    /**
     * 通过类型将组织转换树
     */
    @ApiOperation(value = "通过orgType获取组织树", notes = "通过orgType获取组织树")
    @RequestMapping(value = "tree", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public List<Map<String, Object>> getOrgTree(Org org) {
        if (StringUtils.isEmpty(org.getOrgType())) {
            throw new RuntimeException("非法参数");
        }
        org.setSortColumns("org_sort");
        org.setOrgStatus("QY");

        String oldOrgId = org.getOrgId();
        org.setOrgId("");
        List<Org> orgList = iTucOrgService.getListNoPage(org);
        org.setOrgId(oldOrgId);

        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        if (orgList.size() > 0) {
            resultList = iTucOrgService.handleTreeData(org,
                    orgList);
        }

        return resultList;
    }


    /**
     * 根据type和id直接出树
     */
    @ApiOperation(value = "根据type和id查询下一节点数据", notes = "根据type和id查询下一节点数据")
    @RequestMapping(value = "get/{orgType}/{type}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<List<TreeEntity>> getOrgTreeGYGS(@PathVariable String orgType,
                                              @PathVariable String type,
                                              @RequestParam(required = false) String id,
                                              @RequestParam(required = false) String orgId,
                                              @RequestParam(required = false) String staffName) {
        List<TreeEntity> treeEntitieList = iTucOrgService.getTree(orgType, type, id, orgId, staffName);
        return R.ok(treeEntitieList);
    }


    /**
     * 功能描述:搜索组织（选人组件用，勿动）
     *
     * @param: [orgName]
     * @return: com.blueland.framework.model.ServiceResponse<java.util.List < com.blueland.model.TreeEntity>>
     * @auther: lg 540923947@qq.com
     * @date: 2019/5/9 11:44
     */
    @ApiOperation(value = "搜索组织", notes = "搜索组织")
    @RequestMapping(value = "searchOrg", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<List<TreeEntity>> searchOrg(String orgName, String companyId) {
        Org org = new Org();
        org.setOrgStatus("QY");
        org.setSortColumns("org_sort");
        org.setQueryOrg(orgName);
        org.setCompanyId(companyId);
        List<TreeEntity> list = this.iTucOrgService.searchOrg(org);
        return R.ok(list);
    }

    /**
     * 功能描述:搜索组织（选人组件用，勿动）
     *
     * @param: [orgName]
     * @return: com.blueland.framework.model.ServiceResponse<java.util.List < com.blueland.model.TreeEntity>>
     * @auther: lg 540923947@qq.com
     * @date: 2019/5/9 11:44
     */
    @ApiOperation(value = "搜索组织和用户", notes = "搜索组织和用户")
    @RequestMapping(value = "search/organduser", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<List<TreeEntity>> searchOrgAndUser(String inputName, String companyId) {
        Org org = new Org();
        org.setOrgStatus("QY");
        org.setSortColumns("org_sort");
        org.setQueryOrg(inputName);
        org.setCompanyId(companyId);
        List<TreeEntity> list = this.iTucOrgService.searchOrg(org);
        TucStaffEntity tucStaffEntity = new TucStaffEntity();
        tucStaffEntity.setStaffStatus("QY");
        tucStaffEntity.setSortColumns("staff_sort");
        tucStaffEntity.setQueryStaff(inputName);
        tucStaffEntity.setCompanyId(companyId);
        List<TreeEntity> userList = iTucStaffService.searchUser(tucStaffEntity);
        list.addAll(userList);
        return R.ok(list);
    }

    @ApiOperation(value = "更新redis部门数据", notes = "更新redis")
    @GetMapping("/updateDept")
    public R updateDeptData() {
        sysRedisService.flushDept();
        return R.ok();
    }

    @ApiOperation(value = "缓存部门数据", notes = "初始化redis中的部门信息")
    @GetMapping("/initDept")
    public R initDept() {
        sysRedisService.initDept();
        return R.ok();
    }

    @ApiVersion(groups = Version.SIX)
    @ApiOperation("获取顶级组织id")
    @GetMapping("/getTopOrgId")
    public R<String> getTopOrgId() {
        return R.ok(iTucOrgService.getTopOrgId());
    }

    @ApiVersion(groups = Version.SIX)
    @ApiOperation("根据部门code获取顶级销售组织id")
    @GetMapping("/getSellOrgId/{deptCode}")
    public R<String> getSellOrgId(@PathVariable("deptCode") String deptCode) {
        return R.ok(iTucOrgService.getSellOrgId(deptCode));
    }

}
