package nckd.jimin.jyyy.hr.hspm.opplugin.infoclassify.personinfo;

import kd.bos.cache.CacheFactory;
import kd.bos.cache.TempFileCache;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.serialization.SerializationUtils;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IClientViewProxy;
import kd.bos.form.control.AttachmentPanel;
import kd.bos.form.control.Toolbar;
import kd.bos.form.control.UrlUtil;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.form.control.events.UploadEvent;
import kd.bos.form.control.events.UploadListener;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.util.CollectionUtils;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.hr.hbp.common.constants.HRBaseConstants;
import kd.hr.hbp.common.util.HRJSONUtils;
import kd.hr.hbp.common.util.HRStringUtils;
import kd.hr.hbp.formplugin.web.HRDataBaseEdit;
import kd.sdk.hr.hspm.business.service.AttacheHandlerService;
import kd.sdk.hr.hspm.common.constants.AttachConstants;
import kd.sdk.hr.hspm.common.constants.HspmCommonConstants;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import static kd.bos.base.bdversion.BdVersionUtils.NAME;
import static kd.bos.org.utils.Consts.STR_ONE;

/**
 * 信息批量维护-》基本信息-》弹框页面
 * 元数据标识：nckd_hspm_personinfo_ext，基本信息表单
 * 新增附件面板字段
 * author: chengchaohua
 * data: 2025-06-19
 */
public class BasicInfoHspmPlugin extends HRDataBaseEdit implements UploadListener {

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        AttachmentPanel attachmentPanel = this.getView().getControl("attachmentpanelap_std"); //附件面板
        attachmentPanel.addUploadListener(this);

        Toolbar mbar = this.getView().getControl("tbmain"); // 工具栏标识
        mbar.addItemClickListener(this);

    }

    /**
     * 附件删除
     * @param evt
     */
    @Override
    public void remove(UploadEvent evt) {
        defaultRemoveAttachment(evt);
    }

    /**
     * 删除附件
     *
     * @param evt
     */
    protected void defaultRemoveAttachment(UploadEvent evt) {
        Object[] attachs = evt.getUrls();
        Map<String, Object> attachment = (Map<String, Object>) attachs[0];
        Object removeUid = attachment.get("uid");
        String removeUidString = this.getPageCache().get("removeUid");
        Set<String> removeUidSet = new HashSet<>(attachs.length);
        if (!HRStringUtils.isEmpty(removeUidString)) {
            removeUidSet = SerializationUtils.fromJsonString(removeUidString, Set.class);
        }
        removeUidSet.add(removeUid.toString());
        String callbackKey = evt.getCallbackKey();
        String attachJsonString = this.getPageCache().get(callbackKey);
        getPageCache().put("removeUid", SerializationUtils.toJsonString(removeUidSet));
        AttachmentPanel control = this.getControl("attachmentpanelap_std");
        // 缓存内移除已删除附件
        List<Map<String, Object>> saveAttachments = control.getAttachmentData().stream()
                .filter(attach -> !attach.get("uid").equals(removeUid))
                .collect(Collectors.toList());
        // 删除一个附件后，把剩下附件信息保存到缓存中
        this.getPageCache().put(callbackKey, SerializationUtils.toJsonString(saveAttachments));
        this.getPageCache().put("isAttachChanged", STR_ONE);
    }

    /**
     * 附件上传
     * @param evt
     */
    @Override
    public void upload(UploadEvent evt) {
        defaultUploadAttachment(evt);
    }

    /**
     * 上传附件
     *
     * @param evt
     */
    protected void defaultUploadAttachment(UploadEvent evt) {
        Object[] attachs = evt.getUrls();
        List<Map<String, Object>> attachments = new ArrayList<>(attachs.length);
        String callbackKey = evt.getCallbackKey();
        String attachJsonString = this.getPageCache().get(callbackKey);
        if (!HRStringUtils.isEmpty(attachJsonString)) {
            attachments = SerializationUtils.fromJsonString(attachJsonString, List.class);
        }
        List<Map<String, Object>> finalAttachments = attachments;
        Arrays.stream(attachs).
                map(attObj -> (Map<String, Object>) attObj).
                forEach(attachment -> finalAttachments.add(attachment));

        // 把附件信息保存到缓存中
        this.getPageCache().put(callbackKey, SerializationUtils.toJsonString(finalAttachments));
        this.getPageCache().put("isAttachChanged", STR_ONE);
    }

    /**
     * 页面初始化
     * @param eventObject
     */
    @Override
    public void beforeBindData(EventObject eventObject) {

    }

    private void setAttachMent(FormShowParameter formShowParameter) {
        Long pkId = queryPkId(formShowParameter);
        List<Map<String, Object>> attachments = AttachmentServiceHelper.getAttachments("hrpi_pernontsprop", String.valueOf(pkId), "attachmentpanelap_std", false);
        String attachKey = "attachmentpanelap_std";
        AttachmentPanel attachmentEdit = (AttachmentPanel)this.getView().getControl(attachKey);
        setDownLoadAllBtn(attachments);
        this.changeAttachmentUrl(attachments);
        IClientViewProxy clientViewProxy = (IClientViewProxy)this.getView().getService(IClientViewProxy.class);
        clientViewProxy.setEntryProperty("attachmentpanel", "data", attachments);
        if (attachmentEdit != null) {
            IClientViewProxy proxy = (IClientViewProxy)attachmentEdit.getView().getService(IClientViewProxy.class);
            proxy.setFieldProperty(attachmentEdit.getKey(), "v", attachments);
            this.getView().getPageCache().put(attachKey, SerializationUtils.toJsonString(attachments));
            String cacheJsonString = this.getPageCache().get("TampAttCache" + this.getView().getPageId());
            Map<String, Object> attachmentInfo = StringUtils.isNotEmpty(cacheJsonString) ? (Map)SerializationUtils.fromJsonString(cacheJsonString, Map.class) : new HashMap();
            ((Map)attachmentInfo).put(attachKey, attachments);
            cacheJsonString = SerializationUtils.toJsonString(attachmentInfo);
            this.getPageCache().put("TampAttCache" + this.getView().getPageId(), cacheJsonString);
        }
    }

    private Long queryPkId(FormShowParameter formShowParameter) {
        Long personId = HRJSONUtils.getLongValOfCustomParam(formShowParameter.getCustomParam("person"));
        //因为通过this.getView().getFormShowParameter().getCustomParam("pkid")获取的pkid为空，所以需要通过其他途径获取pkid,然后再赋值
        //查询人员非时序性属性中附件信息
        HRBaseServiceHelper serviceHelper = new HRBaseServiceHelper("hrpi_pernontsprop");
        //数据版本状态
        QFilter qFilter = new QFilter("datastatus", QCP.equals,"1");
        //初始化状态
        QFilter dFilter = new QFilter("initstatus", QCP.equals,"2");
        //是否当前版本
        QFilter cFilter = new QFilter("iscurrentversion", QCP.equals,"1");
        QFilter pFilter = new QFilter("person", QCP.equals,personId);
        QFilter[] qFilters = new QFilter[]{qFilter,dFilter,cFilter,pFilter};
        DynamicObject dynamicObject = serviceHelper.queryOriginalOne("id", qFilters);
        if(dynamicObject != null){
            this.getView().getFormShowParameter().setCustomParam("pkid", dynamicObject.getString("id"));
            getView().getPageCache().put("pkid",this.getModel().getValue("id")+"");

        }
        return (Long)this.getModel().getValue("id");
    }

    protected void setDownLoadAllBtn(List<Map<String, Object>> attachments) {
        if(attachments == null || attachments.size() == 0){
            return;
        }
        for (Map<String, Object> attachmentMap : attachments) {
            //是否显示预览按钮
            String visiablePreview = "1";
            //是否显示下载按钮
            String visiableDownload = "1";
            //是否显示删除按钮
            String visiableDelete = "1";
            //是否显示重命名按钮
            String visiableRename = "1";
            //visible参数规则为0，1组成,0代表不可见,1代表可见
            attachmentMap.put("visible",visiablePreview + visiableDownload + visiableDelete + visiableRename);
        }
    }

    private void changeAttachmentUrl(List<Map<String, Object>> attachments) {
        if (CollectionUtils.isEmpty(attachments)) {
            return;
        }
        FileService attachmentFileService = FileServiceFactory.getAttachmentFileService();
        TempFileCache tempFileCache = CacheFactory.getCommonCacheFactory().getTempFileCache();
        for (Map<String, Object> attachment : attachments) {
            try{
                String url = (String) attachment.get(AttachConstants.URL);
                // 临时文件不用转换
                if(url.contains("tempfile/download.do?configKey")){
                    return;
                }
                if (url.contains(AttachConstants.KD_EDC_BA)) {
                    url = url.substring(0, url.indexOf(AttachConstants.KD_EDC_BA));
                }
                String path = UrlUtil.getParam(url, AttachConstants.PATH);
                InputStream inputStream = attachmentFileService.getInputStream(path);
                String tempFileUrl = tempFileCache.saveAsFullUrl((String) attachment.get(NAME), inputStream, 2 * 60 * 60);
                attachment.put(AttachConstants.URL, tempFileUrl);
            }catch (Exception es){
            }
        }
    }

    @Override
    public void afterBindData(EventObject e) {
        super.afterBindData(e);
        // 当前页面的附件面板标识：attachmentpanelap_std
        AttachmentPanel attachmentPanel = (AttachmentPanel)this.getControl("attachmentpanelap_std");
        List<Map<String, Object>> attachmentData = attachmentPanel.getAttachmentData();
        int size1 = attachmentData.size();
        // 由于也初始化上面附件面板拿不到数据，特通过下面的查询，然后再绑定到附件面板
        List<Map<String, Object>>  atts = AttachmentServiceHelper.getAttachments("hrpi_pernontsprop",this.getModel().getValue("id") ,"attachmentpanelap_std");
        int size2 = atts.size();
        attachmentPanel.bindData(atts);
        attachmentPanel.getAttachmentData();
    }

    @Override
    public void itemClick(ItemClickEvent evt) {
        super.itemClick(evt);
        if (StringUtils.equals("btnsave", evt.getItemKey()) || StringUtils.equals("btnupdate", evt.getItemKey())) {
            FormShowParameter formShowParameter = this.getView().getFormShowParameter();
            Long pkId = queryPkId(formShowParameter);
            saveAttachments("hrpi_pernontsprop", pkId,"attachmentpanelap_std");
            setAttachMent(getView().getFormShowParameter());
        }
    }

    protected void saveAttachments(String pageId, Long pkId, String attachKey) {
        // 从缓存中取出附件信息
        String attachJsonString = this.getPageCache().get(attachKey);
        if (HRStringUtils.isEmpty(attachJsonString)) {
            return;
        }
        List<Map<String, Object>> attachments = SerializationUtils.fromJsonString(attachJsonString, List.class);
        // 要取平台的缓存，不然重命名附件和备注 不会改业务的缓存字段，导致首次新增附件重命名和备注失败
        String cacheJsonString = this.getPageCache().get("TampAttCache" + this.getView().getPageId());
        if (StringUtils.isNotBlank(cacheJsonString) && !StringUtils.isEmpty(cacheJsonString)) {
            Map<String, Object> attachmentInfo = SerializationUtils.fromJsonString(cacheJsonString, Map.class);
            // attachmentInfo 的key为面板标识
            List<Map<String, Object>> tempAtts = (List) attachmentInfo.get("attachmentpanelap_std");
            if (tempAtts != null) {
                attachments = tempAtts;
            }
        }
        Map<String, Object> attachmentInfo = new HashMap<>(HRBaseConstants.INT_CAPACITY);
        // 绑定到协作单的附件标识attachmentpanel中
        attachmentInfo.put(HspmCommonConstants.ATTACHMENT_PANEL_AP, attachments);
        // 调用中台附件保存
        AttacheHandlerService attachmentHandler = AttacheHandlerService.getInstance();
        String removeUidString = this.getPageCache().get("removeUid");
        Set<String> removeUidSet = new HashSet<>();
        if (!HRStringUtils.isEmpty(removeUidString)) {
            removeUidSet = SerializationUtils.fromJsonString(removeUidString, Set.class);
        }
        removeUidSet.forEach(uid -> attachmentHandler.invokeRemoveAttachment(pageId, pkId, uid));
        attachmentHandler.invokeAttachment(pageId, pkId, "", attachmentInfo);
    }
}
