package cn.estsh.i3plus.core.apiservice.controller.report;

import cn.estsh.i3plus.core.api.iservice.base.IReportService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysRoleService;
import cn.estsh.i3plus.platform.common.tool.ClassTool;
import cn.estsh.i3plus.platform.common.tool.StringTool;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.annotation.AnnoOutputColumn;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.model.common.ClassFieldModel;
import cn.estsh.i3plus.pojo.model.common.ClassModel;
import cn.estsh.i3plus.pojo.model.report.TemplateModel;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import cn.estsh.i3plus.pojo.platform.bean.SysRole;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ResultBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.QueryException;
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.*;

import javax.persistence.Transient;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping(PlatformConstWords.BASE_URL + "/cloud/report")
@Api(description="报表服务")
public class CoreReportController extends CoreBaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(CoreReportController.class);

    @Value("${impp.app.pojo-packages}.bean")
    public String pojoPackagePath;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private IReportService reportService;

    @GetMapping(value = "/role/list")
    @ApiOperation(value = "查询所有角色", notes = "查询所有系统角色")
    public ResultBean findRoleAll() {
        try {
            List<SysRole> list = roleService.findSysRoleAll();
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(list);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }  catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping(value = "/role/list/ids")
    @ApiOperation(value = "查询所有角色", notes = "查询所有系统角色")
    public ResultBean findRoleByIdList(@RequestBody String[] ids) {
        try {
            List<SysRole> list = roleService.findSysRoleByInId(StringTool.getArrayLong(ids));
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(list);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }  catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/role/user/list")
    @ApiOperation(value = "查询登录用户所有角色")
    public ResultBean findSysRoleByUser(HttpServletRequest req) {
        try {
            SessionUser sessionUser = getSessionUser();
            if(sessionUser != null && sessionUser.getUser() != null){
                List<SysRole> list = roleService.findSysRoleByUser(getSessionUser().getUser());
                return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(list);
            }
            return ResultBean.fail("操作失败").setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()).setErrorMsg("获取用户信息失败");
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        }  catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping(value="/template-model/run")
    @ApiOperation(value="查询管理后台所有类",notes = "根据核心包路径列出所有类")
    public ResultBean runTemplateModel(@RequestBody TemplateModel model){
        LOGGER.info("【执行TemplateModel】TemplateModel：{}",model);
        try {
            List list = reportService.selectTemplateModel(model);
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultList(list);
        }catch (Exception e){
            return ResultBean.fail("操作失败").setMsg(e.getMessage()).setErrorMsg(e.getLocalizedMessage()
            );
        }
    }

    @GetMapping(value="/clz-model/list")
    @ApiOperation(value="查询管理后台所有类",notes = "根据核心包路径列出所有类")
    public BaseResultBean<ClassModel> listClzModel() {
        LOGGER.info("【类路径：{}】",pojoPackagePath);
        List<String> clzNameList = ClassTool.getClassName(pojoPackagePath, true);
        List<ClassModel> clzList = new ArrayList<>(clzNameList.size());
        for(String clzName : clzNameList){
            ClassModel model = getClassModel(clzName);
            if(model != null){
                if(StringUtils.isNotBlank(model.getClzFullName())){
                    List<ClassFieldModel> list = getClassFieldModel(model.getClzFullName());
                    model.setFieldList(list);
                }
                clzList.add(model);
            }
        }
        return ResultBean.success("获取类：" + clzList.size()).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(clzList);
    }

    @GetMapping(value="/clz-model/{classPath}")
    @ApiOperation(value="查询管理后台所有类",notes = "根据核心包路径列出所有类")
    public BaseResultBean<ClassModel> getClzModel(@PathVariable("classPath") String classPath) {
        LOGGER.info("【类路径：{}】",pojoPackagePath);
        ClassModel model = getClassModel(classPath);
        if(model != null){
            if(StringUtils.isNotBlank(model.getClzFullName())){
                List<ClassFieldModel> list = getClassFieldModel(model.getClzFullName());
                model.setFieldList(list);
            }
        }
        return ResultBean.success("获取类：" + model.getClzDesc()).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(model);
    }

    @GetMapping(value="/list-clz")
    @ApiOperation(value="查询管理后台所有类",notes = "根据核心包路径列出所有类")
    public BaseResultBean<ClassModel> listClz() {
        LOGGER.info("【类路径：{}】",pojoPackagePath);
        List<String> clzNameList = ClassTool.getClassName(pojoPackagePath, true);
        List<ClassModel> clzList = new ArrayList<>(clzNameList.size());
        for(String clzName : clzNameList){
            clzList.add(getClassModel(clzName));
        }

        return ResultBean.success("获取类：" + clzList.size())
                .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                .setResultList(clzList);
    }

    @GetMapping(value="/pojo-property")
    @ApiOperation(value="查询类所有属性")
    public ResultBean<ClassFieldModel> testWms(@RequestParam("clzFullName") String clzFullName) {
        LOGGER.info("【查询类属性：{}】",clzFullName);
        List<ClassFieldModel> fieldModelList = getClassFieldModel(clzFullName);
        return ResultBean.success("获取属性：" + fieldModelList.size())
                            .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                            .setResultList(fieldModelList);
    }

    private ClassModel getClassModel(String clzName){
        try {
            //注册类
            Class tmpClz = Class.forName(clzName);
            ClassModel classModel = new ClassModel();
            classModel.setServerId(CommonEnumUtil.SOFT_TYPE.CORE.getValue());
            classModel.setServerName(CommonEnumUtil.SOFT_TYPE.CORE.getCode());
            classModel.setPackageName(pojoPackagePath);
            classModel.setClzFullName(clzName);
            classModel.setClzSimpleName(tmpClz.getSimpleName());

            Api api = (Api) tmpClz.getAnnotation(Api.class);
            if(api != null) {
                classModel.setClzDesc(api.value());
                return classModel;
            }else{
                LOGGER.warn("不添加类：{},因为没有添加api描述", tmpClz);
            }
        } catch (ClassNotFoundException e) {
            LOGGER.error("【类：{}注册出错】",clzName,clzName,e);
        }
        return null;
    }

    private List<ClassFieldModel> getClassFieldModel(String clzFullName){
        List<ClassFieldModel> fieldModelList = new ArrayList<>();
        try {
            Class tmpClz = Class.forName(clzFullName);
            List<Field> fields = ClassTool.getAllFieldsList(tmpClz);
            ClassFieldModel fieldModel = null;
            ApiParam apiParam;
            Transient tran;
            for(Field f : fields){
                tran = f.getAnnotation(Transient.class);
                if(tran == null && !"serialVersionUID".equals(f.getName())) {
                    // 临时对象不需要处理
                    fieldModel = new ClassFieldModel();
                    fieldModel.setPackageName(pojoPackagePath);
                    fieldModel.setClzFullName(clzFullName);
                    fieldModel.setClzSimpleName(tmpClz.getSimpleName());
                    fieldModel.setFieldName(f.getName());

                    apiParam = f.getAnnotation(ApiParam.class);
                    if(apiParam != null){
                        fieldModel.setFieldDesc(apiParam.value());
                    }
                    fieldModelList.add(fieldModel);
                }else{
                    LOGGER.info("【临时属性：{}】",f.getName());
                }
            }
        } catch (ClassNotFoundException e) {
            LOGGER.error("【类：{}实例化出错】",clzFullName,e);
        }
        return fieldModelList;
    }

}
