package com.yizhi.application.enroll.controller;

import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.yizhi.core.application.enums.InternationalEnums;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.enroll.application.feign.EnrollFeignClient;
import com.yizhi.enroll.application.vo.*;
import com.yizhi.enroll.application.vo.domain.Enroll;
import com.yizhi.enroll.application.vo.domain.EnrollRecord;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.system.remote.OrganizationClient;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.training.application.feign.TrainingProjectClient;
import com.yizhi.training.application.vo.domain.TrainingProjectVo;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.BizResponse;
import com.yizhi.util.application.domain.Response;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.plugins.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * <p>
 * 报名主体表，入口在培训项目 前端控制器 管理端
 * </p>
 *
 * @author bob123
 * @since 2018-03-07
 */
@Api(tags = "报名主体表管理端接口", description = "报名主体表管理端接口")
@RestController
@RequestMapping("/manage/enroll")
public class EnrollManageController {

    private static final Logger LOG = LoggerFactory.getLogger(EnrollManageController.class);

    @Autowired
    private EnrollFeignClient enrollFeignClient;

    @Autowired
    private AccountClient accountClient;

    @Autowired
    private OrganizationClient organizationClient;

    @Autowired
    private TrainingProjectClient trainingProjectClient;

    @Autowired
    private EnrollerListExport enrollerListExport;

    @Value("${pc.host.url}")
    String pcHostUrl;

    @ApiOperation(value = "新增报名信息", notes = "新增报名信息")
    @PostMapping("/insert")
    @ApiImplicitParams({@ApiImplicitParam(name = "trainingProjectId", value = "培训项目ID"),
            @ApiImplicitParam(name = "startTime", value = "报名开始时间"),
            @ApiImplicitParam(name = "endTime", value = "报名结束时间"),
            @ApiImplicitParam(name = "needAudit", value = "是否需要审核"),
            @ApiImplicitParam(name = "personLimitNum", value = "报名人数限制（0：不限制）默认0"),
            @ApiImplicitParam(name = "notice", value = "报名须知"),})
    public BizResponse<String> insert(@RequestBody EnrollListVO vo) {
        try {
            if (vo.getTrainingProjectId() == null || vo.getStartTime() == null || vo.getEndTime() == null) {
                return BizResponse.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
            }
            Enroll enroll = new Enroll();
            enroll.setTrainingProjectId(Long.valueOf(vo.getTrainingProjectId()));
            enroll.setStartTime(vo.getStartTime());
            enroll.setEndTime(vo.getEndTime());
            enroll.setNeedAudit(vo.getNeedAudit());
            enroll.setPersonLimitNum(vo.getPersonLimitNum());
            enroll.setNotice(vo.getNotice());
            enroll.setEnablePay(vo.getEnablePay());
            enroll.setActualPrice(vo.getActualPrice());
            enroll.setOriginalPrice(vo.getOriginalPrice());
            return enrollFeignClient.insertEnrollV2(enroll);
        } catch (Exception e) {
            LOG.error("新增报名信息异常:" + e);
            return BizResponse.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "编辑报名信息", notes = "编辑报名信息")
    @PostMapping("/update")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "报名ID"),
            @ApiImplicitParam(name = "trainingProjectId", value = "培训项目ID"),
            @ApiImplicitParam(name = "startTime", value = "报名开始时间"),
            @ApiImplicitParam(name = "endTime", value = "报名结束时间"),
            @ApiImplicitParam(name = "needAudit", value = "是否需要审核"),
            @ApiImplicitParam(name = "personLimitNum", value = "报名人数限制（0：不限制）默认0"),
            @ApiImplicitParam(name = "notice", value = "报名须知"),})
    public BizResponse<String> update(@RequestBody EnrollListVO vo) {
        try {
            if (vo.getId() == null || vo.getTrainingProjectId() == null || vo.getStartTime() == null
                    || vo.getEndTime() == null) {
                return BizResponse.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
            }
            Enroll enroll = new Enroll();
            enroll.setId(vo.getId());
            enroll.setTrainingProjectId(vo.getTrainingProjectId());
            enroll.setStartTime(vo.getStartTime());
            enroll.setEndTime(vo.getEndTime());
            enroll.setNeedAudit(vo.getNeedAudit());
            enroll.setPersonLimitNum(vo.getPersonLimitNum());
            enroll.setNotice(vo.getNotice());
            enroll.setOriginalPrice(vo.getOriginalPrice());
            enroll.setActualPrice(vo.getActualPrice());
            enroll.setEnablePay(vo.getEnablePay());
            Long aLong = enrollFeignClient.updateEnroll(enroll);
            if (null == aLong || aLong.compareTo(0L) < 0){
                LOG.error("报名修改失败;入参 = {}", JSONObject.toJSONString(vo));
                return BizResponse.fail(InternationalEnums.INTERNATIONALIZATIONWORDCONTROLLER4.getCode());
            }
            return BizResponse.ok(String.valueOf(aLong));
        } catch (Exception e) {
            LOG.error("编辑报名信息:" + e);
            return BizResponse.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "查询报名信息(单个)", notes = "查询报名信息(单个)")
    @GetMapping("/view")
    public Response<Enroll> view(@ApiParam(name = "trainingProjectId", value = "审核状态") Long trainingProjectId) {
        try {
            if (trainingProjectId == null) {
                return Response.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
            }
            Enroll enroller = enrollFeignClient.selectByProjectId(trainingProjectId);
            return Response.ok(enroller);
        } catch (Exception e) {
            LOG.error("添加学员报名信息:" + e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }


    @PostMapping("/record/project")
    public Response<ReturnEnrollVO> selectEnrollByProjectId(@RequestBody ProjectAccountVO vo) {
        try {
            if (vo.getAccountId() == null || vo.getProjectId() == null) {
                return Response.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
            }
            ReturnEnrollVO enroller = enrollFeignClient.selectEnrollByProjectId(vo);
            return Response.ok(enroller);
        } catch (Exception e) {
            LOG.error("添加学员报名信息:" + e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "报名审核", notes = "报名审核")
    @PostMapping("/audit")
    @ApiImplicitParams({@ApiImplicitParam(name = "trainingProjectId", value = "培训项目ID"),
            @ApiImplicitParam(name = "accountId", value = "学员id"),
            @ApiImplicitParam(name = "auditStatus", value = "审核状态")})
    public Response<Boolean> audit(@RequestBody AuditVO vo) {
        if (vo.getAccountId() == null || vo.getAccountId() == null) {
            return Response.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
        }
        return Response.ok(enrollFeignClient.auditEnroll(vo));
    }

    @ApiOperation(value = "导出已报名用户", notes = "导出已报名用户") // registered
    @PostMapping("/export")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userKeyWord", value = "用户关键字"),
            @ApiImplicitParam(name = "orgIds", value = "所在部门"),
            @ApiImplicitParam(name = "auditStatus", value = "审核状态"),
            @ApiImplicitParam(name = "trainingProjectId", value = "项目ID")
    })
    public Response<String> exportRegistered(@RequestBody ExportRequestVO vo) {
        try {
            if (StringUtils.isBlank(vo.getOrgIds())) {
                return Response.fail(InternationalEnums.SITECLASSIFYMANAGECOMTROLLER2.getName());
            }
            // 根据用户关键字 获取 所有用户信息 (模糊匹配)
            List<Long> userIdList = null;
            List<String> orgIdsList = Arrays.asList(vo.getOrgIds().split(","));
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("userIdList", userIdList);
            map.put("orgIdsList", orgIdsList);
            map.put("auditStatus", vo.getAuditStatus());
            map.put("trainingProjectId", vo.getTrainingProjectId());

            // List<EnrollerVo> exportRegisteredList = trEnrollRecordService.exportRegisteredList(map);
            // 账户集合

            // List<String> accountIdList = null;
            //exportRegisteredList.stream().map(EnrollerVo::getAccountId).collect(Collectors.toList());
            // ID集合 获取用户信息 (用户名, 用户状态)
            // List<User> userList = null;

            // HSSFWorkbook workBook = new
            // ExportUtil().export(exportRegisteredList);
            // workBook.write(response.getOutputStream());

            return Response.ok();
        } catch (Exception e) {
            LOG.error("导出已报名用户:" + e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "报名管理信息", notes = "报名管理信息")
    @GetMapping("/list")
    public Response<EnrollerVo> list(
            @ApiParam(value = "用户名、姓名、标签", required = false) @RequestParam(name = "userName", required = false) String userName,
            @ApiParam(value = "部门关键字", required = false) @RequestParam(name = "key", required = false) String key,
            @ApiParam(value = "培训项目ID", required = true) @RequestParam(name = "trainningProjectId", required = true) Long trainningProjectId,
            @ApiParam(value = "审核状态(1待审核、2报名通过、3报名不通过)", required = false) @RequestParam(name = "state", required = false) Integer state,
            @ApiParam(value = "当前页", required = false) @RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNo,
            @ApiParam(value = "页数", required = false) @RequestParam(name = "pageSize", defaultValue = "20", required = false) Integer pageSize
    ) {

        Long companyId = ContextHolder.get().getCompanyId();
        // 根据用户关键字获取用户ID集合
        List<Long> userIdList = null;
        List<Long> orgIdList = null;
        //根据项目Id获得是否需要审核
        int enableEnroll;
        try {
            enableEnroll = trainingProjectClient.getOne(trainningProjectId).getEnableEnroll();
        } catch (Exception e) {
            e.printStackTrace();
            enableEnroll = 1;
        }
        List<AccountVO> userList = null;
        if (StringUtils.isNotBlank(userName)) {
            try {
                userList = accountClient.fuzzySearchAccountByName(userName, companyId);
                if (null != userList) {
                    userIdList = new ArrayList<>();
                    for (AccountVO a : userList) {
                        userIdList.add(a.getId());
                    }
                } else {
                    return Response.ok();
                }

            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }

        if (StringUtils.isNotBlank(key)) {
            orgIdList = organizationClient.findOrgIdByName(key, companyId);
            if (orgIdList == null) {
                return Response.ok();
            }
        }
        EnrollerParam enrollerParam = new EnrollerParam();
        if (null != userIdList) {
            enrollerParam.setUserIdList(userIdList);
        }
        if (orgIdList != null) {
            enrollerParam.setOrgIds(orgIdList);
        }
        enrollerParam.setPageNo(pageNo);
        enrollerParam.setPageSize(pageSize);
        enrollerParam.setTrainningProjectId(trainningProjectId);
        enrollerParam.setEnableEnroll(enableEnroll);
        enrollerParam.setState(state);
        Page<EnrollerVo> list = enrollFeignClient.listEnroll(enrollerParam);
        Map<Long, Object> accountMap = new HashMap<Long, Object>();
        Map<Long, Object> orgMap = new HashMap<Long, Object>();
        EnrollerVo vo = null;
        AccountVO account = null;
        List<String> orgs = null;
        for (EnrollerVo item : list.getRecords()) {
            Long orgId = item.getOrgId();
            Long accountId = item.getAccountId();
            //根据accountId 获取 用户name,userName
            String name = null;
            String fullName = null;
            //根据orgId 获取 部门名称 orgName
            String orgName = null;
            String orgNames = null;
            if (accountMap.containsKey(accountId)) {
                vo = (EnrollerVo) accountMap.get(accountId);
                name = vo.getUserName();
                fullName = vo.getName();
            } else {
                try {
                    account = accountClient.findById(accountId);
                    fullName = account.getFullName();
                    name = account.getName();
                    vo = new EnrollerVo();
                    vo.setUserName(name);
                    vo.setName(fullName);
                    accountMap.put(accountId, vo);
                } catch (Exception e) {
                    name = "--";
                }
            }
            if (orgMap.containsKey(orgId)) {
                vo = (EnrollerVo) orgMap.get(orgId);
                orgName = vo.getOrgName();
                orgNames = vo.getOrgNames();
            } else {
                try {
                    orgs = organizationClient.getChiefOrgNames(orgId, ContextHolder.get().getCompanyId());
                    if (orgs != null && orgs.size() == 1) {
                        orgName = orgs.get(0);
                    } else if (orgs != null && orgs.size() > 1) {
                        orgName = orgs.get(orgs.size() - 1);
                        orgNames = orgs.get(orgs.size() - 2);
                        vo = new EnrollerVo();
                        vo.setOrgNames(orgNames);
                        vo.setOrgName(orgName);
                        orgMap.put(orgId, vo);
                    }
                } catch (Exception e) {
                    orgName = "--";
                }
            }
            item.setName(fullName);
            item.setUserName(name);
            item.setOrgName(orgName);
            item.setOrgNames(orgNames);
        }
        Map<String, Integer> pageMap = new HashMap<String, Integer>();
        pageMap.put("pageNo", pageNo);
        pageMap.put("pageSize", pageSize);
        pageMap.put("pageTotal", list.getTotal());
        return Response.ok(list.getRecords(), pageMap);
    }

    @ApiOperation(value = "报名管理信息导出", notes = "报名管理信息导出")
    @GetMapping("/list/export")
    public Response<Object> enrollerListExport(
            @ApiParam(value = "用户名、姓名、标签", required = false) @RequestParam(name = "userName", required = false) String userName,
            @ApiParam(value = "部门关键字", required = false) @RequestParam(name = "key", required = false) String key,
            @ApiParam(value = "培训项目ID", required = true) @RequestParam(name = "trainningProjectId", required = true) Long trainningProjectId,
            @ApiParam(value = "审核状态(1待审核、2报名通过、3报名不通过)", required = false) @RequestParam(name = "state", required = false) Integer state
    ) {

        RequestContext res = ContextHolder.get();

        Long taskId = System.currentTimeMillis();
        String serialNo = "ENROLLER-LIST-EXPORT-" + taskId.toString();
        String taskName = "报名管理信息导出-" + taskId.toString();

        Map<String, Object> paramMap = new HashMap<String, Object>();

        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
        Date comitTime = new Date();
        paramMap.put("taskId", taskId);
        paramMap.put("serialNo", serialNo);
        paramMap.put("taskName", taskName);
        paramMap.put("comitTime", comitTime);
        paramMap.put("res", res);
        paramMap.put("userName", userName);
        paramMap.put("key", key);
        paramMap.put("trainningProjectId", trainningProjectId);
        paramMap.put("state", state);
        enrollerListExport.execute(paramMap, true);
        TrainingProjectVo trainingProject = trainingProjectClient.getOne(trainningProjectId);
        String fileName = trainingProject.getName() + "报名明细" + sdf2.format(comitTime) + ".xlsx";
        String fileUril = pcHostUrl+"/api/v1/buckets/upload/objects/download/?preview=true&prefix="+fileName;

        return Response.ok(fileUril);
    }

    @ApiOperation(value = "更新报名状态", notes = "更新报名状态")
    @PostMapping("/state/update")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "报名ID"),
            @ApiImplicitParam(name = "auditStatus", value = "更改的状态")})
    public Response<Integer> updateState(@RequestBody EnrollRecord enrollRecord) {
        Integer s = enrollFeignClient.updateState(enrollRecord);
        if (0 < s) {
            return Response.ok(ReturnCode.SUCCESS);
        } else {
            return Response.fail(ReturnCode.UPDATE_FAIL.getCode(),ReturnCode.UPDATE_FAIL.getMsg());
        }
    }

}
