package cn.com.smart.form.service;

import cn.com.smart.bean.SmartResponse;
import cn.com.smart.exception.ServiceException;
import cn.com.smart.form.bean.entity.TFormList;
import cn.com.smart.form.enums.FormListType;
import cn.com.smart.report.bean.entity.TReport;
import cn.com.smart.report.bean.entity.TReportButton;
import cn.com.smart.report.bean.entity.TReportCustomCell;
import cn.com.smart.report.enums.ReportType;
import cn.com.smart.report.service.impl.ReportButtonService;
import cn.com.smart.report.service.impl.ReportFieldService;
import cn.com.smart.report.service.impl.ReportService;
import cn.com.smart.res.SQLResUtil;
import cn.com.smart.service.impl.MgrServiceImpl;
import cn.com.smart.web.bean.entity.TNOPAuth;
import cn.com.smart.web.constant.IWebConstant;
import cn.com.smart.web.service.IOPService;
import com.mixsmart.enums.YesNoType;
import com.mixsmart.exception.NullArgumentException;
import com.mixsmart.utils.CollectionUtils;
import com.mixsmart.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FormListService extends MgrServiceImpl<TFormList> implements IFormListService {

    @Autowired
    private ReportService reportServ;
    @Autowired
    private ReportFieldService reportFieldServ;
    @Autowired
    private IOPService opServ;
    @Autowired
    private ReportButtonService reportBtnServ;

    @Override
    public void createList(List<TFormList> formLists) {
        if(CollectionUtils.isEmpty(formLists)) {
            throw new NullArgumentException("formLists参数对象为空");
        }

        boolean is = true;
        TFormList mainFormList = getMainFormList(formLists);
        if(null == mainFormList) {
            deleteSubFormList(formLists.get(0).getFormId());
            for(TFormList tmp : getSubFormList(formLists)) {
                tmp.setType(FormListType.SUB.getValue());
                tmp.setParentId(null);
                if(!OP_SUCCESS.equals(save(tmp).getResult())) {
                    is = is && false;
                }
            }
        } else {
            //获取主表的列表ID和报表ID
            String[] array = getMainFormListRelateIds(mainFormList.getFormId());
            if(null != array) {
                mainFormList.setId(array[0]);
                mainFormList.getReport().setId(array[1]);
                mainFormList.setParentId(array[1]);
                mainFormList.getReport().getProperties().setId(array[2]);
                mainFormList.getReport().getSqlResource().setId(array[3]);
                is = (OP_SUCCESS.equals(update(mainFormList).getResult()));
                if(is) {
                    deleteSubFormList(mainFormList.getFormId());
                    for(TFormList tmp : getSubFormList(formLists)) {
                        tmp.setParentId(mainFormList.getId());
                        if(!OP_SUCCESS.equals(save(tmp).getResult())) {
                            is = is && false;
                        }
                    }
                }
            } else {
                is = (OP_SUCCESS.equals(save(mainFormList).getResult()));
                if(is) {
                    for(TFormList tmp : getSubFormList(formLists)) {
                        tmp.setParentId(mainFormList.getId());
                        if(!OP_SUCCESS.equals(save(tmp).getResult())) {
                            is = is && false;
                        }
                    }
                }
            }
        }
        if(!is) {
            throw new RuntimeException("表单列表生成异常");
        }
    }

    @Override
    public SmartResponse<String> save(TFormList formList) {
        SmartResponse<String> smartResp = reportServ.save(formList.getReport());
        if(OP_SUCCESS.equals(smartResp.getResult())) {
            formList.setReportId(formList.getReport().getId());
            smartResp = super.save(formList);
        }
        return smartResp;
    }

    @Override
    public SmartResponse<String> update(TFormList formList) {
        //删除报表字段
        Map<String, Object> param = new HashMap<>(1);
        param.put("reportId", formList.getReport().getId());
        reportFieldServ.deleteByField(param);

        SmartResponse<String> smartResp = reportServ.update(formList.getReport());
        if(OP_SUCCESS.equals(smartResp.getResult())) {
            formList.setReportId(formList.getReport().getId());
            smartResp = super.update(formList);
        }
        return smartResp;
    }

    /**
     * 删除子表单列表
     * @param formId
     */
    public void deleteSubFormList(String formId) {
        Map<String, Object> param = new HashMap<>(1);
        param.put("formId", formId);
        SmartResponse<Object> smartResp = opServ.getDatas("get_reportid_by_formid", param);
        if(OP_SUCCESS.equals(smartResp.getResult())) {
            String[] reportIds = new String[smartResp.getDatas().size()];
            int index = 0;
            for(Object obj : smartResp.getDatas()) {
                reportIds[index] = StringUtils.handleNull(obj);
                index++;
            }
            for(String reportId: reportIds) {
                reportServ.delete(reportId);
            }
        }
        opServ.execute("delete_sub_form_list_by_formid", param);
    }

    /**
     * 获取主表单列表对象
     * @param formLists
     * @return
     */
    private TFormList getMainFormList(List<TFormList> formLists) {
        for(TFormList formList : formLists) {
            FormListType formListType = FormListType.getObj(formList.getType());
            if(FormListType.MAIN == formListType) {
                return formList;
            }
        }
        return null;
    }

    /**
     * 获取子表单列表
     * @param formLists
     * @return
     */
    private List<TFormList> getSubFormList(List<TFormList> formLists) {
        List<TFormList> subFormlist = new ArrayList<>();
        for(TFormList formList : formLists) {
            FormListType formListType = FormListType.getObj(formList.getType());
            if(FormListType.SUB == formListType) {
                subFormlist.add(formList);
            }
        }
        return subFormlist;
    }

    /**
     * 获取关联Id如：表单列表ID、报表ID、报表属性ID、报表SQL资源ID
     * @param formId 表单ID
     * @return
     */
    private String[] getMainFormListRelateIds(String formId) {
        Map<String, Object> param = new HashMap<>(1);
        param.put("formId", formId);
        SmartResponse<Object> smartResp = opServ.getDatas("get_main_form_list_report_id", param);
        String[] array = null;
        if(OP_SUCCESS.equals(smartResp.getResult())) {
            Object[] objs = (Object[]) smartResp.getDatas().get(0);
            array = new String[4];
            array[0] = StringUtils.handleNull(objs[0]);
            array[1] = StringUtils.handleNull(objs[1]);
            array[2] = StringUtils.handleNull(objs[2]);
            array[3] = StringUtils.handleNull(objs[3]);
        }
        return array;
    }

    @Override
    public SmartResponse<String> delete(String id) throws ServiceException {
        SmartResponse<String> smartResp = new SmartResponse<String>("删除失败");
        if(StringUtils.isEmpty(id)) {
            return smartResp;
        }
        String[] ids = id.split(IWebConstant.MULTI_VALUE_SPLIT);
        Map<String, Object> param = new HashMap<String, Object>(1);
        param.put("ids", ids);
        SmartResponse<Object> reportIdResp = opServ.getDatas("get_reportid_by_formlistid", param);
        if(OP_SUCCESS.equals(reportIdResp.getResult())) {
            List<String> reportIds = new ArrayList<>(reportIdResp.getDatas().size());
            for(Object obj : reportIdResp.getDatas()) {
                reportIds.add(StringUtils.handleNull(obj));
            }
            opServ.execute("delete_form_list_by_id", param);
            String[] reportIdArray = new String[reportIds.size()];
            reportIds.toArray(reportIdArray);
            param.clear();
            param.put("ids", reportIdArray);
            smartResp = opServ.execute("delete_report", param);
            if(OP_SUCCESS.equals(smartResp.getResult())) {
                smartResp.setMsg("删除成功");
            }
        }
        return smartResp;
    }

    /**
     * 保存或更新报表设计
     * @param formList 报表实体类
     * @return 返回结果
     */
    public SmartResponse<String> saveOrUpdate(TFormList formList) {
        SmartResponse<String> smartResp = new SmartResponse<String>();
        formList.getReport().setName(formList.getName());
        formList.getReport().setType(ReportType.FORM_LIST_REPORT.getValue());
        formList.getReport().getProperties().setIsImport(YesNoType.YES.getIndex());
        formList.getReport().setUserId(formList.getUserId());
        if(null == formList.getIsAutoCreate()) {
            formList.setIsAutoCreate(YesNoType.NO.getIndex());
        }
        if(CollectionUtils.isNotEmpty(formList.getReport().getButtons())) {
            for(TReportButton btn : formList.getReport().getButtons()) {
                btn.setUserId(formList.getUserId());
            }
        }
        if(CollectionUtils.isNotEmpty(formList.getReport().getCustomCells())) {
            for(TReportCustomCell cell : formList.getReport().getCustomCells()) {
                cell.setUserId(formList.getUserId());
            }
        }
        if(StringUtils.isEmpty(formList.getId())) {
            smartResp = this.save(formList);
        } else {
            smartResp = this.update(formList);
        }
        return smartResp;
    }

    /**
     * 关联查询表单列表
     * @param id 表单列表ID
     * @return 返回表单列表实体类（包含报表实体、属性实体数据，字段实体列表，自定义SQL语句实体）
     */
    public TFormList queryAssoc(String id) {
        if(StringUtils.isEmpty(id)) {
            throw new NullArgumentException();
        }
        TFormList formList = super.find(id).getData();
        assocReport(formList);
        return formList;
    }

    /**
     * 关联查询表单列表（与数据字段关联查询报表类型）
     * @param id 表单列表ID
     * @return 返回表单列表实体类（包含报表实体数据，属性实体数据，字段实体列表，自定义SQL语句实体）
     */
    public TFormList queryAssocObj(String id) {
        if(StringUtils.isEmpty(id)) {
            throw new NullArgumentException();
        }
        String sql = SQLResUtil.getOpSqlMap().getSQL("query_assoc_form_list");
        if(StringUtils.isEmpty(sql)) {
            throw new NullPointerException("[query_assoc_form_list]对应的SQL语句为空");
        }
        Map<String, Object> param = new HashMap<String, Object>(1);
        param.put("id", id);
        List<TFormList> formLists = super.getDao().querySqlToEntity(sql, param, TFormList.class);
        if(CollectionUtils.isEmpty(formLists)) {
            return null;
        }
        TFormList formList = formLists.get(0);
        assocReport(formList);
        return formList;
    }

    private void assocReport(TFormList formList) {
        TReport report = reportServ.queryAssoc(formList.getReportId());
        formList.setReport(report);
    }

    /**
     * 根据表单列表ID查找操作按钮
     * @param formListId
     * @return
     */
    public SmartResponse<TNOPAuth> findOPAuths(String formListId) {
        SmartResponse<TNOPAuth> smartResp = new SmartResponse<>();
        TFormList formList = super.find(formListId).getData();
        List<TNOPAuth> opAuths = reportBtnServ.findOPAuths(formList.getReportId(), null);
        if(CollectionUtils.isNotEmpty(opAuths)) {
            smartResp.setDatas(opAuths);
            smartResp.setResult(OP_SUCCESS);
            smartResp.setMsg(OP_SUCCESS_MSG);
        }
        return smartResp;
    }
}
