package com.lagopusempire.multihomes.homeIO.database;

import com.lagopusempire.multihomes.home.Home;
import com.lagopusempire.multihomes.home.LoadResult;
import com.lagopusempire.multihomes.homeIO.HomeIO;
import com.lagopusempire.multihomes.homeIO.HomeListLoadedCallback;
import com.lagopusempire.multihomes.homeIO.HomeLoadedCallback;
import com.lagopusempire.multihomes.homeIO.HomesLoadedCallback;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;

import static com.lagopusempire.multihomes.homeIO.database.ScriptKeys.*;

/**
 *
 * @author MrZoraman
 */
public class DBHomeIO implements HomeIO
{
    private final JavaPlugin plugin;
    private final Connection conn;
    
    public DBHomeIO(JavaPlugin plugin, Connection conn)
    {
        this.plugin = plugin;
        this.conn = conn;
    }

    @Override
    public void saveHome(final Home home, final Runnable callback)
    {
        final UUID uuid = home.getOwner();
        
        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> 
        {
            if(getHome(uuid, home.getName()) == null)
            {
                //home does not exist
                final String query = Scripts.getScript(CREATE_HOME);
                
            }
            else
            {
                //home exists, update it
            }
            
            plugin.getServer().getScheduler().runTask(plugin, () -> callback.run());
        });
    }

    @Override
    public void loadHomes(UUID uuid, HomesLoadedCallback callback)
    {
        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> 
        {
            final Map<String, Home> homes = new HashMap<>();
            
            
            plugin.getServer().getScheduler().runTask(plugin, () -> callback.homesLoaded(homes));
        });
        
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void loadHome(UUID uuid, String homeName, HomeLoadedCallback callback)
    {
        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> 
        {
            final Home home = getHome(uuid, homeName);
            
            plugin.getServer().getScheduler().runTask(plugin, () -> callback.homeLoaded(home));
        });
    }

    @Override
    public void getHomeList(UUID uuid, HomeListLoadedCallback callback)
    {
        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> 
        {
            
            
            plugin.getServer().getScheduler().runTask(plugin, () -> 
            {
                
            });
        });
        
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    private Home getHome(UUID uuid, String homeName)
    {
        final String loadHomeQuery = Scripts.getScript(LOAD_HOME);
        try(final PreparedStatement stmt = conn.prepareStatement(loadHomeQuery))
        {
            stmt.setString(1, uuid.toString());
            stmt.setString(2, homeName);

            try(final ResultSet rs = stmt.executeQuery())
            {
                if(rs.next())
                {
                    final double x = rs.getDouble("x");
                    final double y = rs.getDouble("y");
                    final double z = rs.getDouble("z");
                    final float yaw = rs.getFloat("yaw");
                    final float pitch = rs.getFloat("pitch");
                    final String worldName = rs.getString("world_name");

                    final World world = Bukkit.getWorld(worldName);
                    if(world == null)
                    {
                        return new Home(uuid, homeName, LoadResult.NO_WORLD);
                    }
                    else
                    {
                        final Location loc = new Location(world, x, y, z, yaw, pitch);
                        return new Home(uuid, homeName, loc);
                    }
                }
                else
                {
                    return new Home(uuid, homeName, LoadResult.DOES_NOT_EXIST);
                }
            }
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();
        }
        
        throw new IllegalStateException("Undefined state in DBHomeIO! (This is the developer's problem)");
    }
}

@@ -1644,206 +1644,1862 @@
     
-%0A            %7D%0A            else%0A            %7B%0A                //home exists, update it%0A            %7D%0A            %0A            plugin.getServer().getScheduler().runTask(plugin, () -%3E callback.run());
+try(final PreparedStatement stmt = conn.prepareStatement(query))%0A                %7B%0A                    stmt.setString(1, home.getOwner().toString());%0A                    stmt.setString(2, home.getName());%0A                    stmt.setDouble(3, home.getLoc().getX());%0A                    stmt.setDouble(4, home.getLoc().getY());%0A                    stmt.setDouble(5, home.getLoc().getZ());%0A                    stmt.setFloat (6, home.getLoc().getYaw());%0A                    stmt.setFloat (7, home.getLoc().getPitch());%0A                    stmt.setString(8, home.getLoc().getWorld().getName());%0A                    %0A                    stmt.execute();%0A                    %0A                    plugin.getServer().getScheduler().runTask(plugin, () -%3E callback.run());%0A                %7D%0A                catch (SQLException e)%0A                %7B%0A                    e.printStackTrace();%0A                %7D%0A            %7D%0A            else%0A            %7B%0A                //home exists, update it%0A                final String query = Scripts.getScript(UPDATE_HOME);%0A                try(final PreparedStatement stmt = conn.prepareStatement(query))%0A                %7B%0A                    stmt.setDouble(1, home.getLoc().getX());%0A                    stmt.setDouble(2, home.getLoc().getY());%0A                    stmt.setDouble(3, home.getLoc().getZ());%0A                    stmt.setFloat (4, home.getLoc().getYaw());%0A                    stmt.setFloat (5, home.getLoc().getPitch());%0A                    stmt.setString(6, home.getLoc().getWorld().getName());%0A                    %0A                    stmt.execute();%0A                    %0A                    plugin.getServer().getScheduler().runTask(plugin, () -%3E callback.run());%0A                %7D%0A                catch (SQLException e)%0A                %7B%0A                    e.printStackTrace();%0A                %7D%0A            %7D
 %0A   

save home implemented