package com.ruoyi.aicall.controller;

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

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aicall.domain.CcCallTask;
import com.ruoyi.aicall.domain.CcLlmAgentProvider;
import com.ruoyi.aicall.llm.ILlmCapability;
import com.ruoyi.aicall.llm.model.AccountBaseEntity;
import com.ruoyi.aicall.service.ICcCallTaskService;
import com.ruoyi.cc.service.ICcParamsService;
import com.ruoyi.cc.utils.LlmAccountParser;
import com.ruoyi.common.utils.CommonUtils;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UuidGenerator;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.aicall.domain.CcLlmAgentAccount;
import com.ruoyi.aicall.service.ICcLlmAgentAccountService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 机器人参数配置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;

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


    @RequiresPermissions("aicall:account:view")
    @GetMapping()
    public String account()
    {
        return prefix + "/account";
    }

    /**
     * 查询机器人参数配置列表
     */
    @RequiresPermissions("aicall:account:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(CcLlmAgentAccount ccLlmAgentAccount)
    {
        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;
    }

    /**
     * 导出机器人参数配置列表
     */
    @RequiresPermissions("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);
        JSONObject accountJson = new JSONObject();
        accountJson.put("rootId", UuidGenerator.GetOneUuid());
        ccLlmAgentAccount.setAccountJson(JSONObject.toJSONString(accountJson));
        mmap.put("ccLlmAgentAccount", ccLlmAgentAccount);
        return prefix + "/add";
    }

    /**
     * 新增保存机器人参数配置
     */
    @RequiresPermissions("aicall:account:add")
    @Log(title = "机器人参数配置", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(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);
        }
        return toAjax(ccLlmAgentAccountService.insertCcLlmAgentAccount(ccLlmAgentAccount));
    }

    /**
     * 修改机器人参数配置
     */
    @RequiresPermissions("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)));
            }
        }
        if (StringUtils.isBlank(accountJson.getString("rootId"))) {
            accountJson.put("rootId", UuidGenerator.GetOneUuid());
        }
        String recordingPath = ccParamsService.getParamValueByCode("recording_path", "/home/Records/");
        if (StringUtils.isNotEmpty(accountJson.getString("openingRemarksWav"))) {
            accountJson.put("openingRemarksFileUrl", "recordings/files?filename=" +accountJson.getString("openingRemarksWav").replace(recordingPath, ""));
        }
        if (StringUtils.isNotEmpty(accountJson.getString("customerNoVoiceTipsWav"))) {
            accountJson.put("customerNoVoiceTipsFileUrl", "recordings/files?filename=" +accountJson.getString("customerNoVoiceTipsWav").replace(recordingPath, ""));
        }
        if (StringUtils.isNotEmpty(accountJson.getString("hangupTipsWav"))) {
            accountJson.put("hangupTipsFileUrl", "recordings/files?filename=" +accountJson.getString("hangupTipsWav").replace(recordingPath, ""));
        }
        if (StringUtils.isNotEmpty(accountJson.getString("transferToAgentTipsWav"))) {
            accountJson.put("transferToAgentTipsFileUrl", "recordings/files?filename=" +accountJson.getString("transferToAgentTipsWav").replace(recordingPath, ""));
        }
        ccLlmAgentAccount.setAccountJson(JSONObject.toJSONString(accountJson));
        mmap.put("ccLlmAgentAccount", ccLlmAgentAccount);

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

    /**
     * 复制机器人参数配置
     */
    @RequiresPermissions("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";
    }

    /**
     * 修改保存机器人参数配置
     */
    @RequiresPermissions("aicall:account:edit")
    @Log(title = "机器人参数配置", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(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));
        }
    }

    /**
     * 删除机器人参数配置
     */
    @RequiresPermissions("aicall:account:remove")
    @Log(title = "机器人参数配置", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String 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 "";
        }
    }

}
