package cn.com.smart.form.list;

import cn.com.smart.form.bean.entity.TFormList;
import cn.com.smart.form.enums.FormType;
import cn.com.smart.form.list.bean.*;
import cn.com.smart.report.bean.entity.*;
import cn.com.smart.report.enums.ReportType;
import cn.com.smart.web.constant.enums.BtnAuthType;
import cn.com.smart.web.constant.enums.BtnPropType;
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.LoggerUtils;
import com.mixsmart.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 乌草坡 2019-09-02
 * @since 1.0
 */
public class FormListPropDelegate {

    private static final Logger logger = LoggerFactory.getLogger(FormListPropDelegate.class);

    private FormListProp formListProp;

    private IOPService opServ;

    public FormListPropDelegate(FormListProp formListProp, IOPService opServ) {
        this.formListProp = formListProp;
        this.opServ = opServ;
    }

    public TFormList toFormList() {
        if(null == this.formListProp) {
            throw new NullArgumentException("formListProp对象为空");
        }
        if(CollectionUtils.isEmpty(getFormListProp().getListFieldProps())) {
            LoggerUtils.warn(logger, "字段属性为空，不支持转换为对象");
            return null;
        }
        TFormList formList = new TFormList();
        formList.setName(getFormListProp().getFormName());
        formList.setFormId(getFormListProp().getFormId());
        formList.setUserId(getFormListProp().getUserId());
        formList.setType(getFormListProp().getFormListType());
        formList.setIsAutoCreate(YesNoType.YES.getIndex());
        formList.setReport(createReport());
        return formList;
    }

    /**
     * 创建报表对象
     * @return 返回报表对象
     */
    private TReport createReport() {
        LoggerUtils.debug(logger, "开始创建报表对象...");
        TReport report = new TReport();
        report.setName(getFormListProp().getFormName());
        report.setType(ReportType.FORM_LIST_REPORT.getValue());
        report.setUserId(getFormListProp().getUserId());
        report.setProperties(createReportProperties());
        report.setSqlResource(createReportSqlResource());
        report.setFields(createReportFields());
        autoCreateCell(report);
        autoCreateBtn(report);
        return report;
    }

    /**
     * 创建报表属性对象
     * @return 返回报表属性对象
     */
    private TReportProperties createReportProperties() {
        LoggerUtils.debug(logger, "开始创建报表属性...");
        TReportProperties reportProp = new TReportProperties();
        reportProp.setIsCheckbox(YesNoType.NO.getIndex());
        if(getFormListProp().getListFieldProps().size() > 12) {
            reportProp.setIsFixedHeader(YesNoType.NO.getIndex());
        } else {
            reportProp.setIsFixedHeader(YesNoType.YES.getIndex());
        }
        reportProp.setIsHasId(YesNoType.YES.getIndex());
        reportProp.setIsShowId(YesNoType.NO.getIndex());
        reportProp.setIsImport(YesNoType.YES.getIndex());
        return reportProp;
    }

    /**
     * 创建报表SQL资源对象
     * @return 返回报表SQL资源对象
     */
    private TReportSqlResource createReportSqlResource() {
        LoggerUtils.debug(logger, "开始创建报表SQL资源...");
        TReportSqlResource sqlResource = new TReportSqlResource();
        sqlResource.setIsFilter(YesNoType.YES.getIndex());
        GenerateSqlByListFieldDelegate delegate = new GenerateSqlByListFieldDelegate(getFormListProp(), opServ);
        sqlResource.setName(delegate.getSqlName());
        String sql = delegate.createSQL();
        if(StringUtils.isEmpty(sql)) {
            throw new RuntimeException("自动生成SQL失败");
        }
        sqlResource.setSql(sql);
        return sqlResource;
    }

    /**
     * 创建报表字段列表
     * @return 返回报表字段列表
     */
    private List<TReportField> createReportFields() {
        LoggerUtils.debug(logger, "开始创建报表字段列表...");
        List<TReportField> reportFields = new ArrayList<>();
        int index = 1;
        for(AbstractListFieldProp fieldProp : getFormListProp().getListFieldProps()) {
            TReportField reportField = new TReportField();
            reportField.setTitle(fieldProp.getTitle());
            if(fieldProp.getSupportSearch()) {
                reportField.setSearchName(fieldProp.getFieldName());
                if(fieldProp instanceof TextPluginListFieldProp) {
                    handleTextFieldProp(reportField, (TextPluginListFieldProp)fieldProp);
                } else if(fieldProp instanceof DateListFieldProp) {
                    handleDateFieldProp(reportField, (DateListFieldProp)fieldProp);
                } else if(fieldProp instanceof OptionListFieldProp) {
                    handleOptionFieldProp(reportField, (OptionListFieldProp)fieldProp);
                }
            }
            if(fieldProp.getSupportSort()) {
                reportField.setSortFieldName(fieldProp.getFieldName());
            }
            reportField.setSortOrder(index);
            reportFields.add(reportField);
            index++;
        }
        TReportField opField = new TReportField();
        opField.setTitle("操作");
        opField.setSortOrder(index);
        reportFields.add(opField);
        return reportFields;
    }

    /**
     * 处理文本字段属性对象
     * @param reportField 报表字段对象
     * @param fieldProp 字段属性对象
     */
    private void handleTextFieldProp(TReportField reportField, TextPluginListFieldProp fieldProp) {
        reportField.setSearchPluginType(fieldProp.getTextPluginType());
        reportField.setSearchPluginUrl(fieldProp.getUrl());
    }

    /**
     * 处理日期字段属性对象
     * @param reportField 报表字段对象
     * @param fieldProp 字段属性对象
     */
    private void handleDateFieldProp(TReportField reportField, DateListFieldProp fieldProp) {
        reportField.setSearchPluginType(fieldProp.getDateType());
        reportField.setSearchDataFormat(fieldProp.getDateFormat());
    }

    /**
     * 处理选项字段属性对象
     * @param reportField 报表字段对象
     * @param fieldProp 字段属性对象
     */
    private void handleOptionFieldProp(TReportField reportField, OptionListFieldProp fieldProp) {
        reportField.setSearchPluginType(fieldProp.getPluginType());
        if(StringUtils.isNotEmpty(fieldProp.getUrl())) {
            reportField.setSearchPluginUrl(fieldProp.getUrl());
        } else if(CollectionUtils.isNotEmpty(fieldProp.getOptions())) {
            reportField.setLabelValues(fieldProp.getOptions());
        }
    }

    /**
     * 自动创建单元格
     * @param report
     */
    private void autoCreateCell(TReport report) {
        String viewUrl = "";
        String editUrl = "";
        String paramName = "";
        String paramValue = "";
        int fieldSize = report.getFields().size();
        FormType formType = FormType.getObj(this.formListProp.getFormType());
        if(formType == FormType.NORMAL_FORM) {
            viewUrl = "form/instance/view?formId=${formId}&formDataId=${formDataId}";
            editUrl = "form/instance/edit?id=${formDataId}";
            paramName = "formId,formDataId";
            paramValue = fieldSize + "," + (fieldSize + 1);
        } else if(formType == FormType.FLOW_FORM) {
            viewUrl = "process/viewForm?processId=${processId}&orderId=${orderId}";
            editUrl = "process/editForm?processId=${processId}&orderId=${orderId}";
            paramName = "processId,orderId";
            paramValue = (fieldSize + 2) + "," + (fieldSize + 3);
        }
        StringBuilder cellContentBuilder = new StringBuilder();
        cellContentBuilder.append("<button type=\"button\" class=\"btn btn-info btn-sm cnoj-open-popup\" data-title=\"查看信息\" data-uri=\""+viewUrl+"\">查看</button>");
        cellContentBuilder.append(" &nbsp;");
        cellContentBuilder.append("<button type=\"button\" class=\"btn btn-primary btn-sm cnoj-open-popup\" data-title=\"修改数据\" data-uri=\""+editUrl+"\">修改</button>");
        TReportCustomCell customCell = new TReportCustomCell();
        customCell.setContent(cellContentBuilder.toString());
        customCell.setPosition(report.getFields().size());
        customCell.setParamName(paramName);
        customCell.setParamValue(paramValue);
        customCell.setUserId(report.getUserId());
        List<TReportCustomCell> customCells = new ArrayList<>(1);
        customCells.add(customCell);
        report.setCustomCells(customCells);
    }

    /**
     * 自动生成按钮
     * @param report
     */
    private void autoCreateBtn(TReport report) {
        String addUrl = "";
        String delUrl = "";
        int fieldSize = report.getFields().size();
        FormType formType = FormType.getObj(this.formListProp.getFormType());
        if(formType == FormType.NORMAL_FORM) {
            addUrl = "form/instance/create?formId=${formId}";
            delUrl = "form/instance/delete";
        } else if(formType == FormType.FLOW_FORM) {
            addUrl = "process/form?processName=${processName}";
            delUrl = "process/mgr/delete.json";
        }

        TReportButton addBtn = new TReportButton();
        addBtn.setName("添加");
        addBtn.setDialogTitle("添加" + report.getName());
        addBtn.setBtnId(BtnAuthType.ADD.getValue());
        addBtn.setOpenType(BtnPropType.OpenStyle.OPEN_NEW_TAB_IFRAME.getValue());
        addBtn.setUrl(addUrl);
        addBtn.setUserId(report.getUserId());
        addBtn.setSortOrder(1);

        TReportButton delBtn = new TReportButton();
        delBtn.setBtnId(BtnAuthType.DELETE.getValue());
        delBtn.setPromptMsg("你确定要删除选中的数据吗？");
        delBtn.setUrl(delUrl);
        delBtn.setUserId(report.getUserId());
        delBtn.setName("删除");
        delBtn.setSortOrder(2);

        List<TReportButton> buttons = new ArrayList<>(2);
        buttons.add(addBtn);
        buttons.add(delBtn);
        report.setButtons(buttons);
    }

    public FormListProp getFormListProp() {
        return formListProp;
    }

    public void setFormListProp(FormListProp formListProp) {
        this.formListProp = formListProp;
    }
}
