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

import com.infoepoch.pms.dispatchassistant.common.utils.OracleUtils;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.line.history.ConversationLineHistory;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.line.history.ConversationLineHistoryCriteria;
import com.infoepoch.pms.dispatchassistant.domain.langchain.record.conversation.line.history.IConversationLineHistoryRepository;
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class ConversationLineHistoryRepository implements IConversationLineHistoryRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void insert(ConversationLineHistory entity) {
        String sql = "INSERT INTO AI_CONVERSATION_LINE_HISTORY(CLH_ID, CLH_LINE_ID, CLH_ROLE, CLH_CONTENT, CLH_SEQUENCE) VALUES (?, ?, ?, ?, ?)";
        jdbcTemplate.update(sql, entity.getId(), entity.getLineId(), entity.getRole(), entity.getContent(), entity.getSequence());
    }

    @Override
    public void batchInsert(List<ConversationLineHistory> list) {
        String sql = "INSERT INTO AI_CONVERSATION_LINE_HISTORY(CLH_ID, CLH_LINE_ID, CLH_ROLE, CLH_CONTENT, CLH_SEQUENCE) VALUES (?, ?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ConversationLineHistory history = list.get(i);
                int j = 0;
                ps.setString(++j, history.getId());
                ps.setString(++j, history.getLineId());
                ps.setString(++j, history.getRole());
                ps.setString(++j, history.getContent());
                ps.setObject(++j, history.getSequence());
            }

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

    @Override
    public void update(ConversationLineHistory entity) {
        String sql = "UPDATE AI_CONVERSATION_LINE_HISTORY SET CLH_LINE_ID = ?, CLH_ROLE = ?, CLH_CONTENT = ?, CLH_SEQUENCE = ? WHERE CLH_ID = ?";
        jdbcTemplate.update(sql, entity.getLineId(), entity.getRole(), entity.getContent(), entity.getSequence(), entity.getId());
    }

    @Override
    public void batchUpdate(List<ConversationLineHistory> list) {
        String sql = "UPDATE AI_CONVERSATION_LINE_HISTORY SET CLH_LINE_ID = ?, CLH_ROLE = ?, CLH_CONTENT = ?, CLH_SEQUENCE = ? WHERE CLH_ID = ?";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ConversationLineHistory history = list.get(i);
                int j = 0;
                ps.setString(++j, history.getLineId());
                ps.setString(++j, history.getRole());
                ps.setString(++j, history.getContent());
                ps.setObject(++j, history.getSequence());
                ps.setString(++j, history.getId());
            }

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

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

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

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

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

    private ConversationLineHistory convertRowSet(SqlRowSet rowSet) {
        return new ConversationLineHistory(
                rowSet.getString("CLH_ID"),
                rowSet.getString("CLH_LINE_ID"),
                rowSet.getString("CLH_ROLE"),
                rowSet.getString("CLH_CONTENT"),
                rowSet.getObject("CLH_SEQUENCE") == null ? null : rowSet.getInt("CLH_SEQUENCE")
        );
    }

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

        return andMap;
    }

}
