package com.ywt.outpatient.controllers.taihe;

import com.ywt.biz.common.util.Checker;
import com.ywt.biz.common.util.DateUtil;
import com.ywt.gapi.Result;
import com.ywt.gapi.ResultCode;
import com.ywt.gapi.doctor.*;
import com.ywt.gapi.nfyy.NfyyService;
import com.ywt.gapi.nfyy.TimeInfo;
import com.ywt.gapi.system.GetHospitalRequest;
import com.ywt.gapi.system.GetHospitalResponse;
import com.ywt.gapi.system.SystemService;
import com.ywt.gapi.third.taihe.*;
import com.ywt.outpatient.core.BaseResponse;
import com.ywt.outpatient.core.annotations.UserLogin;
import com.ywt.outpatient.core.utils.BizUtil;
import com.ywt.outpatient.core.Constant;
import com.ywt.outpatient.domain.models.enums.DatePeriodEnum;
import com.ywt.outpatient.service.rpc.OrderService;
import com.ywt.outpatient.service.rpc.UserService;
import com.ywt.outpatient.service.web.taihe.TaiheSystemService;
import com.ywt.outpatient.service.web.taihe.TaiheUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 患者端预约挂号(将太和和南方医院的进行合并)
 */
@RestController("/taihe/main/register")
@RequestMapping({"/taihe/main/register"})
public class MainRegisterController {
    private static Logger logger = LoggerFactory.getLogger(MainRegisterController.class);

    @DubboReference
    private TaiheService taiheServiceBlockingStub;

    @DubboReference
    private OrderService orderServiceBlockingStub;

    @DubboReference
    private UserService userServiceBlockingStub;

    @Autowired
    private TaiheSystemService systemService;

    @Autowired
    private TaiheUserService userService;

    @DubboReference
    private DoctorService doctorServiceBlockingStub;

    @DubboReference
    private NfyyService nfyyServiceBlockingStub;

    @DubboReference
    private SystemService systemServiceBlockingStub;

    /**
     * 得到排班记录(根据医生ID查找医生的排班)
     *
     * @return
     */
    @UserLogin(need = false)
    @RequestMapping({"/getScheduleList"})
    public @ResponseBody
    BaseResponse getScheduleList(@RequestParam(name = "doctorId") int doctorId) {
        BaseResponse response = new BaseResponse();

        try {
            //得到医生信息
            GetDoctorHisCodeRequest getDoctorHisCodeRequest = GetDoctorHisCodeRequest.newBuilder()
                    .setDoctorId(doctorId)
                    .build();
            GetDoctorHisCodeResponse getDoctorHisCodeResponse = doctorServiceBlockingStub.getDoctorHisCode(getDoctorHisCodeRequest);
            if (getDoctorHisCodeResponse.getResult().getCode() != ResultCode.SUCCEED){
                return response.failed(BaseResponse.PARAMETER_ERROR, getDoctorHisCodeResponse.getResult().getInfo());
            }

            DoctorHisCode doctorHisCode = getDoctorHisCodeResponse.getDoctorHisCode();
            if (Checker.isNone(doctorHisCode)){
                return response.failed(BaseResponse.PARAMETER_ERROR, "暂无排班信息");
            }
            int hospitalId = doctorHisCode.getHospitalId();
            String doctorCode = doctorHisCode.getDoctorCode();
            String deptCode = doctorHisCode.getDeptCode();
            int source = 0;     // 1-南方医院，2-太和医院，3-医生加诊排班

            //hospitalId ,1-南方医院，12-太和医院
            if (hospitalId == Constant.NFYY_HOSPITAL_ID){
                source = 1;
                response = nfyyScheduleList(doctorCode, deptCode, hospitalId, doctorId);
//                Map<String, Object> data = (Map<String, Object>)response.getData();
//                Object obj = data.get("list");
//                if (Checker.isNone(obj)){
//                    source = 3;
//                    response = addRegSchduleList(doctorId, hospitalId);
//                }
            }
            else if (hospitalId == Constant.NFYYBYFY_HOSPITAL_ID || hospitalId == Constant.TAIHE_HOSPITAL_ID){
                source = 2;
                response = taiheScheduleList(doctorCode, deptCode, hospitalId, doctorId);
//                Map<String, Object> data = (Map<String, Object>)response.getData();
//                Object obj = data.get("list");
//                if (Checker.isNone(obj)){
//                    source = 3;
//                    response = addRegSchduleList(doctorId, hospitalId);
//                }
            }
            else {
                source = 3;
                response = addRegSchduleList(doctorId, hospitalId);    //其他
            }

            Map<String, Object> data = (Map<String, Object>)response.getData();
            data.put("source",source);
            return response.succeed("处理成功");

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getScheduleList(){}", e.getMessage());
            return response.failed(BaseResponse.APP_EXCEPTION, Constant.ERROR_PROMPT);
        }
    }

    /**
     * 得到南方医院的挂号
     *
     * @param doctorCode
     * @param deptCode
     * @return
     */
    public BaseResponse nfyyScheduleList(String doctorCode, String deptCode, int hospitalId, int doctorId){
        BaseResponse response = new BaseResponse();

        if (hospitalId != 1) {
            return response.failed(BaseResponse.PARAMETER_ERROR, "医院不存在");
        }

        List<Map<String, Object>> dataList = new LinkedList<>();

        //取医生8天排班的分时信息
        int[] periods = {DatePeriodEnum.MORNING.getValue(), DatePeriodEnum.AFTERNOON.getValue()};
        Calendar calendar = Calendar.getInstance();

        for (int offset = 0; offset < 5; offset++) {
            if (offset > 0) {
                calendar.add(Calendar.DATE, 1);
            }
            String strDate = DateUtil.formatDate(calendar.getTime(), "yyyy-MM-dd");

            for (int p : periods) {
                Map<String, Object> map = getNfyyScheduleTimeInfoResponse(deptCode, doctorCode, strDate, p);

                if (map != null) {
                    dataList.add(map);
                }
            }
        }

        String deptName = "";
        String doctorName = "";
        String avatar = "";
        String doctorTitle = "";
        String doctorSpec = "";
        double fee = 0d;
        double regFee = 0d;
        double treatFee = 0d;

        if (dataList.size() > 0) {
            Map<String, Object> map = dataList.get(0);
            String strDate = map.get("serviceDate").toString();
            com.ywt.gapi.nfyy.GetScheduleListRequest getScheduleListRequest = com.ywt.gapi.nfyy.GetScheduleListRequest.newBuilder()
                    .setDepartmentCode(deptCode+"")
                    .setEndDate(strDate)
                    .setStartDate(strDate)
                    .setDoctorCode(doctorCode+"")
                    .setRBASSessionCode("")
                    .build();
            com.ywt.gapi.nfyy.GetScheduleListResponse getScheduleListResponse = nfyyServiceBlockingStub.getScheduleList(getScheduleListRequest);

            if (getScheduleListResponse.getCode() == ResultCode.SUCCEED_VALUE) {
                List<com.ywt.gapi.nfyy.Schedule> scheduleList = getScheduleListResponse.getSchedulesList();
                if (scheduleList.size() > 0) {
                    com.ywt.gapi.nfyy.Schedule schedule = scheduleList.get(0);
                    deptName = schedule.getDepartmentName();
                    doctorName = schedule.getDoctorName();
                    avatar = schedule.getImageUrl();
                    doctorTitle = schedule.getDoctorTitle();
                    doctorSpec = schedule.getDoctorSpec();
                    fee = Checker.parseDouble(schedule.getFee());
                    regFee = Checker.parseDouble(schedule.getRegFee());
                    treatFee = Checker.parseDouble(schedule.getCheckupFee());
                }
            }
        }
        else{
            GetDoctorRequest req = GetDoctorRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorResponse resp = doctorServiceBlockingStub.getDoctor(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                DoctorInfo info = resp.getDoctorInfo();
                deptName = info.getDept();
                doctorName = info.getName();
                avatar = info.getAvatar();
                doctorTitle = info.getTitle();
                doctorSpec = info.getSpecialty();
            }
        }

        GetHospitalRequest getHospitalByIdRequest = GetHospitalRequest.newBuilder()
                .setHospitalId(hospitalId)
                .build();
        GetHospitalResponse getHospitalResponse = systemServiceBlockingStub.getHospital(getHospitalByIdRequest);
        String address = "";
        if (getHospitalResponse.getResult().getCode() == ResultCode.SUCCEED){
            address = getHospitalResponse.getHospital().getAddress();
        }

        Map<String, Object> data = new HashMap<>();
        data.put("list", dataList);
        data.put("hospitalName", "南方医科大学南方医院");
        data.put("hospitalAddress", address);
        data.put("hospitalId", hospitalId);
        data.put("deptCode", deptCode);
        data.put("deptName", deptName);
        data.put("doctorCode", doctorCode);
        data.put("doctorName", doctorName);
        data.put("avatar", avatar);
        data.put("doctorTitle", doctorTitle);
        data.put("doctorSpec", doctorSpec);
        data.put("fee", fee);
        data.put("regFee", regFee);
        data.put("treatFee", treatFee);

        return response.succeed("处理成功", data);
    };

    /**
     * 得到南方医院的号（日期，时间段）
     * @param deptCode
     * @param doctorCode
     * @param serviceDate
     * @param period
     * @return
     */
    private Map<String, Object> getNfyyScheduleTimeInfoResponse(String deptCode, String doctorCode, String serviceDate, int period) {
        List<Map<String, Object>> lst = new LinkedList<>();

        String RBASSessionCode = period == DatePeriodEnum.AFTERNOON.getValue() ? "X" : "S";
        com.ywt.gapi.nfyy.GetScheduleTimeInfoRequest getScheduleTimeInfoRequest = com.ywt.gapi.nfyy.GetScheduleTimeInfoRequest.newBuilder()
                .setDepartmentCode(deptCode)
                .setDoctorCode(doctorCode)
                .setServiceDate(serviceDate)
                .setRBASSessionCode(RBASSessionCode)
                .build();
        com.ywt.gapi.nfyy.GetScheduleTimeInfoResponse getScheduleTimeInfoResponse = nfyyServiceBlockingStub.getScheduleTimeInfo(getScheduleTimeInfoRequest);

        if (getScheduleTimeInfoResponse.getCode() == ResultCode.SUCCEED_VALUE) {
            List<com.ywt.gapi.nfyy.ScheduleTimeInfo> scheduleTimeInfoList = getScheduleTimeInfoResponse.getScheduleTimeInfosList();

            for (com.ywt.gapi.nfyy.ScheduleTimeInfo scheduleTimeInfo : scheduleTimeInfoList) {
                String availableFlag = "N";

                for (TimeInfo timeInfo : scheduleTimeInfo.getTimeInfosList()) {
                    availableFlag = timeInfo.getAvailableFlag();
                }

                Map<String, Object> map = new HashMap<>();
                map.put("scheduleItemCode", scheduleTimeInfo.getScheduleItemCode());
                map.put("startTime", scheduleTimeInfo.getStartTime());
                map.put("endTime", scheduleTimeInfo.getEndTime());
                map.put("availableTotalNum", scheduleTimeInfo.getAvailableTotalNum());
                map.put("availableLeftNum", scheduleTimeInfo.getAvailableLeftNum());
                map.put("availableFlag", availableFlag);

                lst.add(map);
            }
        }

        if (lst.size() > 0) {
            Map<String, Object> dateMap = new HashMap<>();
            dateMap.put("serviceDate", serviceDate);
            dateMap.put("period", period);
            dateMap.put("datePeriod", DatePeriodEnum.valueOf(period).getDisplayName());
            dateMap.put("schedule", lst);

            return dateMap;
        }

        return null;
    }


    /**
     * 得到太和医生分时排班信息
     *
     * @return
     */
    public @ResponseBody
    BaseResponse taiheScheduleList(String doctorCode, String deptCode, int hospitalId, int doctorId) {
        BaseResponse response = new BaseResponse();

//        if (hospitalId != 12) {
//            return response.failed(BaseResponse.PARAMETER_ERROR, "医院不存在");
//        }

        List<Map<String, Object>> dataList = new LinkedList<>();

        //取医生8天排班的分时信息
        int[] periods = {DatePeriodEnum.MORNING.getValue(), DatePeriodEnum.AFTERNOON.getValue(), DatePeriodEnum.NIGHT.getValue()};
        Calendar calendar = Calendar.getInstance();

        for (int offset = 0; offset < 5; offset++) {
            if (offset > 0) {
                calendar.add(Calendar.DATE, 1);
            }
            String strDate = DateUtil.formatDate(calendar.getTime(), "yyyy-MM-dd");
            for (int p : periods) {
                Map<String, Object> map = getTaiheScheduleTimeInfoResponse(deptCode+"", doctorCode+"", strDate, p);

                if (map != null) {
                    dataList.add(map);
                }
            }
        }

        String deptName = "";
        String doctorName = "";
        String avatar = "";
        String doctorTitle = "";
        String doctorSpec = "";
        int fee = 0;
        int regFee = 0;
        int treatFee = 0;

        if (dataList.size() > 0) {
            Map<String, Object> map = dataList.get(0);
            String strDate = map.get("serviceDate").toString();
            GetScheduleListRequest getScheduleListRequest = GetScheduleListRequest.newBuilder()
                    .setDeptCode(deptCode)
                    .setDoctorCode(doctorCode)
                    .setServiceDate(strDate)
                    .setHospitalId(BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped()))
                    .build();
            GetScheduleListResponse getScheduleListResponse = taiheServiceBlockingStub.getScheduleList(getScheduleListRequest);

            if (getScheduleListResponse.getCode() == ResultCode.SUCCEED_VALUE) {
                List<Schedule> scheduleList = getScheduleListResponse.getSchedulesList();
                if (scheduleList.size() > 0) {
                    Schedule schedule = scheduleList.get(0);
                    deptName = schedule.getDeptName();
                    doctorName = schedule.getDoctorName();
                    avatar = schedule.getAvatar();
                    doctorTitle = schedule.getDoctorTitle();
                    doctorSpec = schedule.getDoctorSpec();
                    fee =  schedule.getFee();
                    regFee =  schedule.getRegFee();
                    treatFee =  schedule.getCheckupFee();
                }
            }
        }else{
            GetDoctorRequest req = GetDoctorRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorResponse resp = doctorServiceBlockingStub.getDoctor(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                DoctorInfo info = resp.getDoctorInfo();
                deptName = info.getDept();
                doctorName = info.getName();
                avatar = info.getAvatar();
                doctorTitle = info.getTitle();
                doctorSpec = info.getSpecialty();
            }
        }

        GetHospitalRequest getHospitalByIdRequest = GetHospitalRequest.newBuilder()
                .setHospitalId(hospitalId)
                .build();
        GetHospitalResponse getHospitalResponse = systemServiceBlockingStub.getHospital(getHospitalByIdRequest);
        String address = "";
        if (getHospitalResponse.getResult().getCode() == ResultCode.SUCCEED){
            address = getHospitalResponse.getHospital().getAddress();
        }


        Map<String, Object> data = new HashMap<>();
        data.put("list", dataList);
        data.put("hospitalName", BizUtil.getHospitalNameByIdSimply(hospitalId));
        data.put("hospitalAddress", address);
        data.put("hospitalId", hospitalId);
        data.put("deptCode", deptCode);
        data.put("deptName", deptName);
        data.put("doctorCode", doctorCode);
        data.put("doctorName", doctorName);
        data.put("avatar", !Checker.isNone(avatar) ? avatar : Constant.DOCTOR_AVATAR_URL);
        data.put("doctorTitle", doctorTitle);
        data.put("doctorSpec", doctorSpec);
        data.put("fee", fee);
        data.put("regFee", regFee);
        data.put("treatFee", treatFee);
        data.put("doctorId", doctorId);        //医生ID

        return response.succeed("处理成功", data);
    }

    /**
     * 得到太和医院的分时排班信息
     *
     * @param deptCode
     * @param doctorCode
     * @param serviceDate
     * @param period
     * @return
     */
    private Map<String, Object> getTaiheScheduleTimeInfoResponse(String deptCode, String doctorCode, String serviceDate, int period) {
        List<Map<String, Object>> lst = new LinkedList<>();

        GetScheduleTimeInfoRequest getScheduleTimeInfoRequest = GetScheduleTimeInfoRequest.newBuilder()
                .setDeptCode(deptCode)
                .setDoctorCode(doctorCode)
                .setServiceDate(serviceDate)
                .setDatePeriod(period)
                .setHospitalId(BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped()))
                .build();
        GetScheduleTimeInfoResponse getScheduleTimeInfoResponse = taiheServiceBlockingStub.getScheduleTimeInfo(getScheduleTimeInfoRequest);

        if (getScheduleTimeInfoResponse.getCode() == ResultCode.SUCCEED_VALUE) {
            List<ScheduleTimeInfo> scheduleTimeInfoList = getScheduleTimeInfoResponse.getScheduleTimeInfosList();

            for (ScheduleTimeInfo scheduleTimeInfo : scheduleTimeInfoList) {

                Map<String, Object> map = new HashMap<>();
                map.put("scheduleItemCode", scheduleTimeInfo.getScheduleItemCode());
                map.put("startTime", scheduleTimeInfo.getStartTime());
                map.put("endTime", scheduleTimeInfo.getEndTime());
                map.put("availableTotalNum", scheduleTimeInfo.getAvailableTotalNum());
                map.put("availableLeftNum", scheduleTimeInfo.getAvailableLeftNum());
                map.put("availableFlag", scheduleTimeInfo.getAvailableFlag());

                lst.add(map);
            }
        }

        if (lst.size() > 0) {
            Map<String, Object> dateMap = new HashMap<>();
            dateMap.put("serviceDate", serviceDate);
            dateMap.put("period", period);
            dateMap.put("datePeriod", DatePeriodEnum.valueOf(period).getDisplayName());
            dateMap.put("schedule", lst);

            return dateMap;
        }

        return null;
    }


    /**
     * 得到医生加诊排班的信息
     *
     * @param doctorId
     * @return
     */
    public BaseResponse addRegSchduleList(int doctorId, int hospitalId) {
        BaseResponse response = new BaseResponse();
        try {

            GetDoctorScheduleRequest req = GetDoctorScheduleRequest.newBuilder().setDoctorId(doctorId).build();
            GetDoctorScheduleResponse resp = doctorServiceBlockingStub.getDoctorSchedule(req);
            Result result = resp.getResult();

            if (result.getCode() == ResultCode.SUCCEED) {
                List<DoctorSchedule> aList = resp.getDoctorScheduleList();
                Map<String, Object> data = new HashMap<>();

                List lst = new ArrayList();
//                if (!Checker.isNone(aList)) {
//
//                    String dayDate = new SimpleDateFormat("yyyy-M-d").format(new Date());   //当前日期
//                    String morning = dayDate + PointInTimeEnum.Morning.getDisplayName();
//                    Date morningDate = DateUtil.parseDate(morning, "yyyy-M-d HH:mm:ss");    //表示上午
//
//                    String afternoon = dayDate + PointInTimeEnum.Afternoon.getDisplayName();
//                    Date afternoonDate = DateUtil.parseDate(afternoon, "yyyy-M-d HH:mm:ss");    //表示下午
//
//                    String night = dayDate + PointInTimeEnum.Night.getDisplayName();
//                    Date nightDate = DateUtil.parseDate(night, "yyyy-M-d HH:mm:ss");         //表示晚上
//
//                    String dateTime = new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(new Date());           // 表示今天
//                    Date dateTimeDate = DateUtil.parseDate(dateTime, "yyyy-MM-dd 00:00:00");

//                    Date nowDate = new Date();      //  现在的时间

//                    for (DoctorSchedule a : aList) {
//
//                        // 这里需要对日期进行判断，时间过了的时间段，不再进行显示
//                        Date scheduleDate = DateUtil.convertTimestampToDate(a.getClinicTime());    // 表示预约排班的日期
//
//                        int p_morning = a.getMorning();
//                        int p_afternoon = a.getAfternoon();
//
//                        //先对现在的时间进行判断,排班时间必须要大于等于 现在的时间
//                        if (dateTimeDate.after(scheduleDate))
//                            continue;
//
//                        if (dateTimeDate.equals(scheduleDate)) {                 //表示日期相等
//                            if (nowDate.after(nightDate)) {  //如果现在的时间大于晚上的时间，则不能选当天的
//                                continue;
//                            } else if (nowDate.after(afternoonDate)) { //当前时间为当天下午7点后，晚上10点之前，则上午，下午的排班都不行
//                                if (p_morning == 1 || p_afternoon == 1) {
//                                    continue;
//                                }
//                            } else if (nowDate.after(morningDate)) { //当前时间大于12点，则上午不可选
//                                if (p_morning == 1) {
//                                    continue;
//                                }
//                            }
//                        }
//
//                        if (a.getClinicTime() != -1 && !(a.getMorning() == 0 && a.getAfternoon() == 0 && a.getNight() == 0)) {
//                            Map map = new HashMap();
//                            //日期格式化
//                            String clinicTime = DateUtil.convertTimestampToDateString(a.getClinicTime(), "yyyy-MM-dd");
//
//                            if (a.getMorning() == 1) {
//                                map.put("clinicDate", clinicTime + " 上午 ");
//                            } else if (a.getAfternoon() == 1) {
//                                map.put("clinicDate", clinicTime + " 下午 ");
//                            } else if (a.getNight() == 1) {
//                                map.put("clinicDate", clinicTime + " 晚上 ");
//                            }
//                            map.put("scheduleId", a.getScheduleId());
//                            map.put("configId", a.getConfigId());
//                            map.put("province", a.getProvince());
//                            map.put("city", a.getCity());
//                            map.put("area", a.getArea());
//                            map.put("address", a.getAddress());
//                            map.put("remark", a.getRemark());
//                            map.put("amount", Double.parseDouble(a.getAmount() / 100.0 + ""));
//                            map.put("amountStr", String.format("¥%.2f", a.getAmount() / 100d));
//                            lst.add(map);
//                        }
//                    }
//                }
                data.put("list", lst);

                //
                GetDoctorRequest request = GetDoctorRequest.newBuilder()
                        .setDoctorId(doctorId).build();
                GetDoctorResponse doctoResp = doctorServiceBlockingStub.getDoctor(request);
                if (doctoResp.getResult().getCode() == ResultCode.SUCCEED) {
                    DoctorInfo info = doctoResp.getDoctorInfo();
                    data.put("doctorName", info.getName());
                    data.put("avatar", info.getAvatar());
                    data.put("doctorSpec", info.getSpecialty());
                    data.put("briefIntro", info.getBriefIntro());
                    data.put("dept", info.getDept());
                    data.put("hospitalName", info.getHospital());
                    data.put("hospitalId", hospitalId);
                    data.put("doctorTitle", info.getTitle());
                }
                return response.succeed("处理成功", data);
            }
            return response.failed(BaseResponse.APP_ERROR, result.getInfo());
        } catch (Exception e) {
            logger.error("getAllAddress({}): {}", e.getMessage(), e);
            return response.error();
        }
    }

}
