package org.dromara.talk.controller.admin;

import java.util.List;
import java.io.IOException;

import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.talk.domain.vo.TalkAgentVo;
import org.dromara.talk.domain.bo.TalkAgentBo;
import org.dromara.talk.service.ITalkAgentService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.core.domain.dto.DictDataDTO;
import org.dromara.common.core.service.DictService;

/**
 * 客服配置（管理端）
 *
 * @author Lion Li
 * @date 2026-01-27
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/talk/admin/agent")
public class TalkAgentController extends BaseController {

    private final ITalkAgentService talkAgentService;
    private final DictService dictService;

    /**
     * 查询客服配置列表
     *
     * @param bo 查询条件对象，包含客服名称、性别、状态等筛选条件
     * @param pageQuery 分页参数，包含页码和每页数量
     */
    @SaCheckPermission("talk:agent:list")
    @GetMapping("/list")
    public TableDataInfo<TalkAgentVo> list(TalkAgentBo bo, PageQuery pageQuery) {
        return talkAgentService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出客服配置列表
     *
     * @param bo 查询条件对象，包含客服名称、性别、状态等筛选条件
     * @param response HTTP响应对象，用于输出Excel文件流
     */
    @SaCheckPermission("talk:agent:export")
    @Log(title = "客服配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(TalkAgentBo bo, HttpServletResponse response) {
        List<TalkAgentVo> list = talkAgentService.queryList(bo);
        ExcelUtil.exportExcel(list, "客服配置", TalkAgentVo.class, response);
    }

    /**
     * 获取客服配置详细信息
     *
     * @param id 主键
     */
    @SaCheckPermission("talk:agent:query")
    @GetMapping("/{id}")
    public R<TalkAgentVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(talkAgentService.queryById(id));
    }

    /**
     * 新增客服配置
     *
     * @param bo 客服配置对象，包含客服名称、性别、头像、欢迎语、TTS参数等信息
     */
    @SaCheckPermission("talk:agent:add")
    @Log(title = "客服配置", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody TalkAgentBo bo) {
        return toAjax(talkAgentService.insertByBo(bo));
    }

    /**
     * 修改客服配置
     *
     * @param bo 客服配置对象，包含客服ID及需要修改的字段（名称、性别、头像、欢迎语、TTS参数等）
     */
    @SaCheckPermission("talk:agent:edit")
    @Log(title = "客服配置", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TalkAgentBo bo) {
        return toAjax(talkAgentService.updateByBo(bo));
    }

    /**
     * 删除客服配置
     *
     * @param ids 主键串
     */
    @SaCheckPermission("talk:agent:remove")
    @Log(title = "客服配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(talkAgentService.deleteWithValidByIds(List.of(ids), true));
    }

    /**
     * 上传客服头像
     *
     * @param file 上传的文件
     */
    @SaCheckPermission("talk:agent:edit")
    @Log(title = "客服配置", businessType = BusinessType.UPDATE)
    @PostMapping("/avatar")
    public R<String> uploadAvatar(@RequestParam("file") MultipartFile file) {
        try {
            String avatarUrl = talkAgentService.uploadAvatar(file);
            return R.ok(avatarUrl);
        } catch (IOException e) {
            return R.fail("上传头像失败: " + e.getMessage());
        }
    }

    /**
     * 获取TTS语音字典
     */
    @SaCheckPermission("talk:agent:list")
    @GetMapping("/dict/ttsVcn")
    public R<List<DictDataDTO>> getTtsVcnDict() {
        return R.ok(dictService.getDictData("tts_vcn"));
    }

    /**
     * 改变客服状态
     *
     * @param id        客服ID
     * @param newStatus 新状态
     */
    @Log(title = "客服配置", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/status/{newStatus}")
    public R<Void> changeStatus(@NotNull(message = "客服ID不能为空") @PathVariable Long id,
                                @NotNull(message = "状态不能为空") @PathVariable String newStatus) {
        boolean success = talkAgentService.changeAgentStatus(id, newStatus);
        if (success) {
            return R.ok();
        } else {
            return R.fail("状态更新失败，客服可能已被其他用户占用");
        }
    }

}
