package com.fs.company.controller.aicall;

import com.alibaba.fastjson.JSONObject;
import com.fs.aicall.domain.CcCallTask;
import com.fs.aicall.domain.CcLlmAgentAccount;
import com.fs.aicall.service.ICcLlmAgentAccountService;
import com.fs.aicall.service.ICcParamsService;
import com.fs.aicall.service.ICcCallTaskService;
import com.fs.aicall.service.ICompanyBindAiModelService;
import com.fs.aicall.utils.CommonUtils;
import com.fs.aicall.utils.StringUtils;
import com.fs.common.annotation.Log;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.page.TableDataInfo;
import com.fs.common.enums.BusinessType;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.framework.security.LoginUser;
import com.fs.framework.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 机器人参数配置Controller
 * 
 * @author ruoyi
 * @date 2025-06-16
 */
@Controller
@RequestMapping("/aicall/account")
public class CcLlmAgentAccountController extends BaseController
{
    private String prefix = "aicall/account";

    @Autowired
    private ICcLlmAgentAccountService ccLlmAgentAccountService;
    @Autowired
    private ICcParamsService ccParamsService;
    @Autowired
    private ICcCallTaskService ccCallTaskService;
    @Autowired
    private ICompanyBindAiModelService companyBindAiModelService;

    @Autowired
    private TokenService tokenService;

    private static List<String> hideKeys = Arrays.asList("apiKey", "oauthPrivateKey", "oauthPublicKeyId", "patToken");


    @PreAuthorize("@ss.hasPermi('aicall:account:view')")
    @GetMapping()
    public String account()
    {
        return prefix + "/account";
    }

    /**
     * 查询机器人参数配置列表
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:list')")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(@RequestBody CcLlmAgentAccount ccLlmAgentAccount)
    {
        // 获取当前登录的公司ID
        Long companyId = getCurrentCompanyId();
        if (companyId != null) {
            List<Long> modelIds = companyBindAiModelService.selectModelIdsByCompanyId(companyId);
            if (!modelIds.isEmpty()) {
                ccLlmAgentAccount.setModelIds(modelIds);
            } else {
                return getDataTable(new ArrayList<>());
            }
        }
        
        startPage();
        List<CcLlmAgentAccount> list = ccLlmAgentAccountService.selectCcLlmAgentAccountList(ccLlmAgentAccount);
        TableDataInfo tableDataInfo = getDataTable(list);
        List<CcLlmAgentAccount> records = (List<CcLlmAgentAccount>) tableDataInfo.getRows();
        for (CcLlmAgentAccount data: records) {
            JSONObject accountJson = JSONObject.parseObject(data.getAccountJson());
            for (String key: accountJson.keySet()) {
                if (hideKeys.contains(key)) {
                    accountJson.put(key, CommonUtils.maskStringUtil(accountJson.getString(key)));
                }
            }
            data.setAccountJson(JSONObject.toJSONString(accountJson));
        }
        tableDataInfo.setRows(records);
        return tableDataInfo;
    }

    /**
     * 获取当前登录的公司ID
     * @return 公司ID
     */
    private Long getCurrentCompanyId() {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        return loginUser.getUser().getCompanyId();
    }

    /**
     * 导出机器人参数配置列表
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:export')")
    @Log(title = "机器人参数配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(CcLlmAgentAccount ccLlmAgentAccount)
    {
        List<CcLlmAgentAccount> list = ccLlmAgentAccountService.selectCcLlmAgentAccountList(ccLlmAgentAccount);
        ExcelUtil<CcLlmAgentAccount> util = new ExcelUtil<CcLlmAgentAccount>(CcLlmAgentAccount.class);
        return util.exportExcel(list, "机器人参数配置数据");
    }

    /**
     * 新增机器人参数配置
     */
    @GetMapping("/add")
    public String add(ModelMap mmap)
    {
        CcLlmAgentAccount ccLlmAgentAccount = new CcLlmAgentAccount();
        ccLlmAgentAccount.setInterruptIgnoreKeywords(ccParamsService.getParamValueByCode("default_interrupt_ignore_keywords", ""));
        ccLlmAgentAccount.setInterruptFlag(0);
        ccLlmAgentAccount.setAccountJson("{}");
        mmap.put("ccLlmAgentAccount", ccLlmAgentAccount);
        return prefix + "/add";
    }

    /**
     * 新增保存机器人参数配置
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:add')")
    @Log(title = "机器人参数配置", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(@RequestBody CcLlmAgentAccount ccLlmAgentAccount)
    {
        if ("Coze".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("CozeAccount");
        } else if ("LocalNlpChat".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("CozeAccount");
        } else if ("JiutianWorkflow".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())
                || "JiutianAgent".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("JiutianAccount");
        } else {
            ccLlmAgentAccount.setAccountEntity("LlmAccount");
        }
        if (null == ccLlmAgentAccount.getKbCatId()) {
            ccLlmAgentAccount.setKbCatId(-1);
        }
        
        // 新增模型
        int result = ccLlmAgentAccountService.insertCcLlmAgentAccount(ccLlmAgentAccount);
        
        // 获取当前登录的公司ID
        Long companyId = getCurrentCompanyId();
        if (result > 0 && companyId != null) {
            companyBindAiModelService.bindCompanyToModel(ccLlmAgentAccount.getId().longValue(), companyId);
        }
        
        return toAjax(result);
    }

    /**
     * 修改机器人参数配置
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:edit')")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Integer id, ModelMap mmap)
    {
        CcLlmAgentAccount ccLlmAgentAccount = ccLlmAgentAccountService.selectCcLlmAgentAccountById(id);
        if (StringUtils.isBlank(ccLlmAgentAccount.getInterruptIgnoreKeywords())) {
            ccLlmAgentAccount.setInterruptIgnoreKeywords(ccParamsService.getParamValueByCode("default_interrupt_ignore_keywords", ""));
        }
        JSONObject accountJson = JSONObject.parseObject(ccLlmAgentAccount.getAccountJson());
        for (String key: accountJson.keySet()) {
            if (hideKeys.contains(key)) {
                accountJson.put(key, CommonUtils.maskStringUtil(accountJson.getString(key)));
            }
        }
        ccLlmAgentAccount.setAccountJson(JSONObject.toJSONString(accountJson));
        mmap.put("ccLlmAgentAccount", ccLlmAgentAccount);

        String errMsg = checkEdit(ccLlmAgentAccount.getId());
        mmap.put("errorMsg", errMsg);
        return prefix + "/edit";
    }

    /**
     * 复制机器人参数配置
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:edit')")
    @GetMapping("/copy/{id}")
    public String copy(@PathVariable("id") Integer id, ModelMap mmap)
    {
        CcLlmAgentAccount ccLlmAgentAccount = ccLlmAgentAccountService.selectCcLlmAgentAccountById(id);
        if (StringUtils.isBlank(ccLlmAgentAccount.getInterruptIgnoreKeywords())) {
            ccLlmAgentAccount.setInterruptIgnoreKeywords(ccParamsService.getParamValueByCode("default_interrupt_ignore_keywords", ""));
        }
        ccLlmAgentAccount.setId(-1*ccLlmAgentAccount.getId());
        ccLlmAgentAccount.setName(ccLlmAgentAccount.getName() + "-副本");
        JSONObject accountJson = JSONObject.parseObject(ccLlmAgentAccount.getAccountJson());
        for (String key: accountJson.keySet()) {
            if (hideKeys.contains(key)) {
                accountJson.put(key, CommonUtils.maskStringUtil(accountJson.getString(key)));
            }
        }
        ccLlmAgentAccount.setAccountJson(JSONObject.toJSONString(accountJson));
        mmap.put("ccLlmAgentAccount", ccLlmAgentAccount);
        return prefix + "/edit";
    }

    /**
     * 修改保存机器人参数配置
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:edit')")
    @Log(title = "机器人参数配置", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@RequestBody CcLlmAgentAccount ccLlmAgentAccount)
    {

        if (ccLlmAgentAccount.getId() > 0) {
            String errMsg = checkEdit(ccLlmAgentAccount.getId());
            if (StringUtils.isNotEmpty(errMsg)) {
                return AjaxResult.error(errMsg);
            }
        }

        if ("Coze".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("CozeAccount");
        } else if ("LocalNlpChat".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("CozeAccount");
        } else if ("JiutianWorkflow".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())
                || "JiutianAgent".equalsIgnoreCase(ccLlmAgentAccount.getProviderClassName())) {
            ccLlmAgentAccount.setAccountEntity("JiutianAccount");
        } else {
            ccLlmAgentAccount.setAccountEntity("LlmAccount");
        }

        Integer orignId = ccLlmAgentAccount.getId();
        if (orignId < 0) {
            orignId = orignId * -1;
        }
        CcLlmAgentAccount oldCcLlmAgentAccount = ccLlmAgentAccountService.selectCcLlmAgentAccountById(orignId);
        JSONObject oldAccountJson = JSONObject.parseObject(oldCcLlmAgentAccount.getAccountJson());
        JSONObject newAccountJson = JSONObject.parseObject(ccLlmAgentAccount.getAccountJson());
        for (String key: newAccountJson.keySet()) {
            // 是需要脱敏的key，且值包含星号，则值不更新
            if (hideKeys.contains(key) && newAccountJson.getString(key).contains("****")) {
                newAccountJson.put(key, oldAccountJson.getString(key));
            }
        }
        ccLlmAgentAccount.setAccountJson(JSONObject.toJSONString(newAccountJson));
        if (null == ccLlmAgentAccount.getKbCatId()) {
            ccLlmAgentAccount.setKbCatId(-1);
        }

        if (ccLlmAgentAccount.getId() > 0) {
            return toAjax(ccLlmAgentAccountService.updateCcLlmAgentAccount(ccLlmAgentAccount));
        } else {
            ccLlmAgentAccount.setId(null);
            return toAjax(ccLlmAgentAccountService.insertCcLlmAgentAccount(ccLlmAgentAccount));
        }
    }

    /**
     * 删除机器人参数配置
     */
    @PreAuthorize("@ss.hasPermi('aicall:account:remove')")
    @Log(title = "机器人参数配置", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        //获取公司id
        Long companyId = getCurrentCompanyId();
        //删除公司绑定的AI模型
        companyBindAiModelService.deleteBindAiModelByCompanyIdAndModelIds(companyId,ids);

        return toAjax(ccLlmAgentAccountService.deleteCcLlmAgentAccountByIds(ids));
    }


    @GetMapping("/all")
    @ResponseBody
    public AjaxResult all()
    {
        List<CcLlmAgentAccount> list = ccLlmAgentAccountService.selectCcLlmAgentAccountList(new CcLlmAgentAccount());
        for (CcLlmAgentAccount data: list) {
            JSONObject accountJson = JSONObject.parseObject(data.getAccountJson());
            for (String key: accountJson.keySet()) {
                if (hideKeys.contains(key)) {
                    accountJson.put(key, CommonUtils.maskStringUtil(accountJson.getString(key)));
                }
            }
            data.setAccountJson(JSONObject.toJSONString(accountJson));
        }
        return AjaxResult.success(list);
    }



    private String checkEdit(Integer id)
    {
        CcLlmAgentAccount llmAgentAccount = ccLlmAgentAccountService.selectCcLlmAgentAccountById(id);
        List<CcCallTask> ccCallTaskList = ccCallTaskService.selectCcCallTaskList(new CcCallTask().setLlmAccountId(id));
        List<String> ids = new ArrayList<>();
        for (CcCallTask ccCallTask: ccCallTaskList) {
            // AI外呼，且不自动停止，且状态为正在拨打的任务，需要手动停止任务后再修改大模型配置再手动启动任务
            if (ccCallTask.getTaskType() == 1
                    && ccCallTask.getIfcall() == 1
                    && ccCallTask.getAutoStop() == 0) {
                ids.add(ccCallTask.getBatchName());
            }
        }
        if (ids.size() > 0) {
            return String.format("%s%s%s", "请先暂停任务：", StringUtils.join(ids, ","), "，再修改该配置，修改完成后再启动任务");
        } else {
            return "";
        }
    }

}
