package com.qryord.mp.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.qryord.common.constant.Constants;
import com.qryord.common.enums.EDelete;
import com.qryord.common.enums.EQueryStatus;
import com.qryord.common.enums.EQueryType;
import com.qryord.common.enums.ERole;
import com.qryord.common.utils.DateUtils;
import com.qryord.common.utils.MailUtil;
import com.qryord.common.utils.PageUtils;
import com.qryord.common.utils.StringUtils;
import com.qryord.common.utils.http.HttpUtils;
import com.qryord.framework.config.MailConfig;
import com.qryord.mp.common.BaseApiController;
import com.qryord.mp.common.RespResultModel;
import com.qryord.mp.model.*;
import com.qryord.project.business.query.domain.TQuery;
import com.qryord.project.business.query.service.ITQueryService;
import com.qryord.project.master.model.domain.Model;
import com.qryord.project.master.model.service.IModelService;
import com.qryord.project.master.modelKind.domain.ModelKind;
import com.qryord.project.master.modelKind.service.IModelKindService;
import com.qryord.project.master.roleField.domain.RoleField;
import com.qryord.project.master.roleField.service.IRoleFieldService;
import com.qryord.project.system.config.service.IConfigService;
import com.qryord.project.system.user.domain.User;
import com.qryord.project.system.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;

import java.text.MessageFormat;
import java.util.*;

@Api("用户相关使用")
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/api/app")
public class QueryApiController extends BaseApiController {

    @Autowired
    private IRoleFieldService roleFieldService;
    @Autowired
    private ITQueryService queryService;
    @Autowired
    private IConfigService configService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IModelService modelService;
    @Autowired
    private IModelKindService modelKindService;
    @Autowired
    private MailConfig mailConfig;

    @ApiOperation(value = "获取画面字段控制，roleKey必须")
    @PostMapping("/getFieldRight")
    public RespResultModel<List<RoleFieldResp>> getFieldRight(@RequestBody UserReq userReq) {

        List<RoleFieldResp> rtn = new ArrayList<>();

        RoleField cond = new RoleField();
        cond.setRoleKey(userReq.getRoleKey());
        cond.setDelFlag(EDelete.FALSE.getVal());

        List<RoleField> roleFields = roleFieldService.selectRoleFieldList(cond);

        for (RoleField rf : roleFields) {
            RoleFieldResp rfResp = new RoleFieldResp();

            rfResp.setFieldKey(rf.getFieldKey());
            rfResp.setRoleKey(rf.getRoleKey());
            rfResp.setShowFlag(rf.getShowFlag());
            rtn.add(rfResp);
        }

        return new RespResultModel(rtn);
    }

    @ApiOperation(value = "查询数据，查询类型，序列号必须，code:200 查询成功 code:500 查询失败，报message")
    @PostMapping("/getQryResult")
    public RespResultModel<QueryResp> getQryResult(@RequestBody QueryReq req) {

        if (req.getSysUserId() == null || req.getSysUserId() == 0L) {
            return new RespResultModel("用户ID必须输入。");
        }
        if (StringUtils.isBlank(req.getQueryType())) {
            return new RespResultModel("请先确认查询种类。");
        }
        if (StringUtils.isBlank(req.getSnNo())) {
            return new RespResultModel("商品序列号必须输入。");
        }
        if (EQueryType.ITEM.getVal().equals(req.getQueryType())) {
            if (StringUtils.isBlank(req.getModelName())) {
                return new RespResultModel("商品查询时，商品型号必须输入。");
            }
        }

        // 对于限制权限的用户来说，发货日期两年前的数据不让看
        User user = userService.selectUserById(req.getSysUserId());

        QueryResp rtn = new QueryResp();

        Date nowDate = DateUtils.getNowDate();
        TQuery qry = new TQuery();
        qry.setUserId(req.getSysUserId());
        qry.setQryTime(nowDate);
        qry.setQueryType(req.getQueryType());
        qry.setModelId(req.getModelId());
        qry.setModelName(req.getModelName());
        qry.setSerialNo(req.getSnNo());
        qry.setDelFlag(EDelete.FALSE.getVal());
        qry.setCreateBy(req.getSysUserId().toString());
        qry.setCreateTime(nowDate);
        qry.setUpdateBy(req.getSysUserId().toString());
        qry.setUpdateTime(nowDate);

        // 通过EDP用户名密码，获取accessToken
        String userName = configService.selectConfigByKey(Constants.edp_userName);
        String pswd = configService.selectConfigByKey(Constants.edp_password);
        String tokenUrl =configService.selectConfigByKey(Constants.edp_tokenUrl);

        String token = "";

        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");
        Map<String, String> tokenBody = new HashMap<String, String>();
        tokenBody.put("loginName", userName);
        tokenBody.put("loginPwd", pswd);

        HttpResponse response = null;
        try {
            response = HttpUtils.doPost(tokenUrl, headers,JSON.toJSONString(tokenBody, SerializerFeature.PrettyFormat));

            String rtnSrc = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject = JSON.parseObject(rtnSrc);

            if (jsonObject != null) {
                if ("1".equals(jsonObject.getString("code"))) {
                    JSONObject objBody = JSON.parseObject(jsonObject.getString("data"));
                    token = objBody.getString("xaccessToken");
                } else {
                    log.error(jsonObject.getString("msg"));
                    qry.setQryStatus(EQueryStatus.FAILURE.getVal());
                    queryService.insertTQuery(qry);
                    SendMail(user.getUserName(),req.getQueryType(),req.getSnNo(), req.getModelName());
                    return new RespResultModel("结果异常，请联系SCM人工查询。");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            qry.setQryStatus(EQueryStatus.FAILURE.getVal());
            queryService.insertTQuery(qry);
            SendMail(user.getUserName(),req.getQueryType(),req.getSnNo(), req.getModelName());
            return new RespResultModel("结果异常，请联系SCM人工查询。");
        }

        response = null;

        headers.put("x-access-token", token);
        Map<String, String> bodys = new HashMap<String, String>();
        String qryUrl = "";

        //通过token和参数，获取数据。
        if (EQueryType.BOX.getVal().equals(req.getQueryType())) {
            // 通过箱号查询
            bodys.put("cartonNumber", req.getSnNo());
            qryUrl =configService.selectConfigByKey(Constants.edp_boxQryUrl);
        } else {
            // 通过型号和序列号查询
            bodys.put("itemDescription", req.getModelName());
            bodys.put("serialNumber", req.getSnNo());
            qryUrl =configService.selectConfigByKey(Constants.edp_prodQryUrl);
        }

//        if (startDate != null) {
//            // 日期
//            bodys.put("createTimeBegin", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,startDate));
//        }

        try {
            response = HttpUtils.doPost(qryUrl, headers,JSON.toJSONString(bodys, SerializerFeature.PrettyFormat));

            String rtnSrc = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject = JSON.parseObject(rtnSrc);

            if (jsonObject != null) {
                if ("1".equals(jsonObject.getString("code"))) {
                    JSONObject objBody = JSON.parseObject(jsonObject.getString("data"));
                } else {
                    log.error(jsonObject.getString("msg"));
                    qry.setQryStatus(EQueryStatus.FAILURE.getVal());
                    queryService.insertTQuery(qry);
                    SendMail(user.getUserName(),req.getQueryType(),req.getSnNo(), req.getModelName());
                    return new RespResultModel("结果异常，请联系SCM人工查询。");
                }
            }

            if (jsonObject != null) {
                if ("1".equals(jsonObject.getString("code"))) {
                    JSONObject objBody = JSON.parseObject(jsonObject.getString("data"));

                    rtn.setSnNo(objBody.getString("serialNumber"));
                    rtn.setItemCode(objBody.getString("itemNumber"));
                    rtn.setCustNo(objBody.getString("customerNumber"));
                    rtn.setCustName(objBody.getString("customerName"));
                    rtn.setProdName(objBody.getString("itemDescription1"));
                    rtn.setPropName(objBody.getString("itemDescription2"));
                    rtn.setBatchNo(objBody.getString("lotNumber"));
                    rtn.setAddress(objBody.getString("shipAddress"));
                    rtn.setOutDate(objBody.getDate("operatorDate"));
                    rtn.setOrderNo(objBody.getString("purchaseOrder"));
                    if (objBody.getBigDecimal("quantity") != null) {
                        rtn.setQuantity(objBody.getBigDecimal("quantity").intValue());
                    }

                    if (user.getRoles() != null && user.getRoles().size()>0) {
                        if (ERole.NORMAL.getVal().equals(user.getRoles().get(0).getRoleKey())) {
                            //按日本财年计算开始时间。
                            if (DateUtils.getNowDate().compareTo(DateUtils.getFinanceDate())>0) {
                                //当前年财年已经开始，只能查看前一年4月1日至今的。
                                Date startDate = null;
                                startDate = DateUtils.getFinanceDate();
                                startDate = DateUtils.addYears(startDate,-1);
                                if (rtn.getOutDate() != null) {
                                    if (rtn.getOutDate().compareTo(startDate) < 0) {
                                        return new RespResultModel("超出可查询时限。");
                                    }
                                }
                            }
                        }
                    } else {
                        return new RespResultModel("无权限查看数据。");
                    }

                } else {
                    log.error(jsonObject.getString("msg"));
                    qry.setQryStatus(EQueryStatus.FAILURE.getVal());
                    queryService.insertTQuery(qry);
                    SendMail(user.getUserName(),req.getQueryType(),req.getSnNo(), req.getModelName());
                    return new RespResultModel("结果异常，请联系SCM人工查询。");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            qry.setQryStatus(EQueryStatus.FAILURE.getVal());
            queryService.insertTQuery(qry);
            SendMail(user.getUserName(),req.getQueryType(),req.getSnNo(), req.getModelName());
            return new RespResultModel("结果异常，请联系SCM人工查询。");
        }

        qry.setQryStatus(EQueryStatus.SUCCESS.getVal());
        queryService.insertTQuery(qry);
        return new RespResultModel(rtn);
    }

    @ApiOperation(value = "查询历史数据")
    @PostMapping("/getQryHis")
    public RespResultModel<List<QueryHisResp>> getQryHis(@RequestBody QueryReq req) {

        List<QueryHisResp> rtn = new ArrayList<>();
        TQuery cond = new TQuery();
        cond.setUserId(req.getSysUserId());

        PageUtils.startPage();
        List<TQuery> queryList = queryService.selectTQueryList(cond);

        for (TQuery q : queryList) {
            QueryHisResp qhResp = new QueryHisResp();

            qhResp.setModelId(q.getModelId());
            qhResp.setModelName(q.getModelName());
            qhResp.setSnNo(q.getSerialNo());
            qhResp.setQryTime(q.getQryTime());
            qhResp.setQueryType(EQueryType.parseByVal(q.getQueryType()));
            qhResp.setQueryStatus(EQueryStatus.parseByVal(q.getQryStatus()));

            rtn.add(qhResp);
        }

        return new RespResultModel(rtn);
    }

    @ApiOperation(value = "获取商品型号")
    @PostMapping("/getModels")
    public RespResultModel<List<ModelKindResp>> getModels() {

        List<ModelKindResp> rtn = new ArrayList<>();

        ModelKind condMk = new ModelKind();
        condMk.setDelFlag(EDelete.FALSE.getVal());

        List<ModelKind> modelKindList = modelKindService.selectModelKindList(condMk);

        for (ModelKind mk : modelKindList) {
            ModelKindResp mkResp = new ModelKindResp();
            mkResp.setModelKindId(mk.getId());
            mkResp.setKindName(mk.getKindName());

            Model cond = new Model();
            cond.setDelFlag(EDelete.FALSE.getVal());
            cond.setMkId(mk.getId());

            List<Model> modelList = modelService.selectModelList(cond);
            List<ModelResp> modelRespList = new ArrayList<>();
            for (Model m : modelList) {
                ModelResp mResp = new ModelResp();

                mResp.setModelId(m.getId());
                mResp.setModelName(m.getModelName());

                modelRespList.add(mResp);
            }
            mkResp.setModelList(modelRespList);
            rtn.add(mkResp);
        }

        return new RespResultModel(rtn);
    }

    private void SendMail(String userName,String queryType, String sn, String modelName) {

        MailUtil mailUtil = new MailUtil(mailConfig);

        // 通过邮件将查询结果通知用户
        String mailBox = configService.selectConfigByKey("scan.failure.maillist");

        try {
            if (EQueryType.BOX.getVal().equals(queryType)) {
                mailUtil.sendEmail(mailBox, "联系人", MessageFormat.format(Constants.MAIL_CONTENT_BOX,userName,EQueryType.parseByVal(queryType).getDesc(), sn));
            } else {
                mailUtil.sendEmail(mailBox, "联系人", MessageFormat.format(Constants.MAIL_CONTENT_ITEM,userName,EQueryType.parseByVal(queryType).getDesc(), sn, modelName));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }


    }

}
