package me.km.playerbank;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import me.km.databank.DataBank;

public class PlayerBank implements IPlayerBank {
    private final PreparedStatement add;
    private final PreparedStatement changeName;
    private final PreparedStatement getId;
    private final PreparedStatement getUUIDfromID;
    private final PreparedStatement getNamefromID;
    private final PreparedStatement getUUID;

    public PlayerBank(DataBank databank) {
        databank.execute("CREATE TABLE IF NOT EXISTS players ("
                + "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
                + "uuid_1 BIGINT NOT NULL, "
                + "uuid_2 BIGINT NOT NULL, "
                + "name VARCHAR(20) NOT NULL, "
                + "UNIQUE INDEX (uuid_1, uuid_2));");

        add = databank.prepareStatement("INSERT INTO players (uuid_1,uuid_2,name) VALUES (?,?,?);");
        changeName = databank.prepareStatement("UPDATE players SET name=? WHERE uuid_1=? AND uuid_2=?;");
        getId = databank.prepareStatement("SELECT id FROM players WHERE uuid_1=? AND uuid_2=?;");
        getUUIDfromID = databank.prepareStatement("SELECT uuid_1,uuid_2 FROM players WHERE id=?;");
        getNamefromID = databank.prepareStatement("SELECT name FROM players WHERE id=?;");
        getUUID = databank.prepareStatement("SELECT uuid_1,uuid_2 FROM players WHERE name=?;");
    }

    @Override
    public boolean add(UUID uuid, String name) {
        try {
            add.setLong(1, uuid.getLeastSignificantBits());
            add.setLong(2, uuid.getMostSignificantBits());
            add.setString(3, name);
            add.executeUpdate();
            return true;
        } catch(SQLException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public void changeName(UUID uuid, String name) {
        try {
            changeName.setString(1, name);
            changeName.setLong(2, uuid.getLeastSignificantBits());
            changeName.setLong(3, uuid.getMostSignificantBits());
            changeName.executeUpdate();
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public int getId(UUID uuid) {
        try {
            getId.setLong(1, uuid.getLeastSignificantBits());
            getId.setLong(2, uuid.getMostSignificantBits());
            try(ResultSet rs = getId.executeQuery()) {
                if(rs.next()) {
                    return rs.getInt(1);
                }
                return -1;
            } catch(SQLException ex) {
                ex.printStackTrace();
            }
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
        return -1;
    }

    @Override
    public UUID getUUIDfromID(int id) {
        try {
            getUUIDfromID.setInt(1, id);
            try(ResultSet rs = getUUIDfromID.executeQuery()) {
                if(rs.next()) {
                    return new UUID(rs.getLong(2), rs.getLong(1));
                }
            } catch(SQLException ex) {
                ex.printStackTrace();
            }
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    public String getNamefromID(int id) {
        try {
            getNamefromID.setInt(1, id);
            try(ResultSet rs = getNamefromID.executeQuery()) {
                if(rs.next()) {
                    return rs.getString(1);
                }
            } catch(SQLException ex) {
                ex.printStackTrace();
            }
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
        return "";
    }

    @Override
    public UUID getUUID(String name) {
        try {
            getUUID.setString(1, name);
            try(ResultSet rs = getUUID.executeQuery()) {
                if(rs.next()) {
                    return new UUID(rs.getLong(2), rs.getLong(1));
                }
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }
}
