package com.fs.his.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.SecurityUtils;
import com.fs.common.utils.sign.Md5Utils;
import com.fs.his.config.FsSysConfig;
import com.fs.his.domain.*;
import com.fs.his.mapper.FsDoctorMapper;
import com.fs.his.mapper.FsFollowMapper;
import com.fs.his.mapper.FsFollowTempMapper;
import com.fs.his.mapper.FsStoreOrderMapper;
import com.fs.his.param.FsDoctorListUParam;
import com.fs.his.param.FsDoctorParam;
import com.fs.his.param.FsUpdateFollowParam;
import com.fs.his.service.IFsDoctorService;
import com.fs.his.service.IFsPrescribeService;
import com.fs.his.utils.ConfigUtil;
import com.fs.his.utils.HttpUtil;
import com.fs.his.utils.qrcode.QRCodeUtils;
import com.fs.his.vo.*;
import com.fs.im.dto.MsgCustomDTO;
import com.fs.im.dto.MsgDTO;
import com.fs.im.dto.MsgDataDTO;
import com.fs.im.dto.MsgDataFormatDTO;
import com.fs.im.service.IImService;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.zxing.WriterException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;

/**
 * 医生管理Service业务层处理
 *
 * @author fs
 * @date 2023-06-05
 */
@Service
public class FsDoctorServiceImpl implements IFsDoctorService
{
    @Autowired
    private FsDoctorMapper fsDoctorMapper;
    @Autowired
    private FsStoreOrderMapper fsStoreOrderMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private FsFollowTempMapper fsFollowTempMapper;
    @Autowired
    FsFollowMapper fsFollowMapper;
    @Autowired
    private IImService imService;
    @Autowired
    private IFsPrescribeService fsPrescribeService;
    @Autowired
    ConfigUtil configUtil;
    /**
     * 查询医生管理
     *
     * @param doctorId 医生管理主键
     * @return 医生管理
     */
    @Override
    public FsDoctor selectFsDoctorByDoctorId(Long doctorId)
    {
        return fsDoctorMapper.selectFsDoctorByDoctorId(doctorId);
    }

    /**
     * 查询医生管理列表
     *
     * @param fsDoctor 医生管理
     * @return 医生管理
     */
    @Override
    public List<FsDoctor> selectFsDoctorList(FsDoctor fsDoctor)
    {
        return fsDoctorMapper.selectFsDoctorList(fsDoctor);
    }

    /**
     * 新增医生管理
     *
     * @param fsDoctor 医生管理
     * @return 结果
     */
    @Override
    public int insertFsDoctor(FsDoctor fsDoctor)
    {
        FsDoctor f = fsDoctorMapper.selectFsDoctorByAccount(fsDoctor.getAccount());
        if (f!=null){
            throw new CustomException("账号已存在");
        }

        fsDoctor.setCreateTime(DateUtils.getNowDate());
        int i = fsDoctorMapper.insertFsDoctor(fsDoctor);
        if (fsDoctor.getIsPrescribeDoctor()==1){
            fsDoctor.setPrescribeDoctorId(fsDoctor.getDoctorId());
            fsDoctorMapper.updateFsDoctor(fsDoctor);
        }
        return i;
    }

    /**
     * 修改医生管理
     *
     * @param fsDoctor 医生管理
     * @return 结果
     */
    @Override
    public int updateFsDoctor(FsDoctor fsDoctor)
    {

//        fsDoctor.setUpdateBy(SecurityUtils.getUsername());
        fsDoctor.setUpdateTime(DateUtils.getNowDate());
        return fsDoctorMapper.updateFsDoctor(fsDoctor);
    }

    /**
     * 批量删除医生管理
     *
     * @param doctorIds 需要删除的医生管理主键
     * @return 结果
     */
    @Override
    public int deleteFsDoctorByDoctorIds(Long[] doctorIds)
    {
        return fsDoctorMapper.deleteFsDoctorByDoctorIds(doctorIds);
    }

    /**
     * 删除医生管理信息
     *
     * @param doctorId 医生管理主键
     * @return 结果
     */
    @Override
    public int deleteFsDoctorByDoctorId(Long doctorId)
    {
        return fsDoctorMapper.deleteFsDoctorByDoctorId(doctorId);
    }

    @Override
    public List<FsDoctorListVO> selectFsDoctorListVO(FsDoctorParam fsDoctor) {
        return fsDoctorMapper.selectFsDoctorListVO(fsDoctor);
    }

    @Override
    public List<UserVo> selectUserVOList(String name) {
        return fsDoctorMapper.selectuserVOList(name);
    }

    @Override
    public FsDoctorVO selectFsDoctorVOByDoctorId(Long doctorId) {
        return fsDoctorMapper.selectFsDoctorVOByDoctorId(doctorId);
    }

    @Override
    public List<UserVo> selectUserDocVoList(String name) {
        return fsDoctorMapper.selectuserDocVoList(name);
    }

    @Override
    public List<FsDoctorListUVO> selectFsDoctorListUVO(FsDoctorListUParam param) {
        return fsDoctorMapper.selectFsDoctorListUVO(param);
    }

    @Override
    public int updateEditFsDoctor(FsDoctor fsDoctor) {

        fsDoctor.setAuditTime(DateUtils.getNowDate());
        return fsDoctorMapper.updateFsDoctor(fsDoctor);
    }

    @Override
    public FsDoctor selectFsDoctorByAccount(String account) {
        return fsDoctorMapper.selectFsDoctorByAccount(account);
    }

    @Override
    public FsDoctor selectFsDoctorByUserId(long userId) {
        return fsDoctorMapper.selectFsDoctorByUserId(userId);
    }
    public int updateFsDoctorPassWord(FsDoctor fsDoctor) {
        FsDoctor f = new FsDoctor();
        f.setPassword(Md5Utils.hash((fsDoctor.getPassword())));
        f.setDoctorId(fsDoctor.getDoctorId());
        return fsDoctorMapper.updateFsDoctor(f);
    }

    @Override
    public byte[] getWxaCodeUnLimit() {

        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.config");
        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);

        String url="https://api.weixin.qq.com/cgi-bin/stable_token";
        HashMap<String, String> map = new HashMap<>();
        map.put("grant_type","client_credential");
        map.put("appid","wx6535a9714d7e4e67");
        map.put("secret","8fd06ebe1b15bbdfbd5b524e04a20ab4");
        String accessToken = HttpUtil.endApi(url, null, map);
        // 创建Gson对象
        Gson gson = new Gson();
        // 将JSON字符串解析为Java对象
        Map<String, String> accessTokenMap  = gson.fromJson(accessToken, new TypeToken<Map<String, Object>>(){}.getType());
        String codeUrl="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessTokenMap.get("access_token");
        HashMap<String, String> jsonMap = new HashMap<>();
        jsonMap.put("page","pages_user/registerDoctor");
        jsonMap.put("scene","userId="+SecurityUtils.getUserId());
        //正式版为 "release"，体验版为 "trial"，开发版为 "develop"
        jsonMap.put("env_version","trial");
        byte[] bytes = HttpUtil.getWechatQrcodeByHttpURL(codeUrl, jsonMap);
        return bytes;
    }
    @SuppressWarnings("all")
    @Override
    public String getDoctorInquiryImg(Long doctorId){
        FsSysConfig sysConfig = configUtil.getSysConfig();

        String codeUrl=sysConfig.getCodeUrl()+"doctorImg?doctorId="+doctorId;
        FsDoctor fsDoctor = fsDoctorMapper.selectFsDoctorByDoctorId(doctorId);
        String doctorCardUrl = fsDoctor.getDoctorCardUrl();
        if (doctorCardUrl!=null&&doctorCardUrl!=""){
            return doctorCardUrl;
        }
        String avatar = fsDoctor.getAvatar();
        if (avatar==null&&avatar!=""){
            throw new CustomException("请先配置工作照");
        }
        File mb = new File("C:\\fs\\doc.jpg");
        if (!mb.exists()) {
            // 创建目录
            throw  new CustomException("模板文件不存在");
        }
        BufferedImage image = null;
        try {
            image = ImageIO.read(mb);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建画笔(image为上一步的图片对象)
        Graphics2D pen = image.createGraphics();
        try {
            URL url = new URL(avatar);
            BufferedImage img = ImageIO.read(url);
            BufferedImage rund = rund(img);
          //  rund.getGraphics().drawImage(rund, 0, 0, 155, 155, null);
           BufferedImage bufferedImage = convertCircular(rund);
            pen.drawImage(bufferedImage, 100, 710, 150, 150, null);
        } catch (IOException e) {
            e.printStackTrace();
        }

        pen.setColor(Color.black);
        //处理字体 高清加边缘模糊
        pen.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        pen.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        pen.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        pen.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
        pen.setFont(new Font("黑体", Font.BOLD  ,50));
        pen.setColor(Color.decode("#ffffff"));
        String doctorName = fsDoctor.getDoctorName();
        if (doctorName.length()==2){
            doctorName=doctorName.substring(0,1)+" "+doctorName.substring(1,2);
        }
        pen.drawString(doctorName,270,807);

        try {
            ByteArrayOutputStream qr = QRCodeUtils.create(codeUrl);
            byte[] imageBytes = qr.toByteArray(); // 从 ByteArrayOutputStream 获取字节数组

            ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); // 创建 ByteArrayInputStream
            BufferedImage qrImage = ImageIO.read(inputStream);
            pen.drawImage(qrImage, 210, 340, 235, 235, null);
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
        CloudStorageService storage = OSSFactory.build();
        String url = storage.uploadSuffix(inputStream, ".jpg");
        FsDoctor doctor = new FsDoctor();
        doctor.setDoctorId(doctorId);
        doctor.setDoctorCardUrl(url);
        fsDoctorMapper.updateFsDoctor(doctor);
        return url;
    }

    @Override
    public FsDoctor selectFsDoctorByDoctorIdForUpdate(Long doctorId) {
        return fsDoctorMapper.selectFsDoctorByDoctorIdForUpdate(doctorId);
    }

    @Override
    public void addFsDoctorOrderNumberByDoctorId(Long doctorId) {

        FsDoctor doc = fsDoctorMapper.selectFsDoctorByDoctorId(doctorId);
        FsDoctor fsDoctor = new FsDoctor();
        fsDoctor.setDoctorId(doctorId);
        fsDoctor.setOrderNumber(doc.getOrderNumber()+1);
        fsDoctorMapper.updateFsDoctor(fsDoctor);
    }
   List<Long> doctorIds;
   Integer lun=0;
    @Override
    public Long selectFsDoctorDoctorByPackage() {
        List<Long> ids = fsDoctorMapper.selectFsDoctorDoctorByPackage();
        if (doctorIds==null||doctorIds.size()!=ids.size()){
            doctorIds=ids;
        }
        Long doctorId=null;
        if (ids!=null&&ids.size()>0){
            if (lun>=ids.size()){
                lun=0;
            }
            doctorId = ids.get(lun);
            lun++;
        }
        return doctorId;
    }

    @Override
    public Long selectFollowDoctorDoctorByPackage() {
        return fsDoctorMapper.selectFollowDoctorDoctorByPackage();
    }

    @Override
    public List<OptionsVO> selectfollowDoctorList() {
        return fsDoctorMapper.selectfollowDoctorList();
    }

    @Override
    public int editFollowByFsDoctor(FsUpdateFollowParam fsDoctor) {
        Long fromId = fsDoctor.getFromId();
        List<FsStoreOrder> orders = fsStoreOrderMapper.selectStoreOrderIdByFollowDoctorId(fromId);
        int i = fsStoreOrderMapper.updateFsStoreOrderByFollow(fsDoctor);
        if (orders!=null&&orders.size()>0){
            SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
            Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
            Integer followTempId = (Integer) config.get("followTempId");
            FsFollowTemp fsFollowTemp = fsFollowTempMapper.selectFsFollowTempByTempId(followTempId + 0L);

            for (FsStoreOrder order : orders) {

                try {
                    if (fsFollowTemp != null) {
                        FsFollow fsFollow = new FsFollow();
                        fsFollow.setTempId(followTempId + 0L);
                        FsPrescribe fsPrescribe = fsPrescribeService.selectFsPrescribeByPrescribeId(order.getPrescribeId());
                        fsFollow.setPatientPhone(order.getUserPhone());
                        if (fsPrescribe != null) {
                            fsFollow.setPatientName(fsPrescribe.getPatientName());
                            fsFollow.setPatientId(fsPrescribe.getPatientId());
                        }
                        fsFollow.setUserId(order.getUserId());
                        fsFollow.setDoctorId(order.getFollowDoctorId());
                        fsFollow.setTotalNum(1);
                        fsFollow.setStoreOrderId(order.getOrderId());
                        fsFollow.setCompanyId(order.getCompanyId());
                        fsFollow.setCompanyUserId(order.getCompanyUserId());
                        fsFollow.setDeptId(order.getDeptId());
                        fsFollow.setNum(1);
                        fsFollow.setInquiryOrderId(order.getInquiryOrderId());
                        fsFollow.setPlanTime(DateUtils.getNowDate());
                        fsFollow.setPushStatus(1);
                        fsFollow.setWriteStatus(0);
                        fsFollow.setFormJson(fsFollowTemp.getFormJson());
                        fsFollow.setCreateTime(DateUtils.getNowDate());
                        fsFollowMapper.insertFsFollow(fsFollow);
                        MsgDTO msgDTO = new MsgDTO();
                        MsgCustomDTO customDTO3 = new MsgCustomDTO();
                        customDTO3.setType("startFollow");
                        customDTO3.setOrderType(2);
                        customDTO3.setImType(2);
                        customDTO3.setFollowId(fsFollow.getFollowId().toString());
                        customDTO3.setOrderId(order.getOrderId().toString());
                        msgDTO.setCloudCustomData(JSONUtil.toJsonStr(customDTO3));
                        msgDTO.setFrom_Account("D-" + fsFollow.getDoctorId());
                        msgDTO.setTo_Account("U-" + fsFollow.getUserId());
                        List<MsgDataDTO> msgs = new ArrayList<>();
                        MsgDataDTO msg = new MsgDataDTO();
                        String ext = JSONUtil.toJsonStr(fsFollow);
                        String followId = fsFollow.getFollowId().toString();
                        msg.setMsgContent(new MsgDataFormatDTO("follow", ext, followId));
                        msg.setMsgType("TIMCustomElem");//TIMCustomElem
                        msgs.add(msg);
                        msgDTO.setMsgBody(msgs);
                        imService.sendMsg(msgDTO);

                        MsgDTO msgDTO2 = new MsgDTO();
                        MsgCustomDTO customDTO = new MsgCustomDTO();
                        customDTO.setType("startFollow");
                        customDTO.setOrderType(2);
                        customDTO.setImType(2);
                        customDTO.setFollowId(fsFollow.getFollowId().toString());
                        customDTO.setOrderId(order.getOrderId().toString());
                        msgDTO2.setCloudCustomData(JSONUtil.toJsonStr(customDTO));
                        msgDTO2.setFrom_Account("D-" + fsFollow.getDoctorId());
                        msgDTO2.setTo_Account("U-" + fsFollow.getUserId());
                        List<MsgDataDTO> msgs2 = new ArrayList<>();
                        MsgDataDTO msg2 = new MsgDataDTO();
                        msg2.setMsgContent(new MsgDataFormatDTO("尊敬的用户，为了您的健康，请认真填写随访单，以便医生随时了解您的用药情况，评估治疗效果。\n" +
                                "如果在用药中出现任何不适，可直接在对话框中描述您目前的情况，我将及时为您解答！"));
                        msg2.setMsgType("TIMTextElem");//TIMCustomElem
                        msgs2.add(msg2);
                        msgDTO2.setMsgBody(msgs2);
                        imService.sendMsg(msgDTO2);
                    }
                }catch (Exception e){

                }
            }
        }


        return i;
    }

    @Override
    public List<OptionsVO> selectAllfollowDoctorList() {
        return fsDoctorMapper.selectAllfollowDoctorList();
    }

    @Override
    public List<UserVo> selectAllDocVoList() {
        return fsDoctorMapper.selectAllDocVoList();
    }

    @Override
    public List<UserVo> selectUserDocVoListByCompany(Long companyId) {
        return fsDoctorMapper.selectUserDocVoListByCompany(companyId);
    }

    public static BufferedImage convertCircular(BufferedImage bi1) throws IOException {
        // 透明底的图片
        BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight());
        Graphics2D g2 = bi2.createGraphics();
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2.drawImage(bi1, 0, 0, null);
        // 设置颜色
        g2.setBackground(Color.green);
        g2.dispose();
        return bi2;
    }

    public static BufferedImage rund( BufferedImage originalImage){
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        double targetAspectRatio = 1;
        int targetHeight = (int) Math.round(originalWidth / targetAspectRatio);
        if (targetHeight > originalHeight) {
            targetHeight = originalHeight;
        }
        int targetWidth = (int) Math.round(targetHeight * targetAspectRatio);
        int x = (originalWidth - targetWidth) / 2;
        int y = (originalHeight - targetHeight) / 2;

        return originalImage.getSubimage(x, y, targetWidth, targetHeight);
    }

}
