/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pw.yumc.Residence.economy;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.bukkit.ChatColor;
import org.bukkit.entity.Player;

import com.bekvon.bukkit.residence.permissions.PermissionGroup;
import com.bekvon.bukkit.residence.permissions.PermissionManager;
import com.bekvon.bukkit.residence.protection.ClaimedResidence;
import com.bekvon.bukkit.residence.protection.CuboidArea;
import com.bekvon.bukkit.residence.protection.ResidenceManager;

import pw.yumc.Residence.ResidenceMain;

/**
 *
 * @author Administrator
 */
public class TransactionManager {
    private Map<String, Integer> sellAmount;
    PermissionManager gmanager;
    ResidenceManager manager;
    ResidenceMain plugin;

    public TransactionManager(final ResidenceMain plugin, final ResidenceManager m, final PermissionManager g) {
        this.plugin = plugin;
        gmanager = g;
        manager = m;
        sellAmount = Collections.synchronizedMap(new HashMap<String, Integer>());
    }

    public static boolean chargeEconomyMoney(final ResidenceMain plugin, final Player player, final int amount) {
        final EconomyInterface econ = plugin.getEconomyManager();
        if (econ == null) {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("MarketDisabled"));
            return false;
        }
        if (!econ.canAfford(player.getName(), amount)) {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NotEnoughMoney"));
            return false;
        }
        econ.subtract(player.getName(), amount);
        player.sendMessage(ChatColor.GREEN
                + plugin.getLanguage().getPhrase("MoneyCharged", ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN));
        return true;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static TransactionManager load(final ResidenceMain plugin, final Map root, final PermissionManager p, final ResidenceManager r) {
        final TransactionManager tman = new TransactionManager(plugin, r, p);
        if (root != null) {
            tman.sellAmount = root;
        }
        return tman;
    }

    public void buyPlot(final String areaname, final Player player, final boolean resadmin) {
        final PermissionGroup group = gmanager.getGroup(player);
        if (!resadmin) {
            if (!plugin.getConfigManager().enableEconomy() || plugin.getEconomyManager() == null) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("MarketDisabled"));
                return;
            }
            final boolean canbuy = group.canBuyLand() || player.hasPermission("plugin.buy");
            if (!canbuy && !resadmin) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NoPermission"));
                return;
            }
        }
        if (isForSale(areaname)) {
            final ClaimedResidence res = manager.getByName(areaname);
            if (res == null) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("InvalidArea"));
                sellAmount.remove(areaname);
                return;
            }
            if (res.getPermissions().getOwner().equals(player.getName())) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("OwnerBuyFail"));
                return;
            }
            if (plugin.getResidenceManager().getOwnedZoneCount(player.getName()) >= group.getMaxZones() && !resadmin) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("ResidenceTooMany"));
                return;
            }
            final int amount = sellAmount.get(areaname);
            if (!resadmin) {
                if (!group.buyLandIgnoreLimits()) {
                    final CuboidArea[] areas = res.getAreaArray();
                    for (final CuboidArea thisarea : areas) {
                        if (!group.inLimits(thisarea)) {
                            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("ResidenceBuyTooBig"));
                            return;
                        }
                    }
                }
            }
            final EconomyInterface econ = plugin.getEconomyManager();
            if (econ == null) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("MarketDisabled"));
                return;
            }
            final String buyerName = player.getName();
            String sellerName = res.getPermissions().getOwner();
            final Player sellerNameFix = plugin.getServer().getPlayer(sellerName);
            if (sellerNameFix != null) {
                sellerName = sellerNameFix.getName();
            }
            if (econ.canAfford(buyerName, amount)) {
                if (!econ.transfer(buyerName, sellerName, amount)) {
                    player.sendMessage(ChatColor.RED + "Error, could not transfer " + amount + " from " + buyerName + " to " + sellerName);
                    return;
                }
                res.getPermissions().setOwner(player.getName(), true);
                res.getPermissions().applyDefaultFlags();
                this.removeFromSale(areaname);
                player.sendMessage(ChatColor.GREEN
                        + plugin.getLanguage().getPhrase("MoneyCharged", ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN));
                player.sendMessage(ChatColor.GREEN + plugin.getLanguage().getPhrase("ResidenceBought", ChatColor.GREEN + areaname + ChatColor.YELLOW));
                final Player seller = plugin.getServer().getPlayer(sellerName);
                if (seller != null && seller.isOnline()) {
                    seller.sendMessage(ChatColor.GREEN
                            + plugin.getLanguage().getPhrase("ResidenceBuy", ChatColor.YELLOW + player.getName() + ChatColor.GREEN + "." + ChatColor.YELLOW + areaname + ChatColor.GREEN));
                    seller.sendMessage(ChatColor.GREEN + plugin.getLanguage().getPhrase("MoneyCredit",
                            ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN));
                }
            } else {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NotEnoughMoney"));
            }
        } else {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("InvalidResidence"));
        }
    }

    public void clearSales() {
        sellAmount.clear();
        System.out.println("[Residence] - ReInit land selling.");
    }

    public int getSaleAmount(final String name) {
        return sellAmount.get(name);
    }

    public boolean isForSale(final String areaname) {
        return sellAmount.containsKey(areaname);
    }

    public void printForSaleResidences(final Player player) {
        final Set<Entry<String, Integer>> set = sellAmount.entrySet();
        player.sendMessage(ChatColor.YELLOW + plugin.getLanguage().getPhrase("LandForSale") + ":");
        final StringBuilder sbuild = new StringBuilder();
        sbuild.append(ChatColor.GREEN);
        boolean firstadd = true;
        for (final Entry<String, Integer> land : set) {
            if (!firstadd) {
                sbuild.append(", ");
            } else {
                firstadd = false;
            }
            sbuild.append(land.getKey());
        }
        player.sendMessage(sbuild.toString());
    }

    public boolean putForSale(final String areaname, final int amount) {
        if (plugin.getConfigManager().enabledRentSystem()) {
            if (plugin.getRentManager().isForRent(areaname)) {
                return false;
            }
        }
        final ClaimedResidence area = manager.getByName(areaname);
        if (area == null) {
            return false;
        }
        if (sellAmount.containsKey(areaname)) {
            return false;
        }
        sellAmount.put(areaname, amount);
        return true;
    }

    public void putForSale(final String areaname, final Player player, final int amount, final boolean resadmin) {
        if (plugin.getConfigManager().enabledRentSystem()) {
            if (plugin.getRentManager().isForRent(areaname)) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("RentSellFail"));
                return;
            }
        }
        if (!resadmin) {
            if (!plugin.getConfigManager().enableEconomy() || plugin.getEconomyManager() == null) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("MarketDisabled"));
                return;
            }
            final boolean cansell = plugin.getPermissionManager().getGroup(player).canSellLand() || player.hasPermission("plugin.sell");
            if (!cansell && !resadmin) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NoPermission"));
                return;
            }
            if (amount <= 0) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("InvalidAmount"));
                return;
            }
        }
        final String pname = player.getName();
        final ClaimedResidence area = manager.getByName(areaname);
        if (area == null) {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("InvalidResidence"));
            return;
        }
        if (!area.getPermissions().getOwner().equals(pname) && !resadmin) {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NoPermission"));
            return;
        }
        if (sellAmount.containsKey(areaname)) {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("AlreadySellFail"));
            return;
        }
        sellAmount.put(areaname, amount);
        player.sendMessage(ChatColor.GREEN + plugin.getLanguage().getPhrase("ResidenceForSale", ChatColor.YELLOW + areaname + ChatColor.GREEN + "." + ChatColor.YELLOW + amount + ChatColor.GREEN));
    }

    public void removeFromSale(final Player player, final String areaname, final boolean resadmin) {
        final ClaimedResidence area = manager.getByName(areaname);
        if (area != null) {
            if (!isForSale(areaname)) {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("ResidenceNotForSale"));
                return;
            }
            if (area.getPermissions().getOwner().equals(player.getName()) || resadmin) {
                removeFromSale(areaname);
                player.sendMessage(ChatColor.GREEN + plugin.getLanguage().getPhrase("ResidenceStopSelling"));
            } else {
                player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("NoPermission"));
            }
        } else {
            player.sendMessage(ChatColor.RED + plugin.getLanguage().getPhrase("InvalidArea"));
        }
    }

    public void removeFromSale(final String areaname) {
        sellAmount.remove(areaname);
    }

    public Map<String, Integer> save() {
        return sellAmount;
    }

    public void viewSaleInfo(final String areaname, final Player player) {
        if (sellAmount.containsKey(areaname)) {
            player.sendMessage("------------------------");
            player.sendMessage(ChatColor.YELLOW + "Name:" + ChatColor.DARK_GREEN + " " + areaname);
            player.sendMessage(ChatColor.YELLOW + plugin.getLanguage().getPhrase("SellAmount") + ":" + ChatColor.RED + " " + sellAmount.get(areaname));
            if (plugin.getConfigManager().useLeases()) {
                final Date etime = plugin.getLeaseManager().getExpireTime(areaname);
                if (etime != null) {
                    player.sendMessage(ChatColor.YELLOW + plugin.getLanguage().getPhrase("LeaseExpire") + ":" + ChatColor.GREEN + " " + etime.toString());
                }
            }
            player.sendMessage("------------------------");
        }
    }
}
