package ru.otus.mobile.db;

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

public final class DbClient {
    private final DbConfig config;
    private static final String DEFAULT_PASSWORD_HASH =
            "$2a$10$MUT3Px5CK0cy.vTesX9NaOpWAcbkrZHECe67Qwbh19sx3AlS8bK2C";

    public DbClient(DbConfig config) {
        this.config = config;
    }

    public void resetUserData(String username) {
        resetUserData(username, config.resetSql());
    }

    public void resetUserData(String username, String sql) {
        try (Connection connection = DriverManager.getConnection(
                config.url(),
                config.user(),
                config.password()
        )) {
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                int placeholders = countPlaceholders(sql);
                String passwordHash = System.getProperty("login.password.hash", DEFAULT_PASSWORD_HASH);
                String email = username + "@test.local";
                if (placeholders >= 1) {
                    statement.setString(1, username);
                }
                if (placeholders >= 2) {
                    statement.setString(2, email);
                }
                if (placeholders >= 3) {
                    statement.setString(3, passwordHash);
                }
                if (placeholders >= 4) {
                    statement.setString(4, username);
                }
                statement.execute();
            }
        } catch (SQLException e) {
            throw new IllegalStateException("Failed to reset data for user: " + username, e);
        }
    }

    public void resetReservationData(String username, String ownerUsername, String sql) {
        try (Connection connection = DriverManager.getConnection(
                config.url(),
                config.user(),
                config.password()
        )) {
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                String passwordHash = System.getProperty("login.password.hash", DEFAULT_PASSWORD_HASH);
                statement.setString(1, ownerUsername);
                statement.setString(2, ownerUsername + "@test.local");
                statement.setString(3, passwordHash);
                statement.setString(4, ownerUsername);
                statement.setString(5, username);
                statement.setString(6, username + "@test.local");
                statement.setString(7, passwordHash);
                statement.setString(8, username);
                statement.execute();
            }
        } catch (SQLException e) {
            throw new IllegalStateException("Failed to reset data for reservation user: " + username, e);
        }
    }

    public void updateWishlistTitle(String username, String oldTitle, String newTitle) {
        String sql = """
                UPDATE wishlists
                SET title = ?
                WHERE user_id = (SELECT id FROM users WHERE username = ?)
                  AND title = ?;
                """;
        try (Connection connection = DriverManager.getConnection(
                config.url(),
                config.user(),
                config.password()
        )) {
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                statement.setString(1, newTitle);
                statement.setString(2, username);
                statement.setString(3, oldTitle);
                statement.executeUpdate();
            }
        } catch (SQLException e) {
            throw new IllegalStateException("Failed to update wishlist title for user: " + username, e);
        }
    }

    private int countPlaceholders(String sql) {
        int count = 0;
        for (int i = 0; i < sql.length(); i++) {
            if (sql.charAt(i) == '?') {
                count++;
            }
        }
        return count;
    }
}
