package com.fs.company.controller.common;

import cn.hutool.json.JSONUtil;
import com.fs.common.config.FSConfig;
import com.fs.common.constant.Constants;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.domain.R;
import com.fs.common.exception.file.OssException;
import com.fs.common.utils.security.OssUploadSecurityUtils;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.file.FileUploadUtils;
import com.fs.common.utils.file.FileUtils;
import com.fs.company.service.ICompanyService;
import com.fs.company.utils.AudioUtils;
import com.fs.company.vo.WangUploadVO;
import com.fs.course.service.ITencentCloudCosService;
import com.fs.framework.config.ServerConfig;
import com.fs.framework.security.LoginUser;
import com.fs.framework.service.TokenService;
import com.fs.his.domain.FsExportTask;
import com.fs.his.dto.InquiryConfigDTO;
import com.fs.his.service.IFsExportTaskService;
import com.fs.im.dto.OpenImResponseDTO;
import com.fs.im.service.OpenIMService;
import com.fs.qw.service.IQwWorkTaskService;
import com.fs.qwApi.service.QwApiService;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.fs.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 通用请求处理
 *

 */
@RestController
public class CommonController
{


    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
    @Autowired
    private IFsExportTaskService exportTaskService;
    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private QwApiService qwApiService;
    @Autowired
    private ITencentCloudCosService tencentCloudCosService;


    @Autowired
    private ISysConfigService configService;

    @Autowired
    private OpenIMService openIMService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private TokenService tokenService;
//    @Autowired
//    private TestTwoService testService2;
////
//    @GetMapping("/testSop")
//    public R testSop() throws Exception {
//        testService2.selectSopUserLogsListByTime();
//        return R.ok();
//    }
    @Autowired
    private IQwWorkTaskService qwWorkTaskService;

    @PostMapping("common/test")
    public R test() throws Exception
    {
        qwWorkTaskService.delQwWorkTaskByOver();
      //  qwWorkTaskService.addQwWorkByFirstCourse();
//        qwWorkTaskService.addQwWorkByCourse();
//        qwWorkTaskService.addQwWorkByConversionDay();
      return R.ok();
    }

    @GetMapping("common/test2")
    public R test2(String time) throws Exception
    {
        // 默认是前两天时间
        String createSTime;
        String createETime;
        if (StringUtils.isNotBlank(time)) {
            Date date = DateUtils.parseDate(time);
            createSTime = time+" 00:00:00";
            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(date, 1))+" 00:00:00";
        } else {
            createSTime = DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -2))+" 00:00:00";
            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -1))+" 00:00:00";
        }

        // 这个地方真加的是company money字段 xgb
        companyService.rollbackRedPacketMoney(createSTime, createETime);
        return R.ok();
    }

    @GetMapping("common/test3")
    public R test2(String companyIdStr,String outBatchNo) throws Exception
    {
        // 默认是前两天时间
        Long companyId=Long.parseLong(companyIdStr);
        R result=companyService.checkMchTransferStatusByBatchID(outBatchNo,companyId);
        log.info("查询商户转账结果：{}",result);
        return R.ok();
    }


    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("common/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.checkAllowDownloadFileName(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            // 防御性取 basename，避免异常拼接跳出下载目录
            String safeFileName = StringUtils.substringAfterLast(fileName.replace('\\', '/'), "/");
            if (StringUtils.isEmpty(safeFileName))
            {
                safeFileName = fileName;
            }
            String realFileName = System.currentTimeMillis() + safeFileName.substring(safeFileName.indexOf("_") + 1);
            String filePath = FSConfig.getDownloadPath() + safeFileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (Boolean.TRUE.equals(delete))
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }
    @GetMapping(value = "common/getTask/{taskId}")
    public R getTask(@PathVariable("taskId") Long taskId)
    {
        FsExportTask task=exportTaskService.selectFsExportTaskByTaskId(taskId);
        return R.ok().put("data",task);
    }
    /**
     * 通用上传请求
     */
    @PostMapping("/common/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = FSConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/common/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        try
        {
            if (!FileUtils.checkAllowDownload(resource))
            {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = FSConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    @PostMapping("common/uploadOSS")
    public R uploadOSS(@RequestParam("file") MultipartFile file) throws Exception
    {
        if (file.isEmpty())
        {
            throw new OssException("上传文件不能为空");
        }
        // 上传文件
        String suffix = OssUploadSecurityUtils.validateAndGetDotSuffix(file);
        CloudStorageService storage = OSSFactory.build();
        String url = storage.uploadSuffix(file.getBytes(), suffix);
        return R.ok().put("url",url);
    }

    @PostMapping("common/uploadOSS2")
    public R uploadOSS2(@RequestParam("file") MultipartFile file) throws Exception
    {
        if (file.isEmpty())
        {
            throw new OssException("上传文件不能为空");
        }
        // 校验后缀白名单，并保留清洗后的真实文件名（如 xxx.docx）
        String safeFileName = OssUploadSecurityUtils.validateAndGetSafeFilename(file);
        CloudStorageService storage = OSSFactory.build();
        // 对象键：日期目录 + basename_时间戳.扩展名（防同日覆盖，仍可读且含真实扩展名）
        int dot = safeFileName.lastIndexOf('.');
        String baseName = dot > 0 ? safeFileName.substring(0, dot) : safeFileName;
        String ext = dot > 0 ? safeFileName.substring(dot) : "";
        String objectFileName = baseName + "_" + System.currentTimeMillis() + ext;
        String objectKey = storage.getPathWithSafeFilename(null, objectFileName);
        String url = storage.upload(file.getBytes(), objectKey);
        return R.ok().put("url", url).put("fileName", safeFileName);
    }

    @PostMapping("common/uploadOSSByHOOKImage")
    public R uploadOSSByHOOK(@RequestParam("file") MultipartFile file) throws Exception
    {
        if (file.isEmpty())
        {
            throw new OssException("上传文件不能为空");
        }
        InputStream inputStream = file.getInputStream();
        BufferedImage bufferedImage = ImageIO.read(inputStream);
        if (bufferedImage == null) {
            throw new OssException("无法解析图片，请检查文件内容是否正确");
        }

        // 将 BufferedImage 转换为 PNG 格式字节数组
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", pngOutputStream);

        // 获取 PNG 格式的字节数组
        byte[] pngBytes = pngOutputStream.toByteArray();

        // 上传文件
        CloudStorageService storage = OSSFactory.build();
        String url = storage.uploadSuffix(pngBytes, ".png");

        return R.ok().put("url", url);
    }


    //MP3上传且转化为Sile,并且返回MP3的地址和sile的地址
    @PostMapping("common/uploadOSSByHOOKVoice")
    public R uploadOSSByQw(@RequestParam("file") MultipartFile file) throws Exception
    {
        if (file.isEmpty())
        {
            throw new OssException("上传文件不能为空");
        }

        // 上传文件
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        CloudStorageService storage = OSSFactory.build();
        String mp3Url = storage.uploadSuffix(file.getBytes(), suffix);
        String silkUrl="";
        try {
            silkUrl = AudioUtils.transferAudioSilkFromUrl(mp3Url,true);
        }catch (Exception e){
            throw new Exception("音频转换失败:"+e);
        }

        return R.ok().put("mp3Url", mp3Url).put("silkUrl", silkUrl);
    }
    @PostMapping("/common/uploadWang")
    public WangUploadVO uploadWang(@RequestParam(value = "fileName", required = false) MultipartFile file) throws Exception
    {
        WangUploadVO vo=new WangUploadVO();
        try
        {
            if (file.isEmpty())
            {
                throw new OssException("上传文件不能为空");
            }
            // 上传文件
            String suffix = OssUploadSecurityUtils.validateAndGetDotSuffix(file);
        CloudStorageService storage = OSSFactory.build();
        String url = storage.uploadSuffix(file.getBytes(), suffix);
            vo.setErrno(0);
            List<WangUploadVO.WangUploadItem> items=new ArrayList<>();
            WangUploadVO.WangUploadItem item=new WangUploadVO.WangUploadItem();
            item.setUrl(url);
            items.add(item);
            vo.setData(items);
            return vo;
        }
        catch (Exception e)
        {
            vo.setErrno(-1);
            return vo;
        }
    }

    @GetMapping("/common/getTmpSecretKey")
    public R getTmpSecretKey()
    {
        return tencentCloudCosService.getKeyAndCredentials();
    }

    @GetMapping(value = "/common/getInquiryConfig")
    public AjaxResult getInquiryConfig()
    {
        String json=configService.selectConfigByKey("his.inquiryConfig");
        InquiryConfigDTO configDTO= JSONUtil.toBean(json, InquiryConfigDTO.class);
        String inquirySubType = configDTO.getInquirySubType();
        return AjaxResult.success(inquirySubType);
    }

    //分享会诊
    @PostMapping(value = "/common/sendInquiry")
    public AjaxResult sendInquiry(@RequestBody Map<String,String> map){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long companyUserId = loginUser.getUser().getUserId();
        Long companyId = loginUser.getCompany().getCompanyId();
        String inquiryName = map.get("inquiryName");
        String type = map.get("type");
        String sendID = map.get("sendID");
        String recvID = map.get("recvID");
        String doctorId = map.get("doctorId");
        OpenImResponseDTO inquirySelect = openIMService.sendInquiryUtil(sendID, recvID, 110, "inquirySelect", inquiryName, type,companyId,companyUserId,doctorId);
        return AjaxResult.success(inquirySelect);
    }


}
