package com.fs.company.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.baidu.dev2.thirdparty.jackson.databind.ObjectMapper;
import com.fs.common.annotation.Log;
import com.fs.common.constant.UserConstants;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.core.domain.model.LoginUser;
import com.fs.common.core.page.TableDataInfo;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.enums.BusinessType;
import com.fs.common.utils.PatternUtils;
import com.fs.common.utils.SecurityUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.company.domain.*;
import com.fs.company.param.CompanyUserAreaParam;
import com.fs.company.param.CompanyUserCodeParam;
import com.fs.company.param.CompanyUserQwParam;
import com.fs.company.service.*;
import com.fs.company.vo.BatchUserRolesVO;
import com.fs.company.vo.CompanyUserImportVO;
import com.fs.company.vo.CompanyUserQwListVO;
import com.fs.company.vo.CompanyUserVO;
import com.fs.course.config.CourseConfig;
import com.fs.framework.web.service.TokenService;
import com.fs.his.utils.qrcode.QRCodeUtils;
import com.fs.his.vo.OptionsVO;
import com.fs.hisStore.vo.FsStoreProductExportVO;
import com.fs.im.config.IMConfig;
import com.fs.im.dto.OpenImResponseDTO;
import com.fs.im.service.OpenIMService;
import com.fs.qw.domain.QwCompany;
import com.fs.qw.service.IQwCompanyService;
import com.fs.qw.service.IQwUserService;
import com.fs.qw.vo.CompanyUserQwVO;
import com.fs.qw.vo.QwUserVO;
import com.fs.system.service.ISysConfigService;
import com.fs.utils.DomainUtil;
import com.fs.utils.QwStatusEnum;
import com.fs.voice.utils.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;


/**
 * 用户信息
 */
@RestController
@RequestMapping("/company/CompanyUserAll")
public class CompanyUserAllController extends BaseController {

    @Autowired
    private ICompanyRoleService roleService;

    @Autowired
    private ICompanyPostService postService;

    @Autowired
    private ICompanyUserService companyUserService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private ICompanyUserDelayTimeService companyUserDelayTimeService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private OpenIMService openIMService;

    @Autowired
    IQwCompanyService iQwCompanyService;

    @Autowired
    private IQwUserService qwUserService;

    @Autowired
    private TokenService tokenService;

    private static final String appLink = "https://jump.ylrztop.com/jumpapp/pages/index/index?link=";


    @GetMapping("/getList")
    public TableDataInfo getList(CompanyUser user)
    {
        startPage();
        List<CompanyUser> list = companyUserService.selectCompanyUserList(user);
        return getDataTable(list);
    }
    @GetMapping("/qwList")
    public TableDataInfo qwList(CompanyUserQwParam user) {
        List<CompanyUserQwListVO> list = companyUserService.selectCompanyUserQwListVO(user);
        if (!list.isEmpty()){
            String json = configService.selectConfigByKey("course.config");
            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
            Long sendDelayTime = config.getSendDelayTime();
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            for (CompanyUserQwListVO companyUserQwListVO : list) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    CompanyUserDelayTime companyUserDelayTime = companyUserDelayTimeService.selectCompanyUserDelayTimeByCompanyUser(companyUserQwListVO.getCompanyId(), companyUserQwListVO.getUserId());
                    if (ObjectUtil.isEmpty(companyUserDelayTime)) {
                        companyUserQwListVO.setSendDelayTime(sendDelayTime);
                    } else {
                        companyUserQwListVO.setSendDelayTime(companyUserDelayTime.getSendDelayTime());
                    }
                    //是否绑定
                    if(QwStatusEnum.BOUND.getCode() == companyUserQwListVO.getQwStatus()){
                        if(!companyUserQwListVO.getQwUserId().isEmpty()){
                            Long[] ids = Arrays.stream(companyUserQwListVO.getQwUserId().split(","))
                                    .map(Long::parseLong)
                                    .toArray(Long[]::new);
                            List<QwUserVO> qwUserVOS = qwUserService.selectQwUserVOByIds(ids);
                            companyUserQwListVO.setQwUsers(qwUserVOS);
                        }
                    }
                });
                futures.add(future);
            }
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        }
        return getDataTable(list);
    }

    @Log(title = "用户管理导出", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('company:user:export')")
    @GetMapping("/export")
    public AjaxResult export(CompanyUser user)
    {
        List<CompanyUser> list = companyUserService.selectCompanyUserList(user);
        ExcelUtil<CompanyUser> util = new ExcelUtil<CompanyUser>(CompanyUser.class);
        return util.exportExcel(list, "用户数据");
    }


    @Log(title = "销售信息导入", businessType = BusinessType.IMPORT,isStoreLog = true,logParam = {"销售","信息导入"})
    @PreAuthorize("@ss.hasPermi('company:user:import')")
    @PostMapping("/importCompanyUser")
    public AjaxResult importData(@RequestParam("file") MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
        List<CompanyUserImportVO> list = util.importExcel(file.getInputStream());
        String message = companyUserService.importCompanyUser(list, updateSupport);
        return AjaxResult.success(message);
    }


    @GetMapping("/importTemplate")
    public AjaxResult importTemplate()
    {
        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
        return util.importTemplateExcel("销售数据");
    }



    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('company:user:query')")
    @GetMapping(value = { "/", "/{userId}" })
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
    {
        AjaxResult ajax = AjaxResult.success();
        CompanyRole companyRoleMap=new CompanyRole();

        CompanyUser userById = companyUserService.selectCompanyUserById(userId);
        companyRoleMap.setCompanyId(userById.getCompanyId());
        List<CompanyRole> roles = roleService.selectCompanyRoleList(companyRoleMap);

        ajax.put("roles", CompanyUser.isAdmin(userById.getUserType()) ? roles : roles.stream().filter(r -> r.getRoleKey()!="admin").collect(Collectors.toList()));

        CompanyPost postMap=new CompanyPost();
        postMap.setCompanyId(userById.getCompanyId());
        ajax.put("posts", postService.selectCompanyPostList(postMap));
        if (StringUtils.isNotNull(userId))
        {
            CompanyUser companyUser=companyUserService.selectCompanyUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, companyUser);
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            ajax.put("roleIds", roleService.selectRoleListByUserId(userId));


        }
        return ajax;
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('company:user:query')")
    @GetMapping("/addInfo/{companyId}")
    public AjaxResult addInfo(@PathVariable(value = "companyId", required = true) Long companyId)
    {
        AjaxResult ajax = AjaxResult.success();

        CompanyRole companyRoleMap=new CompanyRole();
        companyRoleMap.setCompanyId(companyId);
        List<CompanyRole> roles = roleService.selectCompanyRoleList(companyRoleMap);

        ajax.put("roles", CompanyUser.isAdmin("01") ? roles : roles.stream().filter(r -> r.getRoleKey()!="admin").collect(Collectors.toList()));

        CompanyPost postMap=new CompanyPost();
        postMap.setCompanyId(companyId);
        ajax.put("posts", postService.selectCompanyPostList(postMap));

        return ajax;
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@ss.hasPermi('company:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody CompanyUser user)
    {
        if (!PatternUtils.checkPassword(user.getPassword())) {
            return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
        }

        //判断用户数量是否已达到上线

        Integer count=companyUserService.selectCompanyUserCountByCompanyId(user.getCompanyId());
        Company company=companyService.selectCompanyById(user.getCompanyId());

        if(count>company.getLimitUserCount()){
            return AjaxResult.error("用户数量已达到上限");
        }
        user.setCompanyId(user.getCompanyId());
        if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(user.getUserName()))))
        {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        }
        if (!StringUtil.strIsNullOrEmpty(user.getDomain())){
            user.setDomain(user.getDomain().replaceAll("^[\\s\\u2005]+", ""));
        }

        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setCreateTime(new Date());
        user.setUserType("01");//一般用户
        user.setIsAudit(1);
        return toAjax(companyUserService.insertUser(user));
    }

    /**
     * 生成创建销售的二维码
     */

    @PreAuthorize("@ss.hasPermi('company:user:addCodeUrl')")
    @Log(title = "生成创建销售的二维码", businessType = BusinessType.INSERT)
    @PostMapping("/addCodeUrl")
    public R addCodeUrl( @RequestBody CompanyUserCodeParam user) throws Exception {

        QwCompany qwCompany = iQwCompanyService.getQwCompanyByRedis(user.getCorpId());
        if (qwCompany == null || qwCompany.getCorpId() == null){
            return R.error("企业信息不存在");
        }

        //部门
        Long deptId = user.getDeptId();

        //角色组
        Long[] roleIds = user.getRoleIds();

        //区域
        String addressId = user.getAddressId();


        Map<String, Object> stateMap = new HashMap<>();
        stateMap.put("companyId", user.getCompanyId());
        stateMap.put("deptId", deptId);
        stateMap.put("roleIds", roleIds); // 数组可以直接存放
        stateMap.put("addressId", addressId);

        // 使用JSON库将Map转换为字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String status = objectMapper.writeValueAsString(stateMap);

        // 如果要将status作为URL参数传递，记得进行URL编码！
        String encodedStatus = URLEncoder.encode(status, StandardCharsets.UTF_8.toString());

        String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+user.getCorpId()+"&redirect_uri=" +
                "http://"+qwCompany.getRealmNameUrl()+"/loginqw/pages/companyLogin/index?corpId="+user.getCorpId() +
                "&response_type=code&scope=snsapi_base&state="+encodedStatus+"&agentid="+qwCompany.getServerAgentId()+"#wechat_redirect";

        R andUpload = QRCodeUtils.createAndUpload(url);
        return  R.ok().put("data",andUpload);
    }
    /**
     * 修改用户
     */
    @PreAuthorize("@ss.hasPermi('company:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody CompanyUser user)
    {

        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        user.setUpdateBy(SecurityUtils.getUsername());

        if (!StringUtil.strIsNullOrEmpty(user.getDomain())){
            user.setDomain(user.getDomain().replaceAll("^[\\s\\u2005]+", ""));
        }

        CompanyUser companyUser = companyUserService.selectCompanyUserById(user.getUserId());

        if (!companyUser.getUserName().equals(user.getUserName())){
            if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(user.getUserName()))))
            {
                return AjaxResult.error("修改员工账号'" + user.getUserName() + "'失败，员工账号已存在");
            }
        }


        logger.info("用户管理-修改用户:"+user.getUserName()+"/登陆人:"+loginUser.getUser().getUserId()+"/名字："+loginUser.getUser().getUserName()+"/修改的角色："+ Arrays.toString(user.getRoleIds()));
        return toAjax(companyUserService.updateUser(user));
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@ss.hasPermi('company:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds)
    {
        for (Long userId : userIds) {
            CompanyUser companyUser = companyUserService.selectCompanyUserById(userId);
            CompanyUserDelayTime companyUserDelayTime = companyUserDelayTimeService.selectCompanyUserDelayTimeByCompanyUser(companyUser.getCompanyId(),userId);
            if (ObjectUtil.isNotEmpty(companyUserDelayTime)){
                companyUserDelayTimeService.deleteCompanyUserDelayTimeById(companyUserDelayTime.getId());
            }
        }
        return toAjax(companyUserService.deleteCompanyUserByIds(userIds));
    }

    /**
     * 重置密码
     */
    @PreAuthorize("@ss.hasPermi('company:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public AjaxResult resetPwd(@RequestBody CompanyUser user)
    {
        if (!PatternUtils.checkPassword(user.getPassword())) {
            return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
        }

        String newPassword = SecurityUtils.encryptPassword(user.getPassword());
        int i = companyUserService.resetUserPwdByUserId(user.getUserId(), newPassword);

        if (i > 0) {
            // 更新缓存用户密码
            redisCache.deleteObject("newCompanyUser:" + user.getCompanyId() + ":" + user.getUserName());
        }

        return toAjax(i);
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('company:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody CompanyUser user)
    {
        //管理员的状态不能修改
        CompanyUser companyUser=companyUserService.selectCompanyUserById(user.getUserId());
        if(companyUser.isAdmin()){
            return AjaxResult.error("不能修改管理员状态");
        }
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(companyUserService.updateCompanyUser(user));
    }




    /**
     * 获取区域
     */
    @GetMapping("/getCitysAreaList")
    public R getCitysAreaList(){
        return R.ok().put("data",companyUserService.getCitysAreaList());
    }

    /**
     * 批量修改 销售的所属区域(临时的)
     */
    @PreAuthorize("@ss.hasPermi('company:user:updateCompanyUserAreaList')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/updateCompanyUserAreaList")
    public R updateCompanyUserAreaList(@RequestBody CompanyUserAreaParam param)
    {
        return companyUserService.updateCompanyUserAreaList(param);
    }


    @GetMapping("/generateSubDomain")
    public R generateSubDomain(CompanyUser user){
        //获取后台配置
        String json= configService.selectConfigByKey("course.config");
        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
        // 生成二级域名
        String subDomain = "http://" + DomainUtil.generateSubDomain(config.getCourseDomainName(), 6, String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
        return  R.ok().put("data",subDomain);
    }

    @PreAuthorize("@ss.hasPermi('company:user:setRegister')")
    @Log(title = "设置是否需要单独注册会员", businessType = BusinessType.UPDATE)
    @PutMapping("/setRegister")
    public AjaxResult setIsRegisterMember(@RequestParam Boolean status, @RequestBody List<Long> userIds) {
        Boolean r = companyUserService.setIsRegisterMember(status, userIds);
        if (r) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error("操作失败");
        }
    }

    @PreAuthorize("@ss.hasPermi('company:user:allowedAllRegister')")
    @Log(title = "是否允许所有方式注册会员", businessType = BusinessType.UPDATE)
    @PutMapping("/allowedAllRegister")
    public AjaxResult isAllowedAllRegister(@RequestParam Boolean status, @RequestBody List<Long> userIds) {
        Boolean r = companyUserService.isAllowedAllRegister(status, userIds);
        if (r) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error("操作失败");
        }
    }
    @PostMapping("/common/uploadOSS")
    public R uploadOSS(@RequestParam("file") MultipartFile file,
                       @RequestParam("userId") String userId) throws Exception {
        String url = companyUserService.uploadQrCode(file, userId);
        return R.ok().put("url", url);
    }


    /**
     * 销售解除绑定医生
     */
    @PreAuthorize("@ss.hasPermi('qw:companyUser:unBindDoctorId')")
    @Log(title = "销售解除绑定医生", businessType = BusinessType.UPDATE)
    @GetMapping("/unBindDoctorId/{userId}")
    public R bindDoctorId(@PathVariable("userId") Long userId){
        return companyUserService.unBindDoctor(userId);
    }

    /**
     * 销售绑定医生
     */
    @PreAuthorize("@ss.hasPermi('qw:companyUser:bindDoctorId')")
    @Log(title = "销售绑定医生", businessType = BusinessType.UPDATE)
    @PostMapping("/bindDoctorId")
    public R unBindDoctorId(@RequestBody CompanyUser companyUser){
        return companyUserService.bindDoctor(companyUser);
    }

    /**
     * 批量修改角色
     * @param batchUserRolesVO
     */
    @PreAuthorize("@ss.hasPermi('company:user:edit')")
    @Log(title = "批量修改角色", businessType = BusinessType.UPDATE)
    @PostMapping("/updateBatchUserRoles")
    public R updateBatchUserRoles(@RequestBody BatchUserRolesVO batchUserRolesVO){
        Assert.notEmpty(batchUserRolesVO.getRoleIds(), "角色不能为空");
        Assert.notEmpty(batchUserRolesVO.getUserIds(), "用户不能为空");
        return companyUserService.updateBatchUserRoles(batchUserRolesVO);
    }


    @ApiOperation("校验客服是否注册新的im")
    @PostMapping("/accountCheck")
    public R accountCheck(@RequestBody Map<String, String> userIdMap){
        //获取管理员token
        String userId = userIdMap.get("userId");
        String adminToken = openIMService.getAdminToken();
        JSONObject requestBody = new JSONObject();
        // 解析响应
        if (StringUtils.isNotEmpty(adminToken)) {
            //查询用户是否注册
            ArrayList<String> userIds = new ArrayList<>();
            requestBody = new JSONObject();
            userIds.add(userId);
            requestBody.put("checkUserIDs", userIds);
            String body = HttpRequest.post(IMConfig.URL+"/user/account_check")
                    .header("operationID", String.valueOf(System.currentTimeMillis()))
                    .header("token", adminToken)
                    .body(requestBody.toString())
                    .execute()
                    .body();
            JSONObject jsonObject = new JSONObject(body);
            JSONArray results = jsonObject.getJSONObject("data").getJSONArray("results");
            if (results != null && results.length() > 0) {
                JSONObject resultObj = results.getJSONObject(0);
                int accountStatus = resultObj.getInt("accountStatus");
                //未注册自动注册
                if (accountStatus==0){
                    String s = userId.replaceFirst("^C", "");
                    CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(s));
                    if (null==companyUser){
                        return R.error("用户不存在");
                    }
                    ArrayList<Object> users = new ArrayList<>();
                    HashMap<String, String> map = new HashMap<>();
                    map.put("userID",userId);
                    map.put("nickname",companyUser.getNickName());
                    map.put("faceURL",companyUser.getAvatar());
                    users.add(map);
                    requestBody = new JSONObject();
                    //userIds.add(userId);
                    requestBody.put("users", users);
                    String registerBody = HttpRequest.post(IMConfig.URL+"/user/user_register")
                            .header("operationID", String.valueOf(System.currentTimeMillis()))
                            .header("token", adminToken).body(requestBody.toString()).execute().body();
                }
            } else {
                return R.error("返回结果为空");
            }
           /* HashMap<String, String> tokenMap = new HashMap<>();
            tokenMap.put("platformID","1");
            tokenMap.put("userID",userId);*/
            requestBody = new JSONObject();
            requestBody.put("platformID",5);
            requestBody.put("userID",userId);
            String body1 = HttpRequest.post(IMConfig.URL+"/auth/get_user_token")
                    .header("operationID", String.valueOf(System.currentTimeMillis()))
                    .header("token", adminToken)
                    .body(requestBody.toString()).execute().body();
            JSONObject userJson = new JSONObject(body1);
            JSONObject userData = userJson.getJSONObject("data");
            String userToken = userData.getString("token");
            return R.ok().put("token", userToken);
        } else {
            return R.error("获取管理员token失败");
        }
    }
    @ApiOperation("添加好友")
    @PostMapping("/importFriend")
    public R importFriend(@RequestBody HashMap<String,Object> map){
        String ownerUserID = (String) map.get("ownerUserID");
        List<String> friendUserIDs = (List<String>)map.get("friendUserIDs");
        OpenImResponseDTO openImResponseDTO = openIMService.importFriend(ownerUserID, friendUserIDs);
        return R.ok().put("data",openImResponseDTO);
    }
}
