package shine.db.dao;

import shine.db.SqliteDbController;
import shine.db.entities.TestFreeAvatarUploadEntry;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public final class TestFreeAvatarUploadsDAO {

    private static volatile TestFreeAvatarUploadsDAO instance;
    private final SqliteDbController db = SqliteDbController.getInstance();

    private TestFreeAvatarUploadsDAO() {
    }

    public static TestFreeAvatarUploadsDAO getInstance() {
        if (instance == null) {
            synchronized (TestFreeAvatarUploadsDAO.class) {
                if (instance == null) instance = new TestFreeAvatarUploadsDAO();
            }
        }
        return instance;
    }

    public TestFreeAvatarUploadEntry getByLogin(Connection c, String login) throws SQLException {
        String sql = """
            SELECT login, used_count, updated_at_ms, last_tx_id
            FROM test_free_avatar_uploads
            WHERE login = ? COLLATE NOCASE
            LIMIT 1
            """;
        try (PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, login);
            try (ResultSet rs = ps.executeQuery()) {
                if (!rs.next()) return null;
                return mapRow(rs);
            }
        }
    }

    public TestFreeAvatarUploadEntry getByLogin(String login) throws SQLException {
        try (Connection c = db.getConnection()) {
            return getByLogin(c, login);
        }
    }

    public void upsertUsage(Connection c, String login, int usedCount, long updatedAtMs, String lastTxId) throws SQLException {
        String sql = """
            INSERT INTO test_free_avatar_uploads (login, used_count, updated_at_ms, last_tx_id)
            VALUES (?, ?, ?, ?)
            ON CONFLICT(login) DO UPDATE SET
                used_count = excluded.used_count,
                updated_at_ms = excluded.updated_at_ms,
                last_tx_id = excluded.last_tx_id
            """;
        try (PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setString(1, login);
            ps.setInt(2, usedCount);
            ps.setLong(3, updatedAtMs);
            ps.setString(4, lastTxId);
            ps.executeUpdate();
        }
    }

    public void upsertUsage(String login, int usedCount, long updatedAtMs, String lastTxId) throws SQLException {
        try (Connection c = db.getConnection()) {
            upsertUsage(c, login, usedCount, updatedAtMs, lastTxId);
        }
    }

    private static TestFreeAvatarUploadEntry mapRow(ResultSet rs) throws SQLException {
        return new TestFreeAvatarUploadEntry(
                rs.getString("login"),
                rs.getInt("used_count"),
                rs.getLong("updated_at_ms"),
                rs.getString("last_tx_id")
        );
    }
}
