package nccloud.web.fbm.fbm.gather.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.JdbcSession;
import nc.jdbc.framework.PersistenceManager;
import nc.jdbc.framework.exception.DbException;
import nc.jdbc.framework.processor.MapListProcessor;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;

import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 收票登记-到账通知推送按钮
 * 2005适配2312
 *
 * @author mzr
 * @date 2025/04/03
 */
public class DzButton implements ICommonAction {

    @Override
    public Object doAction(IRequest request) {
        // 初始化结果映射，用于存储处理结果
        HashMap<String, String> resultMap = new HashMap<String, String>();
        // 读取请求中的JSON数据

        String json = request.read();
        Map<String, Object> maps = JSON.parseObject(json, Map.class);
        if (maps.get("pks") == null) {
            resultMap.put("result", "请选择行");
            return resultMap;
        }
        int yg = 0;
        int cg = 0;
        int sbl = 0;

        JSONArray jsonArray = (JSONArray) maps.get("pks");
        ArrayList<Object> pks = new ArrayList<>(Arrays.asList(jsonArray.toArray()));

// 使用 String.join 进行字符串拼接
        String result = "";
        StringBuilder sb = new StringBuilder();
        if (pks.size() > 1) {
            for (int i = 0; i < pks.size(); i++) {
                sb.append("'").append(pks.get(i)).append("'");
                if (i < pks.size() - 1) {
                    sb.append(",");
                }
            }

            result = sb.toString();
        } else {
            result = "'" + (String) pks.get(0) + "'";
        }
        // 如果账单编号为空，则返回失败结果
        try {
            // 获取当前年份
            String sql = "select fbm.gatherdate,bank1.pk_bankdoc as fkyh,bank2.pk_bankdoc as  skyh,fbm.acceptorbank,fbm.hidereceivebankacc ,holdunit,org.name as orgname , reg.name as pjname,xxb_bon.bdcode,btype.pk_balatype,reg.code,xxe.exsystemcode,\n" +
                    "xxb_bon.exsysval\n" +
                    ",invoiceunit,fbmbilltype,fbm.fbmbillno,fbm.pk_register, paybankacc as bankaccount,fbm.payunit,cust.name as bankname,fbm.billmaker,fbm.creator,fbm.note,fbm.money,cust.custsupprop ,cust.custsuptype,fbm.pk_banktype ,fbm.pk_org ,fbm.pk_org_v,fbm.hidereceiveunit, fbm.hidepayunit,fbm.hidepaybankacc ,fbm.hidepaybank ,fbm.paybankacc ,fbm.paybank ,fbm.receiveunit,fbm.receivebankacc ,fbm.receivebank ,hidereceivebank, bankdoc.pk_bankaccbas ,fbm.pk_group,fbm.billrange  \n" +
                    "from fbm_register fbm \n" +
                    "left join bd_cust_supplier cust on fbm.hidepayunit=cust.pk_cust_sup  \n" +
                    "left join bd_bankaccbas   bankdoc on fbm.receivebankacc = bankdoc.code\n" +
                    "left join bd_notetype  reg on fbm.fbmbilltype=reg.pk_notetype\n" +
                    "join xx_bdcontra_b xxb_bon  on xxb_bon.exsysval=reg.code\n" +
                    "join xx_bdcontra xxb on xxb.pk_contra=xxb_bon.pk_contra\n" +
                    "join xx_exsystem xxe on xxe.pk_exsystem =xxb.exsystem and xxe.exsystemcode='pkinformer'\n" +
                    "left join org_financeorg  org on org.pk_financeorg=fbm.holdunit\n" +
                    "left   join bd_bankdoc bank1 on fbm.paybank =bank1.name\n" +
                    "left   join bd_bankdoc bank2 on fbm.receivebank =bank2.name\n" +
                    "left join bd_balatype btype on btype.code=xxb_bon.bdcode " +

                    " where  fbm.pk_register in(" + result + ") ";
            List<Map<String, Object>> results = (List<Map<String, Object>>) getQueryService().executeQuery(sql, new MapListProcessor());

            List sqlStr = new ArrayList();
            LocalDateTime creationTime = LocalDateTime.now();

// 格式化年月日

            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = creationTime.format(dateFormatter);
            // 格式化时分秒
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
            String formattedTime = creationTime.format(timeFormatter);

// 格式化时间
            DateTimeFormatter datatimes = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String formatteddatatime = creationTime.format(datatimes);
            yg = results.size();
            for (int i = 0; i < results.size(); i++) {

                Map<String, Object> row = results.get(i);
                String bankAccount = (String) row.get("receivebankacc");
                String gatherdate = (String) row.get("gatherdate");
                // 本方开户银行名称
                String bankName = (String) row.get("receiveunit");
                // 制单人
                String billMaker = (String) row.get("billmaker");
                // 托收协议号
                String consignAgreement = "~";
                // 记录创建时间
                String sj = formatteddatatime;
                // 创建人
                String creator = (String) row.get("creator");
                // 收付性质
                String direction = "receivemoney";
                // （未明确用途，可根据实际情况使用）
                String domain = "~";
                // 制单日期
                String doOperateDate = formatteddatatime;
                // 制单时间
                String doOperateTime = formattedTime;
                // 标记，通常用于逻辑删除，0 表示未删除
                int dr = 0;
                // （未明确用途，可根据实际情况使用）
                String family = "~";
                // 未生成标志
                String generateFlag = "hasnogenerate";
                // 到账日期
                String infoDate = gatherdate;
                // 到账时间
                String infoDateTime = formattedTime;
                // 备注
                String memo = (String) row.get("note");
                // 修改时间
                String modifiedTime = formatteddatatime;
                // 修改人
                String modifier = (String) row.get("creator");
                // 金额
                double money = Double.parseDouble(row.get("money").toString());
                // 对方账户
                String oppBankAccount = (String) row.get("paybankacc");
                // 对方单位内外部标识 custsupprop 0=外部单位;
                // 1=内部单位;

                String oppInOut;
                if (row.get("custsupprop") != null && row.get("custsupprop").toString().equals("0")) {
                    oppInOut = "outer";
                } else {
                    oppInOut = "inner";
                }
                // 对方名称
                String oppUnitName = (String) row.get("payunit");
                // 对方单位类别
                Object custsuptype = row.get("custsuptype");
                String oppUnitType = "cust"; // 默认值

                if (custsuptype != null && custsuptype.toString().equals("2")) {
                    oppUnitType = "supp";
                }

                // 本方账户对应子户
                String pkAccSub = (String) row.get("hidereceivebankacc");
                // （未明确用途，可根据实际情况使用）
                String pk_balatype = (String) row.get("pk_balatype");
                // 本方开户银行主键
                String pkBank = (String) row.get("skyh");
                // 本方银行账号主键
                String pkBankAcc = (String) row.get("pk_bankaccbas");// 1
                // 记账人
                String pkBankAccer = "~";
                // 本方银行类别主键
                String pkBankType = (String) row.get("pk_banktype");

                // 对方单位
                String pk_oppunit = (String) row.get("hidepayunit");
                // 对方开户银行账号主键
                String pk_oppbank = (String) row.get("fkyh");
                // 对方账户PK
                String pk_oppacc = (String) row.get("hidepaybankacc");


                // 单据类型
                String pkBillTypeCode = "36S3";
                // 单据类型主键
                String pkBillTypeId = "1001Z61000000001SOPF";
                // （未明确用途，可根据实际情况使用）
                String pkClaimer = "~";
                // 币种
                String pkCurrType = "1002Z0100000000001K1";
                // （未明确用途，可根据实际情况使用）
                String pkFundType = "~";
                // 所属集团
                String pkGroup = (String) row.get("pk_group");
                // （未明确用途，可根据实际情况使用主键）
                String pkInformer = (String) row.get("pk_register");
                // （未明确用途，可根据实际情况使用）
                String pkOrg = (String) row.get("pk_org");
                // 财务组织版本
                String pkOrgV = (String) row.get("pk_org_v");
                // 来源单据主键
                String pkSrc = null;
                // 制证人
                String pkVouch = (String) row.get("billmaker");
                // 收/付款资金组织
                String recPayFundOrg = "~";
                // 收/付款资金组织计划项目
                String recPayFundPlansubj = "~";
                // （未明确用途，可根据实际情况使用）
                String recPayInnerAcc = "~";
                // （未明确用途，可根据实际情况使用）
                String recPayOrg = "~";
                // （未明确用途，可根据实际情况使用）
                String recPayOrgPlansubj = "~";
                // （未明确用途，可根据实际情况使用）
                String releaseOrg = "~";
                // 风格标志，A 可能表示某种风格类型
                char styleFlag = 'A';
                // （未明确用途，可根据实际情况使用）
                String subFamily = "~";
                // 系统代码
                String sysCode = "sysnet";
                // 时间戳
                String ts = formatteddatatime;
                // 单据号
                long timestamp = System.currentTimeMillis();
                Random random = new Random();
                int randomNumber = random.nextInt(10000); // 生成0到9999之间的随机数
                String vBillNo = "36S" + String.format("%d%04d", timestamp, randomNumber);
                String note_no = (String) row.get("fbmbillno");
                //对账标识码
                String bankrelated_code = "";//sunfj2 流水对账标识码 = 票据号+子票区间 
                if(row.get("billrange")!=null && !"".equals(String.valueOf(row.get("billrange")))) {
                	 bankrelated_code= (String)row.get("fbmbillno")+(String)row.get("billrange");
                }
               
                // String sqlp="insert into cmp_informer(bankaccount,bankname,billmaker,consignagreement,creationtime,creator,direction,domain,doperatedate,doperatetime,dr,family,generateflag,infodate,infodatetime,memo,modifiedtime,modifier,moneyy,oppbankaccount,oppinout,oppunitname,oppunittype,pk_acc_sub,pk_balatype,pk_bank,pk_bankacc,pk_bankaccer,pk_banktype,pk_billtypecode,pk_billtypeid,pk_claimer,pk_currtype,pk_fundtype,pk_group,pk_informer,pk_org,pk_org_v,pk_src,pk_vouch,recpay_fundorg,recpay_fundplansubj,recpay_inneracc,recpay_org,recpay_orgplansubj,release_org,styleflag,subfamily,syscode,ts,vbillno) values('"+num+"','济南热电有限公司','1001A110000000003Q0I','~','"+dam+"','1001A110000000003Q0I','"+pr+"','~','"+transactionDate+"','"+dam+"','0','~','hasnogenerate','"+transactionDate+"','"+timesub+"','"+zhaiYao+"','"+dam+"','1001A110000000003Q0I',"+money+",'"+oppositeAccountNumber+"','"+opp+"','"+oppositeUserName+"','"+opptype+"','"+select[2]+"','~','"+select[0]+"','"+select[1]+"','~','"+select3[0]+"','36S3','1001Z61000000001SOPF','~','1002Z0100000000001K1','~','0001N2100000000002ZE','"+vId+"','0001N710000000001FWC','0001N710000000001FWB','1001A110000000007IWJ','~','~','~','~','~','~','~','A','~','sysnet','"+dam+"','"+fId2+"')"
                // 形成sql
                String sqlp = "insert into cmp_informer(bankaccount,bankname,billmaker,consignagreement,creationtime,creator,direction,domain,doperatedate,doperatetime,dr,family,generateflag,infodate,infodatetime,memo,modifiedtime,modifier,moneyy,oppbankaccount,oppinout,oppunitname,oppunittype,pk_acc_sub,pk_balatype,pk_bank,pk_bankacc,pk_bankaccer,pk_banktype,pk_billtypecode,pk_billtypeid,pk_claimer,pk_currtype,pk_fundtype,pk_group,pk_informer,pk_org,pk_org_v,pk_src,pk_vouch,recpay_fundorg,recpay_fundplansubj,recpay_inneracc,recpay_org,recpay_orgplansubj,release_org,styleflag,subfamily,syscode,ts,vbillno,note_no,pk_oppunit,pk_oppbank,pk_oppacc,bankrelated_code) values('"
                        + bankAccount + "','" + bankName + "','" + billMaker + "','" + consignAgreement + "','" + formatteddatatime + "','" + creator + "','" + direction + "','" + domain + "','" + doOperateDate + "','" + sj + "','" + dr + "','" + family + "','" + generateFlag + "','" + infoDate + "','" + infoDateTime + "','" + memo + "','" + modifiedTime + "','" + modifier + "','" + money + "','" + oppBankAccount + "','" + oppInOut + "','" + oppUnitName + "','" + oppUnitType + "','" + pkAccSub + "','" + pk_balatype + "','" + pkBank + "','" + pkBankAcc + "','" + pkBankAccer + "','" + pkBankType + "','" + pkBillTypeCode + "','" + pkBillTypeId + "','" + pkClaimer + "','" + pkCurrType + "','" + pkFundType + "','" + pkGroup + "','" + pkInformer + "','" + pkOrg + "','" + pkOrgV + "','" + pkSrc + "','" + pkVouch + "','" + recPayFundOrg + "','" + recPayFundPlansubj + "','" + recPayInnerAcc + "','" + recPayOrg + "','" + recPayOrgPlansubj + "','" + releaseOrg + "','" + styleFlag + "','" + subFamily + "','" + sysCode + "','" + ts + "','" + vBillNo + "','" + note_no + "','" + pk_oppunit + "','" + pk_oppbank + "','" + pk_oppacc + "','" + bankrelated_code + "')";
                sqlStr.add(sqlp);
            }
            int succState = executeUpdate(sqlStr);
            cg = succState;
            sbl = yg - succState;
            resultMap.put("flag", "1");
            resultMap.put("message", "插入数据成功，已插入" + succState + "条数据");
            resultMap.put("cg", String.valueOf(cg));
            resultMap.put("sbl", String.valueOf(sbl));
            resultMap.put("yg", String.valueOf(yg));
            // lists转json
        } catch (Exception ex) {
            // 捕获异常，并记录错误日志
            resultMap.put("cg", String.valueOf(0));
            resultMap.put("sbl", String.valueOf(yg));
            resultMap.put("yg", String.valueOf(yg));
            resultMap.put("flag", "0");
            resultMap.put("message", ex.getMessage());
        }
        // 返回结果映射
        return resultMap;
    }

    public IUAPQueryBS getQueryService() {
        return ServiceLocator.find(IUAPQueryBS.class);
    }


    public int executeUpdate(List<String> updateSqls) throws DbException {
        if (updateSqls == null) {
            return 0;
        }

        int ret = 0;
        PersistenceManager manager = null;
        JdbcSession session = null;
        Connection connection = null;

        try {
            manager = PersistenceManager.getInstance();
            session = manager.getJdbcSession();
            connection = session.getConnection();  // 获取实际的数据库连接

            // 开始事务
            connection.setAutoCommit(false);  // 禁用自动提交，手动管理事务

            // 执行批量操作
            for (String sql : updateSqls) {
                session.addBatch(sql);
            }

            // 执行批处理
            ret = session.executeBatch();

            // 提交事务
            connection.commit();  // 批处理成功后提交事务

        } catch (DbException e) {
            if (connection != null) {
                try {
                    // 如果发生异常，回滚事务
                    connection.rollback();
                } catch (SQLException rollbackEx) {
                    // 记录回滚异常的详细信息
                    throw new DbException("Error during transaction rollback", rollbackEx) {
                        @Override
                        public boolean isDataIntegrityViolation() {
                            return false;
                        }

                        @Override
                        public boolean isBadSQLGrammar() {
                            return false;
                        }
                    };
                }
            }
            throw e;  // 将原始异常抛出
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if (connection != null) {
                try {
                    // 恢复自动提交模式，确保不会影响其他操作
                    connection.setAutoCommit(true);
                } catch (SQLException e) {
                    // 忽略恢复自动提交时的异常
                }
            }
            if (manager != null) {
                manager.release();
            }
        }

        return ret;
    }


}