package com.fs.qw.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.fs.common.core.domain.R;
import com.fs.common.core.domain.model.LoginUser;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.company.service.ICompanyService;
import com.fs.course.config.CourseConfig;
import com.fs.framework.web.service.TokenService;
import com.fs.his.vo.OptionsVO;
import com.fs.qw.domain.QwContactWay;
import com.fs.qw.domain.QwUser;
import com.fs.qw.param.*;
import com.fs.qw.service.IQwContactWayService;
import com.fs.qw.service.IQwExternalContactInfoService;
import com.fs.qw.service.IQwGroupChatUserService;
import com.fs.qw.service.IQwTagService;
import com.fs.qw.service.IQwUserService;
import com.fs.course.service.IFsUserCompanyBindService;
import com.fs.course.vo.UserWatchLogListVo;
import com.fs.qw.vo.QwExternalContactUnionIdExportVO;
import com.fs.qw.vo.QwExternalContactVO;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fs.common.annotation.Log;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.enums.BusinessType;
import com.fs.qw.domain.QwExternalContact;
import com.fs.qw.service.IQwExternalContactService;
import com.fs.qw.service.IQwUserServiceAsyncHelper;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.common.core.page.TableDataInfo;
import com.fs.system.service.ISysConfigService;

/**
 * 企业微信客户Controller
 *
 * @author fs
 * @date 2025-06-13
 */
@RestController
@RequestMapping("/qw/externalContact")
public class QwExternalContactController extends BaseController
{
    private IQwExternalContactService qwExternalContactService;
    private IQwTagService iQwTagService;

    @Autowired
    private IQwExternalContactInfoService qwExternalContactInfoService;

    @Autowired
    private IQwContactWayService qwContactWayService;

    @Autowired
    private IQwGroupChatUserService qwGroupChatUserService;

    @Autowired
    private IFsUserCompanyBindService fsUserCompanyBindService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private IQwUserService qwUserService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IQwUserServiceAsyncHelper qwUserServiceAsyncHelper;

    QwExternalContactController(IQwExternalContactService qwExternalContactService,IQwTagService iQwTagService){
        this.qwExternalContactService=qwExternalContactService;
        this.iQwTagService=iQwTagService;
    }


    /**
     * 查询企业微信客户列表
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:list')")
    @GetMapping("/list")
    public TableDataInfo list(QwExternalContactParam qwExternalContact)
    {
        boolean hasBasicQuery = qwExternalContact.getFsUserId() != null
                || qwExternalContact.getExtId() != null
                || qwExternalContact.getId() != null
                || StringUtils.isNotEmpty(qwExternalContact.getExternalUserId());
        boolean hasAddSalesQuery = qwExternalContact.getAddSalesCount() != null
                && hasAddSalesCountScope(qwExternalContact);
        if (!hasBasicQuery && !hasAddSalesQuery) {
            return getDataTable(new ArrayList<>());
        }
        if (qwExternalContact.getAddSalesCount() != null && !hasAddSalesCountScope(qwExternalContact)) {
            return getDataTable(new ArrayList<>());
        }

        QwContactWay qwContactWay = new QwContactWay();
        if (qwExternalContact.getCompanyId() != null) {
            qwContactWay.setCompanyId(qwExternalContact.getCompanyId());
        }
        List<QwContactWay> wayList = qwContactWayService.selectQwContactWayList(qwContactWay);

        startPage();
        if (StringUtils.isNotEmpty(qwExternalContact.getStatuses())) {
            String[] split = qwExternalContact.getStatuses().split(",");
            qwExternalContact.setStatusCondition(split);
        }
        List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getExternalUserId())) {
                List<String> chatNameList = qwGroupChatUserService.selectChatNameByUserId(item.getExternalUserId());
                item.setChatNames(chatNameList);
            }

            if (!Objects.equals(item.getTagIds(), "[]") && item.getTagIds() != null) {
                QwTagSearchParam param = new QwTagSearchParam();
                Gson gson = new Gson();
                List<String> tagIds = gson.fromJson(
                        item.getTagIds(),
                        new TypeToken<List<String>>() {
                        }.getType()
                );

                param.setTagIds(tagIds);

                item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
            }

            if (StringUtils.isNotEmpty(item.getState()) && !wayList.isEmpty()) {
                item.setState(item.getState() + "-" + getContactWayNameStream(item.getState(), wayList));
            }
        });
        if (StringUtils.isNotEmpty(qwExternalContact.getChatName())) {
            list = list.stream()
                    .filter(item -> item.getChatNames() != null && !item.getChatNames().isEmpty())
                    .collect(Collectors.toList());
        }

        return getDataTable(list);
    }

    /**
     * 添加销售数筛选 - 公司下拉
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:list')")
    @GetMapping("/companyOptions")
    public R companyOptions() {
        Long deptId = resolveDeptIdForCompanyScope();
        List<OptionsVO> list = companyService.selectAllCompanyList(deptId);
        return R.ok().put("data", list);
    }

    /**
     * 添加销售数筛选 - 销售下拉（企微昵称 qwUserName）
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:list')")
    @GetMapping("/salesOptions")
    public R salesOptions(@RequestParam(required = false) Long companyId) {
        if (companyId == null) {
            return R.ok().put("data", new ArrayList<>());
        }
        QwUser query = new QwUser();
        query.setCompanyId(companyId);
        List<Map<String, String>> options = qwUserService.selectQwUserList(query).stream()
                .map(QwUser::getQwUserName)
                .filter(StringUtils::isNotEmpty)
                .distinct()
                .sorted()
                .map(name -> {
                    Map<String, String> option = new HashMap<>(2);
                    option.put("dictLabel", name);
                    option.put("dictValue", name);
                    return option;
                })
                .collect(Collectors.toList());
        return R.ok().put("data", options);
    }

    private Long resolveDeptIdForCompanyScope() {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String json = configService.selectConfigByKey("course.config");
        CourseConfig courseConfig = JSONUtil.toBean(json, CourseConfig.class);
        if (!loginUser.isAdmin() && courseConfig.getDept() != null && courseConfig.getDept()) {
            return loginUser.getDeptId();
        }
        return null;
    }

    private boolean hasAddSalesCountScope(QwExternalContactParam param) {
        return param.getCompanyId() != null
                || StringUtils.isNotEmpty(param.getQwUserName());
    }

    public String getContactWayNameStream(String configStr, List<QwContactWay> wayList) {
        if (configStr == null || wayList == null || wayList.isEmpty()) {
            return null;
        }

        return wayList.stream()
                .filter(way -> way.getId() != null &&
                        way.getId().toString().equals(extractLastValue(configStr)))
                .map(QwContactWay::getName)
                .findFirst()
                .orElse(null);
    }

    private String extractLastValue(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }

        int lastColonIndex = input.lastIndexOf(":");
        if (lastColonIndex == -1) {
            return input;
        }

        return input.substring(lastColonIndex + 1);
    }

    /**
     * 重粉看课记录查询
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:list')")
    @GetMapping("/getWatchLogList")
    public TableDataInfo getWatchLogList(UserWatchLogParam param) {
        startPage();
        List<UserWatchLogListVo> list = fsUserCompanyBindService.getWatchLogList(param);
        return getDataTable(list);
    }

    /**
     * 重粉看课历史 - 综合信息查询（关联销售 + 课程进度）
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:list')")
    @GetMapping("/getRepeatCourseHistory")
    public AjaxResult getRepeatCourseHistory(@RequestParam Long fsUserId,
                                             @RequestParam(required = false) Long companyId) {
        return AjaxResult.success(fsUserCompanyBindService.getRepeatCourseHistory(fsUserId, companyId));
    }

    /**
     * 导出企业微信客户列表
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:export')")
    @Log(title = "企业微信客户", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(QwExternalContactParam qwExternalContact)
    {
        List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
        list.forEach(item->{

            if (!Objects.equals(item.getTagIds(), "[]") && item.getTagIds()!=null) {
                QwTagSearchParam param = new QwTagSearchParam();
                Gson gson = new Gson();
                List<String> tagIds = gson.fromJson(
                        item.getTagIds(),
                        new TypeToken<List<String>>() {
                        }.getType()
                );

                param.setTagIds(tagIds);

                item.setTagIdsName(iQwTagService.selectQwTagListByTagIds(param));
            }
        });
        ExcelUtil<QwExternalContactVO> util = new ExcelUtil<QwExternalContactVO>(QwExternalContactVO.class);
        return util.exportExcel(list, "企业微信客户数据");
    }

    /**
     * 导出企业微信客户unionId
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:export')")
    @Log(title = "企业微信客户unionId", businessType = BusinessType.EXPORT)
    @GetMapping("/exportUnionId")
    public AjaxResult exportUnionId(QwExternalContactParam qwExternalContact)
    {
        List<QwExternalContactUnionIdExportVO> list = qwExternalContactService.selectQwExternalContactUnionIdExportVO(qwExternalContact);
        ExcelUtil<QwExternalContactUnionIdExportVO> util = new ExcelUtil<QwExternalContactUnionIdExportVO>(QwExternalContactUnionIdExportVO.class);
        return util.exportExcel(list, "企业微信客户unionId数据");
    }


    /**
     * 获取企业微信客户详细信息
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(qwExternalContactService.selectQwExternalContactById(id));
    }

    /**
     * 新增企业微信客户
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:add')")
    @Log(title = "企业微信客户", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody QwExternalContact qwExternalContact)
    {
        return toAjax(qwExternalContactService.insertQwExternalContact(qwExternalContact));
    }

    /**
     * 修改企业微信客户
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:edit')")
    @Log(title = "企业微信客户", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody QwExternalContactManageParam param)
    {
        if (param == null || param.getId() == null) {
            return AjaxResult.error("企微客户ID不能为空");
        }
        if (param.getManageStatus() == null
                || (param.getManageStatus() != 1 && param.getManageStatus() != 2)) {
            return AjaxResult.error("管理状态无效，仅支持：1正常 2已被总部拉黑");
        }
        QwExternalContact contact = qwExternalContactService.selectQwExternalContactById(param.getId());
        if (contact == null) {
            return AjaxResult.error("企微客户不存在");
        }
        if (contact.getFsUserId() == null) {
            return AjaxResult.error("未绑定小程序会员，无法修改拉黑状态");
        }
        int rows = qwExternalContactService.updateExternalContactManageStatus(param);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error("修改失败");
    }

    /**
     * 删除企业微信客户
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:remove')")
    @Log(title = "企业微信客户", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(qwExternalContactService.deleteQwExternalContactByIds(ids));
    }
    @PreAuthorize("@ss.hasPermi('qw:externalContact:getUserInfo')")
    @GetMapping(value = "getUserInfo/{id}")
    public R getUserInfo(@PathVariable("id") Long id)
    {
        return R.ok().put("data",qwExternalContactInfoService.selectQwExternalContactInfoByExternalContactId(id));
    }

    @PreAuthorize("@ss.hasPermi('qw:externalContact:addUnassigned')")
    @Log(title = "同步待转接", businessType = BusinessType.INSERT)
    @PostMapping("/addUnassigned")
    public R addUnassigned(@RequestBody QwExternalContact qwExternalContact)
    {
        return qwExternalContactService.syncQwExternalContactUnassigned(qwExternalContact.getCorpId());
    }
    @PreAuthorize("@ss.hasPermi('qw:externalContact:transfer')")
    @Log(title = "企业微信客户", businessType = BusinessType.UPDATE)
    @PutMapping("/resignedTransfer")
    public R resignedTransfer(@RequestBody ResignedTransferParam param)
    {
        if (ObjectUtil.isNotEmpty(param.getQwUserName())&&ObjectUtil.isNotEmpty(param.getType())&&param.getType().equals("1")){
            QwExternalContactParam qwExternalContact =new QwExternalContactParam();
            qwExternalContact.setQwUserName(param.getQwUserName());

//            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
//            qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
            List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
            if (!CollectionUtils.isEmpty(list)){
                List<Long> ids = list.stream().map(QwExternalContactVO::getId).collect(Collectors.toList());
                param.setIds(ids);
            }
        }

        qwUserServiceAsyncHelper.resignedTransfer(param);
        int count = param.getIds() != null ? param.getIds().size() : 0;
        return R.ok("转接任务已提交，共 " + count + " 人，完成后请留意转接通知");
    }
    /**
     * 在职转接 分配客户
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:transfer')")
    @Log(title = "企业微信客户", businessType = BusinessType.UPDATE)
    @PutMapping("/transfer")
    public R transfer(@RequestBody TransferParam param)
    {
        if (ObjectUtil.isNotEmpty(param.getQwUserName())&&ObjectUtil.isNotEmpty(param.getType())&&param.getType().equals("1")){
            QwExternalContactParam qwExternalContact =new QwExternalContactParam();
            qwExternalContact.setQwUserName(param.getQwUserName());
//            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
//            qwExternalContact.setCompanyId(loginUser.getCompany().getCompanyId());
            List<QwExternalContactVO> list = qwExternalContactService.selectQwExternalContactListVO(qwExternalContact);
            if (!CollectionUtils.isEmpty(list)){
                List<Long> ids = list.stream().map(QwExternalContactVO::getId).collect(Collectors.toList());
                param.setIds(ids);
            }
        }
        qwUserServiceAsyncHelper.transfer(param);
        int count = param.getIds() != null ? param.getIds().size() : 0;
        return R.ok("转接任务已提交，共 " + count + " 人，完成后请留意转接通知");
    }

    /**
     * 在职/离职转接前置校验（iPad好友关系）
     */
    @PreAuthorize("@ss.hasPermi('qw:externalContact:transfer')")
    @PostMapping("/transferPreCheck")
    public R transferPreCheck(@RequestBody TransferPreCheckParam param)
    {
        return qwExternalContactService.transferPreCheck(param);
    }
}
