package com.fs.app.controller;


import cn.hutool.json.JSONUtil;
import com.fs.app.annotation.Login;
import com.fs.app.param.DoctorEditParam;
import com.fs.app.param.DoctorEditPwdParam;
import com.fs.app.param.DoctorLoginParam;
import com.fs.common.constant.Constants;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.sign.Md5Utils;
import com.fs.his.domain.*;
import com.fs.his.dto.FsExtractDTO;
import com.fs.his.enums.FsExtractTypeEnum;
import com.fs.his.param.FsDoctorBillListSParam;
import com.fs.his.param.FsDoctorDoExtractParam;
import com.fs.his.param.FsDoctorExtractEditParam;
import com.fs.his.param.FsDoctorExtractListSParam;
import com.fs.his.service.*;
import com.fs.his.vo.FsDoctorBillListSVO;
import com.fs.his.vo.FsDoctorExtractListSVO;
import com.fs.sms.service.SmsService;
import com.fs.system.service.ISysConfigService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Api("个人中心")
@RestController
@RequestMapping(value="/app/doctor")
public class DoctorController extends  AppBaseController {
    @Autowired
    RedisCache redisCache;
    @Autowired
    private IFsDoctorService doctorService;
    @Autowired
    private IFsHospitalService hospitalService;
    @Autowired
    private IFsDepartmentService departmentService;
    @Autowired
    private IFsDoctorBillService doctorBillService;
    @Autowired
    private IFsDoctorExtractService doctorExtractService;
    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SmsService smsService;
    @ApiOperation("登录")
    @PostMapping("/login")
    public R login(@Validated  @RequestBody DoctorLoginParam param) {
        FsDoctor doctor=doctorService.selectFsDoctorByAccount(param.getAccount());
        if(doctor==null||!doctor.getStatus().equals(1)){
            return R.error("帐号不存在或已停用");
        }
        else{
            if(StringUtils.isNotEmpty(param.getJpushId())){
                FsDoctor doctorMap=new FsDoctor();
                doctorMap.setDoctorId(doctor.getDoctorId());
                doctorMap.setJpushId(param.getJpushId());
                doctorService.updateFsDoctor(doctorMap);
            }

            if(!doctor.getDoctorType().equals(param.getType())){
                return R.error("非法操作");
            }
            if(!Md5Utils.hash(param.getPassword()).equals(doctor.getPassword())){
                return R.error("密码不正确");
            }
            String token = jwtUtils.generateToken(doctor.getDoctorId());
            redisCache.setCacheObject("doctorToken:"+doctor.getDoctorId(),token,604800, TimeUnit.SECONDS);
            Map<String,Object> map=new HashMap<>();
            map.put("token",token);
            map.put("doctor",doctor);
            if(doctor.getDeptId()!=null){
                FsDepartment department=departmentService.selectFsDepartmentByDeptId(doctor.getDeptId());
                if(department!=null){
                    map.put("deptName",department.getDeptName());
                }
                else{
                    map.put("deptName","");
                }
            }
            return R.ok(map);
        }
    }

    @ApiOperation("登录")
    @PostMapping("/loginByWeb")
    public R loginByWeb(@Validated @RequestBody DoctorLoginParam param) {
        FsDoctor doctor=doctorService.selectFsDoctorByAccount(param.getAccount());
        if(doctor==null||!doctor.getStatus().equals(1)){
            return R.error("帐号不存在或已停用");
        }
        else{
            if(StringUtils.isNotEmpty(param.getJpushId())){
                FsDoctor doctorMap=new FsDoctor();
                doctorMap.setDoctorId(doctor.getDoctorId());
                doctorMap.setJpushId(param.getJpushId());
                doctorService.updateFsDoctor(doctorMap);
            }
            if(!doctor.getDoctorType().equals(param.getType())){
                return R.error("非法操作");
            }
            if(!Md5Utils.hash(param.getPassword()).equals(doctor.getPassword())){
                return R.error("密码不正确");
            }
            boolean captchaOnOff = configService.selectCaptchaOnOff();
            // 验证码开关
            if (captchaOnOff)
            {
                String msg =  validateCaptcha(param.getAccount(), param.getCode(), param.getUuid());
                if(!msg.equals("验证成功")){
                    return R.error(msg);
                };
            }
            String token = jwtUtils.generateToken(doctor.getDoctorId());
            redisCache.setCacheObject("doctorToken:"+doctor.getDoctorId(),token,604800, TimeUnit.SECONDS);
            Map<String,Object> map=new HashMap<>();
            map.put("token",token);
            map.put("doctor",doctor);
            if(doctor.getDeptId()!=null){
                FsDepartment department=departmentService.selectFsDepartmentByDeptId(doctor.getDeptId());
                if(department!=null){
                    map.put("deptName",department.getDeptName());
                }
                else{
                    map.put("deptName","");
                }
            }
            return R.ok(map);
        }
    }

    public String validateCaptcha(String username, String code, String uuid) {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);

        if (captcha == null) {
            // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
//            throw new CaptchaExpireException();
            return "验证码失效";

        }

        if (!code.equalsIgnoreCase(captcha)) {
            // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
//            throw new CaptchaException();
            return "验证码错误";
        }

        return "验证成功";
    }
    @Login
    @ApiOperation("获取医生信息")
    @GetMapping("/getDoctorInfo")
    public R getDoctorInfo(HttpServletRequest request){
        try {
            FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
            FsHospital hospital=hospitalService.selectFsHospitalByHospitalId(doctor.getHospitalId());
            FsDepartment department=departmentService.selectFsDepartmentByDeptId(doctor.getDeptId());

            Map<String,Object> map=new HashMap<>();
            map.put("doctor",doctor);
            map.put("hospital",hospital);
            map.put("department",department);
            return R.ok(map);
        } catch (Exception e){
            return R.error("操作异常");
        }
    }

    @Login
    @ApiOperation("检测是否登录")
    @GetMapping("/checkLogin")
    public R checkLogin(HttpServletRequest request){
        return R.ok("认证成功");
    }


    @Login
    @ApiOperation("修改信息")
    @PostMapping("/editDoctor")
    public R editDoctor(@Validated @RequestBody DoctorEditParam param, HttpServletRequest request){
        FsDoctor doctor=new FsDoctor();
        doctor.setDoctorId(Long.parseLong(getDoctorId()));
        doctor.setWorkStatus(param.getWorkStatus());
        doctor.setPriceJson(param.getPriceJson());
        doctor.setMobile(param.getMobile());
        doctor.setSignUrl(param.getSignUrl());
        doctorService.updateFsDoctor(doctor);
        return R.ok("修改成功");
    }

    @Login
    @ApiOperation("修改密码")
    @PostMapping("/editPwd")
    public R editPwd(@Validated @RequestBody DoctorEditPwdParam param, HttpServletRequest request){
        FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
        if(!Md5Utils.hash(param.getOldPassword()).equals(doctor.getPassword())){
            return R.error("旧密码不正确");
        }
        FsDoctor map=new FsDoctor();
        map.setDoctorId(Long.parseLong(getDoctorId()));
        map.setPassword(Md5Utils.hash(param.getNewPassword()));
        doctorService.updateFsDoctor(map);
        return R.ok("修改成功");
    }

    @Login
    @ApiOperation("获取医生推广海报")
    @GetMapping("/getDoctorInquiryImg")
    public R getDoctorInquiryImg(HttpServletRequest request){
        try {
            String url=doctorService.getDoctorInquiryImg(Long.parseLong(getDoctorId()));
            return R.ok().put("url",url);
        } catch (Exception e){
            return R.error("操作异常");
        }
    }


    @Login
    @ApiOperation("获取医生")
    @GetMapping("/getDoctorDetails")
    public R getDoctorDetails(HttpServletRequest request){
        try {
            FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
            return R.ok().put("data",doctor);
        } catch (Exception e){
            return R.error("操作异常");
        }
    }

    @Login
    @ApiOperation("获取帐单记录")
    @GetMapping("/getDoctorBillList")
    public R getDoctorBillList(FsDoctorBillListSParam param)
    {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        param.setDoctorId(Long.parseLong(getDoctorId()));
        List<FsDoctorBillListSVO> list = doctorBillService.selectFsDoctorBillListSVO(param);
        PageInfo<FsDoctorBillListSVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("获取提现记录")
    @GetMapping("/getDoctorExtractList")
    public R getDoctorExtractList(FsDoctorExtractListSParam param)
    {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        param.setDoctorId(Long.parseLong(getDoctorId()));
        List<FsDoctorExtractListSVO> list = doctorExtractService.selectFsDoctorExtractListSVO(param);
        PageInfo<FsDoctorExtractListSVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }


    @Login
    @ApiOperation("提现")
    @PostMapping("/extract")
    @Transactional
    public R extract(@Validated @RequestBody FsDoctorDoExtractParam param, HttpServletRequest request){
        FsDoctor doctor=doctorService.selectFsDoctorByDoctorIdForUpdate(Long.parseLong(getDoctorId()));
        if(doctor.getStatus().equals(0)){
            return R.error("医生已禁用");
        }
        if(StringUtils.isEmpty(doctor.getExtractJson())){
            return R.error("请先设置提现方式");
        }
        //金额是否大于
        if(param.getMoney().compareTo(BigDecimal.ZERO)<1){
            return R.error("提现金额必须大于0");
        }
        if(param.getMoney().compareTo(doctor.getBalance())==1){
            return R.error("提现金额必须小于等于余额");
        }
        String code=redisCache.getCacheObject(doctor.getMobile());
        if(StringUtils.isEmpty(code)){
            return R.error("验证码已过期");
        }
        if(!code.equals(param.getCode())){
            return R.error("验证码不正确");
        }
        FsDoctor map=new FsDoctor();
        map.setDoctorId(doctor.getDoctorId());
        map.setBalance(doctor.getBalance().subtract(param.getMoney()));
        doctorService.updateFsDoctor(map);
        FsExtractDTO dto= JSONUtil.toBean(doctor.getExtractJson(),FsExtractDTO.class);
        FsDoctorExtract extract=new FsDoctorExtract();
        extract.setUserName(dto.getUserName());
        extract.setPhone(dto.getPhone());
        if(dto.getExtractType().equals(FsExtractTypeEnum.WEIXIN.getValue())) {
            extract.setWechat(dto.getWechat());
        }
        if(dto.getExtractType().equals(FsExtractTypeEnum.ALIPAY.getValue())) {
            extract.setAlipayAccount(dto.getAlipayAccount());
            extract.setAlipayName(dto.getAlipayName());
        }
        if(dto.getExtractType().equals(FsExtractTypeEnum.BANK.getValue())) {
            extract.setBankNo(dto.getBankNo());
            extract.setBankName(dto.getBankName());
            extract.setBankSubName(dto.getBankSubName());
        }
        extract.setExtractType(dto.getExtractType());
        extract.setDoctorId(doctor.getDoctorId());
        extract.setExtractPrice(param.getMoney());
        extract.setBalance(map.getBalance());
        extract.setStatus(0l);
        doctorExtractService.insertFsDoctorExtract(extract);
        //写入记录
        FsDoctorBill bill=new FsDoctorBill();
        bill.setDoctorId(doctor.getDoctorId());
        bill.setCreateTime(new Date());
        bill.setMoney(param.getMoney().multiply(new BigDecimal(-1)));
        bill.setBalance(map.getBalance());
        bill.setTitle("提现");
        bill.setBillType(2);
        bill.setBusinessId(extract.getExtractId().toString());
        doctorBillService.insertFsDoctorBill(bill);
        return R.ok("操作成功,等待后台审核...");

    }


    @Login
    @ApiOperation("修改提现配置")
    @PostMapping("/editExtract")
    public R editExtract(@Validated @RequestBody FsDoctorExtractEditParam param, HttpServletRequest request){
        FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
        String code = redisCache.getCacheObject(doctor.getMobile());
        if(StringUtils.isEmpty(code)){
            return R.error("验证码已过期");
        }
        if(!code.equals(param.getCode())){
            return R.error("验证码不正确");
        }
        FsDoctor map=new FsDoctor();
        map.setDoctorId(Long.parseLong(getDoctorId()));
        FsExtractDTO dto=JSONUtil.toBean(param.getExtractJson(),FsExtractDTO.class);
        map.setExtractJson(JSONUtil.toJsonStr(dto));
        if(doctorService.updateFsDoctor(map)>0){
            return R.ok();
        }
        else{
            return R.error();
        }
    }


    @Login
    @ApiOperation("发送短信验证")
    @PostMapping(value="/sendSmsCode")
    public R sendSmsCode(){
        FsDoctor doctor=doctorService.selectFsDoctorByDoctorId(Long.parseLong(getDoctorId()));
        //此手机号是否已存在REFIDS 如果存在，不能发送
        String captcha = redisCache.getCacheObject(doctor.getMobile());
        if(StringUtils.isNotEmpty(captcha)){
            return R.error("短信已发送,1分钟以内请勿重新发送验证码");
        }
        int code = (int) (Math.random() * (9999 - 1000 + 1)) + 1000;// 产生1000-9999的随机数
        return smsService.sendTSms(doctor.getMobile(),code+"");
    }


}
