package com.yihu.jw.base.endpoint.doctor;

import com.alibaba.fastjson.JSONObject;
import com.yihu.jw.base.endpoint.common.excel.AExcelReader;
import com.yihu.jw.base.endpoint.common.populationBatchImport.PopulationMsg;
import com.yihu.jw.base.service.doctor.BaseDoctorService;
import com.yihu.jw.base.service.doctor.excelImport.BaseDoctorExcelDO;
import com.yihu.jw.base.service.doctor.excelImport.BaseDoctorExcelDOReader;
import com.yihu.jw.base.service.org.OrgTreeService;
import com.yihu.jw.base.util.ConstantUtils;
import com.yihu.jw.base.util.JavaBeanUtils;
import com.yihu.jw.entity.hospital.consult.WlyyHospitalSysDictDO;
import com.yihu.jw.exception.business.ManageException;
import com.yihu.jw.hospital.dict.WlyyHospitalSysDictDao;
import com.yihu.jw.hospital.dict.service.BaseIncentiveDictService;
import com.yihu.jw.restmodel.base.doctor.BaseDoctorVO;
import com.yihu.jw.restmodel.web.Envelop;
import com.yihu.jw.restmodel.web.ListEnvelop;
import com.yihu.jw.restmodel.web.MixEnvelop;
import com.yihu.jw.restmodel.web.PageEnvelop;
import com.yihu.jw.restmodel.web.endpoint.EnvelopRestEndpoint;
import com.yihu.jw.rm.base.BaseRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import com.yihu.jw.entity.base.doctor.BaseDoctorDO;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 医生基础信息控制器
 *
 * @version <pre>
 * Author	Version		Date		Changes
 * litaohong 	1.0  		2018年08月31日 	Created
 *
 * </pre>
 * @since 1.
 */
@RestController
@RequestMapping(value = BaseRequestMapping.BaseDoctor.PREFIX)
@Api(value = "医生基础信息管理", description = "医生基础信息管理服务接口", tags = {"wlyy基础服务 - 医生基础信息管理服务接口"})
public class BaseDoctorEndpoint extends EnvelopRestEndpoint {

    @Autowired
    private BaseDoctorService baseDoctorService;

    @Autowired
    private OrgTreeService orgTreeService;

    @Autowired
    private BaseDoctorExcelDOReader doctorExcelDOReader;
    @Autowired
    private BaseIncentiveDictService baseIncentiveDictService;
    @Autowired
    private WlyyHospitalSysDictDao wlyyHospitalSysDictDao;

    @Value("${wechat.id}")
    private String wechatId;

    @PostMapping(value = BaseRequestMapping.BaseDoctor.CREATE)
    @ApiOperation(value = "新增医生")
    public Envelop create(
            @ApiParam(name = "jsonData", value = "Json数据", required = true)
            @RequestParam String jsonData) throws Exception {
        JSONObject jsonObject = null;
        String str = baseDoctorService.createDoctor(jsonData);
        jsonObject = JSONObject.parseObject(str);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getString("msg"));
    }

    @PostMapping(value = BaseRequestMapping.BaseDoctor.DELETE)
    @ApiOperation(value = "删除")
    public Envelop delete(
            @ApiParam(name = "ids", value = "id串，中间用,分隔", required = true)
            @RequestParam(value = "ids") String ids) {
        baseDoctorService.delete(ids.split(","));
        return success("删除成功");
    }

    @PostMapping(value = BaseRequestMapping.BaseDoctor.UPDATE)
    @ApiOperation(value = "更新医生")
    public Envelop update(
            @ApiParam(name = "jsonData", value = "Json数据", required = true)
            @RequestParam String jsonData) throws Exception {
        String str = baseDoctorService.updateDoctor(jsonData);
        JSONObject jsonObject = JSONObject.parseObject(str);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getString("response"));
    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.PAGE)
    @ApiOperation(value = "获取分页")
    public PageEnvelop<BaseDoctorVO> page(
            @ApiParam(name = "fields", value = "返回的字段，为空返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "过滤器，为空检索所有条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序，规则参见说明文档")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size) throws Exception {
        List<BaseDoctorDO> baseDoctors = baseDoctorService.search(fields, filters, sorts, page, size);
        List<WlyyHospitalSysDictDO> list = wlyyHospitalSysDictDao.findByDictName("doctor_level");
        for(BaseDoctorDO baseDoctorDO:baseDoctors){
            for (WlyyHospitalSysDictDO wlyyHospitalSysDictDO:list){
                if (baseDoctorDO.getLevel().equals(wlyyHospitalSysDictDO.getDictCode())){
                    baseDoctorDO.setLevelName(wlyyHospitalSysDictDO.getDictValue());
                }
            }
        }
        int count = (int) baseDoctorService.getCount(filters);
        return success(baseDoctors, count, page, size, BaseDoctorVO.class);
    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.LIST)
    @ApiOperation(value = "获取列表")
    public ListEnvelop<BaseDoctorVO> list(
            @ApiParam(name = "fields", value = "返回的字段，为空返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "过滤器，为空检索所有条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序，规则参见说明文档")
            @RequestParam(value = "sorts", required = false) String sorts) throws Exception {
        List<BaseDoctorDO> baseDoctors = baseDoctorService.search(fields, filters, sorts);
        return success(baseDoctors, BaseDoctorVO.class);
    }

    /**
     * 单个医生信息（基本信息 + 医院执业及角色信息）
     *
     * @param doctorId
     * @return
     * @throws Exception
     */
    @GetMapping(value = BaseRequestMapping.BaseDoctor.DOCINFO)
    @ApiOperation(value = "获取单个医生及其执业信息")
    public Envelop doctorHosplist(
            @ApiParam(name = "doctorId", value = "医生标识")
            @RequestParam(value = "doctorId", required = true) String doctorId) throws Exception {
        JSONObject jsonObject = baseDoctorService.getOneDoctorInfo(doctorId);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getJSONObject("msg"));
    }

    /**
     * 生效或失效单个医生
     *
     * @param doctorCode
     * @param del
     * @return
     * @throws Exception
     */
    @PostMapping(value = BaseRequestMapping.BaseDoctor.enableOrDis)
    @ApiOperation(value = "生效或失效单个医生")
    public Envelop enableOrDisableDoctor(
            @ApiParam(name = "doctorCode", value = "医生标识")
            @RequestParam(value = "doctorCode", required = true) String doctorCode,
            @ApiParam(name = "del", value = "生效或失效标识")
            @RequestParam(value = "del", required = true) String del) throws Exception {
        String str = baseDoctorService.enableOrDisableDoctor(doctorCode, del);
        JSONObject jsonObject = JSONObject.parseObject(str);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getString("response"));
    }

    /*
     * 医生信息（基本信息 + 医院执业信息）列表
     * @param name
     * @param idcard
     * @param orgCode
     * @param doctorStatus
     * @return
     * @throws Exception
     */
    @GetMapping(value = BaseRequestMapping.BaseDoctor.docFullInfo)
    @ApiOperation(value = "获取医生基础信息列表")
    public PageEnvelop getDoctorFullInfolist(
            @ApiParam(name = "nameOrIdcard", value = "医生姓名或医生身份证号")
            @RequestParam(value = "nameOrIdcard", required = false) String nameOrIdcard,
            @RequestParam(value = "orgCode", required = false) String orgCode,
            @ApiParam(name = "doctorStatus", value = "医生是否生效")
            @RequestParam(value = "doctorStatus", required = false) String doctorStatus,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size) throws Exception {
        JSONObject result = baseDoctorService.queryDoctorListFullInfo(nameOrIdcard,orgCode, doctorStatus,page,size,wechatId);
        return success(result.getJSONArray("msg"),result.getInteger("count"),page,size);
    }


    /**
     * 获取医生新增时选择的机构列表
     *
     * @param townCode
     * @return
     * @throws Exception
     */
    @GetMapping(value = BaseRequestMapping.BaseDoctor.getOrgListByTown)
    @ApiOperation(value = "根据区域获取机构列表")
    public Envelop getOrgListByTown(
            @ApiParam(name = "doctorCode", value = "townCode")
            @RequestParam(value = "doctorCode", required = false    ) String doctorCode,
            @ApiParam(name = "townCode", value = "townCode")
            @RequestParam(value = "townCode", required = true) String townCode) throws Exception {
        JSONObject jsonObject = baseDoctorService.getOrgListByTownAndDoctorCode(doctorCode,townCode);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getJSONArray("msg"));
    }

    /**
     * 获取医生 机构/职务 树形结构数据
     *
     * @param doctorCode
     * @return
     * @throws Exception
     */
    @GetMapping(value = BaseRequestMapping.BaseDoctor.docOrgDutyTreeInfo)
    @ApiOperation(value = "获取医生 机构/职务 树形结构数据")
    public Envelop getOrgDutyTree(
            @ApiParam(name = "doctorCode", value = "doctorCode")
            @RequestParam(value = "doctorCode", required = true) String doctorCode) throws Exception {
        JSONObject jsonObject = baseDoctorService.getDoctorDutyTree(doctorCode);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.get("msg"));
    }

    /**
     * 获取医生 机构/科室 树形结构数据
     *
     * @param doctorCode
     * @return
     * @throws Exception
     */
    @GetMapping(value = BaseRequestMapping.BaseDoctor.docOrgDeptTreeInfo)
    @ApiOperation(value = "获取医生 机构/科室 树形结构数据")
    public Envelop getOrgDeptTree(
            @ApiParam(name = "doctorCode", value = "doctorCode")
            @RequestParam(value = "doctorCode", required = true) String doctorCode) throws Exception {
        JSONObject jsonObject = baseDoctorService.getDoctorDeptTree(doctorCode);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getJSONArray("msg"));
    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.getDoctorListByDept)
    @ApiOperation(value = "获取某一科室下的医生列表")
    public Envelop getDoctorListByDept(
            @ApiParam(name = "deptCode", value = "科室代码", required = true)
            @RequestParam String deptCode) throws Exception {
        JSONObject jsonObject = baseDoctorService.getDoctorListByDept(deptCode);
        if (jsonObject.getString("response").equalsIgnoreCase(ConstantUtils.FAIL)) {
            return failed(jsonObject.getString("msg"));
        }
        return success(jsonObject.getJSONArray("msg"));
    }

    @PostMapping(value = BaseRequestMapping.BaseDoctor.DOCTOR_INFO_IMPORT)
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "基础医生信息列表导入")
    public Envelop importData(
            @ApiParam(name = "file", value = "文件", required = true)
            @RequestPart(value = "file") MultipartFile file,
            HttpServletRequest request) throws IOException, ManageException {
        try {
            request.setCharacterEncoding("UTF-8");
//            AExcelReader excelReader = new BaseDoctorExcelDOReader();
            InputStream inputStream = file.getInputStream();
            Workbook workbook = getWorkbook(inputStream,file.getOriginalFilename());
            doctorExcelDOReader.read(workbook);
            //验证未通过（暂无验证）
            List<BaseDoctorExcelDO> errorLs = doctorExcelDOReader.getErrorLs();
            List<BaseDoctorExcelDO> correctLs = doctorExcelDOReader.getCorrectLs();
            if(correctLs.size()>0){
                Map<String, Object> result = baseDoctorService.batchInsertDoctor(correctLs);
                result.put("errorLs", errorLs);
                return success("导入成功!", result);
            }
        }catch (Exception e){
            e.printStackTrace();
            return failed("导入异常,请检查导入文件格式" + e.getMessage());
        }
        return failed("导入失败");
    }
    @GetMapping("/exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {

        try {

            HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream("/home/医生模板信息.xls"));

// 根据页面index 获取sheet页

            HSSFSheet sheet = wb.getSheet("Sheet1");

            for (int i = 0; i < 2; i++) {

// 创建HSSFRow对象

                HSSFRow row = sheet.createRow(i + 1);

// 创建HSSFCell对象 设置单元格的值

                row.createCell(0).setCellValue("张三" + i);

                row.createCell(1).setCellValue("1");

                row.createCell(2).setCellValue("1");

                row.createCell(3).setCellValue("210503199507250333");
                row.createCell(4).setCellValue("18841409773");
                row.createCell(5).setCellValue("350211A1002/0000001/1303");
                row.createCell(6).setCellValue("1302");
                row.createCell(7).setCellValue("admin");
                row.createCell(8).setCellValue("1");

            }

// 输出Excel文件

            OutputStream output = response.getOutputStream();

            response.reset();

// 设置文件头

            /*response.setHeader("Content-Disposition",

                    "attchement;filename=" + new String("人员信息.xls".getBytes("gb2312"), "ISO8859-1"));

            response.setContentType("application/msexcel");*/
            response.setCharacterEncoding("utf-8");
            response.setContentType("octets/stream");
            response.setHeader("Content-Disposition", "attachment; filename="
                    + new String( "医生模板信息".getBytes("gb2312"), "ISO8859-1" )+".xls");

            wb.write(output);

            wb.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }
    /**
     * 判断文件格式
     * @param in
     * @param fileName
     * @return
     */
    private static Workbook getWorkbook(InputStream in, String fileName) throws Exception {

        Workbook book = null;
        String filetype = fileName.substring(fileName.lastIndexOf("."));

        if(".xls".equals(filetype)) {
            book = new HSSFWorkbook(in);
        } else if (".xlsx".equals(filetype)) {
            book = new XSSFWorkbook(in);
        } else {
            throw new Exception("请上传excel文件！");
        }

        return book;
    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.findIncentive)
    @ApiOperation(value = "查询激励勋章字典")
    public MixEnvelop findIncentive(
            @ApiParam(name = "name", value = "名称", required = true)
            @RequestParam(value = "name", required = false)String name,
            @ApiParam(name = "page", value = "", required = true)
            @RequestParam(value = "page", required = false)Integer page,
            @ApiParam(name = "pageSize", value = "", required = true)
            @RequestParam(value = "pageSize", required = false) Integer pageSize) throws Exception {
        return baseIncentiveDictService.findByName(name,page,pageSize);
    }
    @GetMapping(value = BaseRequestMapping.BaseDoctor.findIncentiveById)
    @ApiOperation(value = "查询激励勋章字典单条")
    public Envelop findIncentiveById(
            @ApiParam(name = "id", value = "", required = true)
            @RequestParam(value = "id", required = false)String id) throws Exception {
        return success(baseIncentiveDictService.findOneById(id));
    }
    @GetMapping(value = BaseRequestMapping.BaseDoctor.deleteIncentiveById)
    @ApiOperation(value = "删除激励勋章字典")
    public Envelop deleteIncentiveById(
            @ApiParam(name = "id", value = "", required = true)
            @RequestParam(value = "id", required = false)String id) throws Exception {
        return success(baseIncentiveDictService.deleteOne(id));
    }
    @GetMapping(value = BaseRequestMapping.BaseDoctor.saveIncentiveById)
    @ApiOperation(value = "保存激励勋章字典")
    public Envelop saveIncentiveById(
            @ApiParam(name = "id", value = "", required = false)
            @RequestParam(value = "id", required = false)String id,
            @ApiParam(name = "code", value = "", required = false)
            @RequestParam(value = "code", required = false)String code,
            @ApiParam(name = "name", value = "", required = false)
            @RequestParam(value = "name", required = false)String name,
            @ApiParam(name = "img", value = "", required = false)
            @RequestParam(value = "img", required = false)String img,
            @ApiParam(name = "status", value = "", required = false)
            @RequestParam(value = "status", required = false)String status) throws Exception {
        return success(baseIncentiveDictService.saveIncentive(id,code,name,img,status));
    }


    @GetMapping(value = BaseRequestMapping.BaseDoctor.saveDoctorIncentive)
    @ApiOperation(value = "给医生勋章")
    public Envelop saveDoctorIncentive(
            @ApiParam(name = "doctor", value = "", required = false)
            @RequestParam(value = "doctor", required = false)String doctor,
            @ApiParam(name = "incentiveIds", value = "", required = false)
            @RequestParam(value = "incentiveIds", required = false)String incentiveIds) {
        try {
            return success(baseDoctorService.saveDoctorIncentive(doctor,incentiveIds));
        } catch (Exception e) {
            e.printStackTrace();
            return failed(e.getMessage());
        }
    }


    @GetMapping(value = BaseRequestMapping.BaseDoctor.findDoctorIncentive)
    @ApiOperation(value = "查询医生勋章")
    public MixEnvelop findDoctorIncentive(
            @ApiParam(name = "doctor", value = "", required = false)
            @RequestParam(value = "doctor", required = false)String doctor,
            @ApiParam(name = "name", value = "", required = false)
            @RequestParam(value = "name", required = false)String name,
            @ApiParam(name = "page", value = "", required = false)
            @RequestParam(value = "page", required = false)Integer page,
            @ApiParam(name = "pageSize", value = "", required = false)
            @RequestParam(value = "pageSize", required = false)Integer pageSize) {


        return baseDoctorService.findIncentiveByDoctor(doctor,name,page,pageSize);

    }


    @GetMapping(value = BaseRequestMapping.BaseDoctor.findDoctorOtherIncentive)
    @ApiOperation(value = "查询医生没有的勋章")
    public ListEnvelop findDoctorOtherIncentive(
            @ApiParam(name = "doctor", value = "", required = false)
            @RequestParam(value = "doctor", required = false)String doctor) {
        return success(baseDoctorService.findIncentiveDict(doctor));

    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.removeIncentive)
    @ApiOperation(value = "删除医生勋章")
    public Envelop removeIncentive(
            @ApiParam(name = "doctor", value = "", required = false)
            @RequestParam(value = "doctor", required = false)String doctor,
            @ApiParam(name = "incentiveId", value = "", required = false)
            @RequestParam(value = "incentiveId", required = false)String incentiveId) {
        return success(baseDoctorService.removeDoctorIncentive(doctor,incentiveId));

    }

    @GetMapping(value = BaseRequestMapping.BaseDoctor.resetDoctorPwd)
    @ApiOperation(value = "医生重置密码")
    public Envelop resetDoctorPwd(
            @ApiParam(name = "doctor", value = "", required = false)
            @RequestParam(value = "doctor", required = true)String doctor) {
        try {
            return success(baseDoctorService.resetDoctorPwd(doctor));
        }catch (Exception e){
           return failedException(e);
        }
    }
}
