package com.infoepoch.pms.dispatchassistant.infractructure.langchain;


import com.infoepoch.pms.dispatchassistant.common.utils.OracleUtils;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.Conversation;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.ConversationCriteria;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.IConversationRepository;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class ConversationRepository implements IConversationRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void insert(Conversation entity) {
        String sql = "INSERT INTO AI_CONVERSATION(C_ID, C_CREATE_TIME, C_USER_ID, C_USER_NAME, C_TYPE, C_LAST_CHAT_TIME) VALUES ( ?, ?, ?, ?, ?, ? )";
        jdbcTemplate.update(sql, entity.getId(), entity.getCreateTime(), entity.getUserId(), entity.getUserName(), entity.getType(),
                entity.getLastChatTime());
    }

    @Override
    public void batchInsert(List<Conversation> list) {
        String sql = "INSERT INTO AI_CONVERSATION(C_ID, C_CREATE_TIME, C_USER_ID, C_USER_NAME, C_TYPE, C_LAST_CHAT_TIME) VALUES ( ?, ?, ?, ?, ?, ? )";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Conversation entity = list.get(i);
                int j = 0;
                ps.setString(++j, entity.getId());
                ps.setTimestamp(++j, entity.getCreateTime() == null ? null : new Timestamp(entity.getCreateTime().getTime()));
                ps.setString(++j, entity.getUserId());
                ps.setString(++j, entity.getUserName());
                ps.setString(++j, entity.getType());
                ps.setTimestamp(++j, entity.getLastChatTime() == null ? null : new Timestamp(entity.getLastChatTime().getTime()));
            }

            @Override
            public int getBatchSize() {
                return list.size();
            }
        });
    }

    @Override
    public void update(Conversation entity) {
        String sql = "UPDATE AI_CONVERSATION SET C_CREATE_TIME = ?, C_USER_ID = ?, C_USER_NAME = ?, C_TYPE = ?, C_LAST_CHAT_TIME = ? WHERE C_ID = ?";
        jdbcTemplate.update(sql, entity.getCreateTime(), entity.getUserId(), entity.getUserName(), entity.getType(),
                entity.getLastChatTime(), entity.getId());
    }

    @Override
    public void batchUpdate(List<Conversation> list) {
        String sql = "UPDATE AI_CONVERSATION SET C_CREATE_TIME = ?, C_USER_ID = ?, C_USER_NAME = ?, C_TYPE = ?, C_LAST_CHAT_TIME = ? WHERE C_ID = ?";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Conversation entity = list.get(i);
                int j = 0;
                ps.setTimestamp(++j, entity.getCreateTime() == null ? null : new Timestamp(entity.getCreateTime().getTime()));
                ps.setString(++j, entity.getUserId());
                ps.setString(++j, entity.getUserName());
                ps.setString(++j, entity.getType());
                ps.setTimestamp(++j, entity.getLastChatTime() == null ? null : new Timestamp(entity.getLastChatTime().getTime()));
                ps.setString(++j, entity.getId());
            }

            @Override
            public int getBatchSize() {
                return list.size();
            }
        });
    }

    @Override
    public Conversation selectById(String id) {
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet("SELECT * FROM AI_CONVERSATION WHERE C_ID = ?", id);
        if (sqlRowSet.next()) {
            return convertRowSet(sqlRowSet);
        }
        return null;
    }

    @Override
    public List<Conversation> selectByCriteria(ConversationCriteria criteria) {
        StringBuffer sql = new StringBuffer("SELECT * FROM AI_CONVERSATION");
        List<Object> params = OracleUtils.combinationSql(sql, createAndMap(criteria), "C_LAST_CHAT_TIME", true);
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql.toString(), params.toArray());
        List<Conversation> list = new ArrayList<>();
        while (sqlRowSet.next()) {
            list.add(convertRowSet(sqlRowSet));
        }
        return list;
    }

    @Override
    public List<Conversation> selectByCriteriaPage(ConversationCriteria criteria, int pageIndex, int pageSize) {
        StringBuffer sql = new StringBuffer("SELECT * FROM AI_CONVERSATION");
        List<Object> params = OracleUtils.combinationSql(sql, createAndMap(criteria), pageIndex, pageSize, "C_LAST_CHAT_TIME", true);
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql.toString(), params.toArray());
        List<Conversation> list = new ArrayList<>();
        while (sqlRowSet.next()) {
            list.add(convertRowSet(sqlRowSet));
        }
        return list;
    }

    @Override
    public int selectByCriteriaCount(ConversationCriteria criteria) {
        StringBuffer sql = new StringBuffer("SELECT COUNT(1) FROM AI_CONVERSATION");
        List<Object> params = OracleUtils.combinationSql(sql, createAndMap(criteria));
        return jdbcTemplate.queryForObject(sql.toString(), params.toArray(), int.class);
    }

    private Conversation convertRowSet(SqlRowSet rowSet) {
        return new Conversation(
                rowSet.getString("C_ID"),
                rowSet.getTimestamp("C_CREATE_TIME"),
                rowSet.getString("C_USER_ID"),
                rowSet.getString("C_USER_NAME"),
                rowSet.getString("C_TYPE"),
                rowSet.getTimestamp("C_LAST_CHAT_TIME")
        );
    }

    private Map<String, Object> createAndMap(ConversationCriteria criteria) {
        Map<String, Object> andMap = new HashMap<>();

        // 用户ID
        if (StringUtils.isNotBlank(criteria.getUserId())) {
            andMap.put(" C_USER_ID = ? ", criteria.getUserId());
        }
        // 用户名称（LIKE）
        if (StringUtils.isNotBlank(criteria.getUserNameContain())) {
            andMap.put(" C_USER_NAME LIKE ? ", "%" + criteria.getUserNameContain() + ")%");
        }
        // 类别
        if (StringUtils.isNotBlank(criteria.getType())) {
            andMap.put(" C_TYPE = ? ", criteria.getType());
        }

        return andMap;
    }

}
