package net.cobem.grizzly.habbohotel.users;

import net.cobem.grizzly.Grizzly;
import net.cobem.grizzly.communication.composers.user.SendBadgesComposer;
import net.cobem.grizzly.habbohotel.guild.Guild;
import net.cobem.grizzly.habbohotel.sessions.Session;
import net.cobem.grizzly.habbohotel.users.badges.BadgeObject;
import net.cobem.grizzly.habbohotel.users.items.ItemHandler;
import net.cobem.grizzly.habbohotel.users.items.trading.TradeObject;
import net.cobem.grizzly.habbohotel.users.messenger.MessengerHandler;
import net.cobem.grizzly.storage.DatabaseResult;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class User {
    private int ID;
    private int Credits;
    private int Pixels;
    private int Currency;
    private int Rank;
    private int Respect;
    private int DailyRespect;
    private int HomeRoom;
    private int NameChanges;

    private String Username;
    private String Mail;
    private String Look;
    private String Motto;
    private String Ticket;
    private String LastOnline;

    private GenderType Gender;

    private MessengerHandler Messenger;
    private ItemHandler Inventory;

    private List<Integer> IgnoredUsers = new ArrayList<>();

    private TradeObject TradeObject = null;

    private List<BadgeObject> Badges = new ArrayList<>();

    private Guild Guild;

    public User(String Ticket) {
        DatabaseResult GrabUser = Grizzly.getStorage().preparedQuery("SELECT * FROM users WHERE auth_ticket = ? LIMIT 1", Arrays.asList(Ticket));

        ResultSet Habbo = GrabUser.getRow();

        if (Habbo == null) {
            return;
        }

        FillClass(Habbo);

        this.Ticket = Ticket;
    }

    public User(int ID) {
        DatabaseResult GrabUser = Grizzly.getStorage().preparedQuery("SELECT * FROM users WHERE id = ?", Arrays.asList(String.valueOf(ID)));

        ResultSet Habbo = GrabUser.getRow();

        FillClass(Habbo);
    }

    public User(ResultSet Set) {
        FillClass(Set);
    }
    private boolean FillClass(ResultSet Set) {
        try {
            this.ID = Set.getInt("id");
            this.Credits = Set.getInt("credits");
            this.Pixels = Set.getInt("vip_points");
            this.Currency = Set.getInt("currency");
            this.Rank = Set.getInt("rank");
            this.Respect = Set.getInt("respect");
            this.DailyRespect = Set.getInt("daily_respect_points");
            this.HomeRoom = Set.getInt("home_room");
            this.NameChanges = Set.getInt("active_name_changes");

            this.Username = Set.getString("username");
            this.Mail = Set.getString("mail");
            this.Look = Set.getString("look");
            this.Motto = Set.getString("motto");
            this.LastOnline = Set.getString("last_online");

            this.Gender = GenderType.valueOf(Set.getString("gender"));
            this.Inventory = new ItemHandler(this.ID);

            if (Set.getInt("primary_guild") != 0) {
                this.Guild = new Guild(Set.getInt("primary_guild"));
            }

            DatabaseResult GetIgnores = Grizzly.getStorage().query("SELECT * FROM user_ignores WHERE user_id = '" + this.ID + "'");

            ResultSet Ignores = GetIgnores.getTable();

            while (Ignores.next()) {
                this.IgnoredUsers.add(Ignores.getInt("ignored_id"));
            }

            DatabaseResult GetBadges = Grizzly.getStorage().query("SELECT * FROM user_badges WHERE user_id = '" + this.ID + "'");

            ResultSet Badges = GetBadges.getTable();

            while (Badges.next()) {
                this.Badges.add(new BadgeObject(Badges));
            }
        } catch (Exception E) {
            return false;
        }
        return true;
    }

    public void refreshMessenger(boolean Online) {
        this.startMessenger();

        this.getMessenger().UpdateStatus(Online);
    }

    public void startMessenger() {
        this.Messenger = new MessengerHandler(this.ID);
    }

    public int getID() {
        return this.ID;
    }

    public int getCredits() {
        return this.Credits;
    }

    public void setCredits(int Value) {
        this.Credits = Value;
    }

    public int getPixels() {
        return this.Pixels;
    }

    public void setPixels(int Value) {
        this.Pixels = Value;
    }

    public int getCurrency() {
        return this.Currency;
    }

    public void setCurrency(int Value) {
        this.Currency = Value;
    }

    public int getRank() {
        return this.Rank;
    }

    public void setRank(int Value) {
        this.Rank = Value;
    }

    public int getRespect() {
        return this.Respect;
    }

    public void setRespect(int Value) {
        this.Respect = Value;
    }

    public int getDailyRespect() {
        return this.DailyRespect;
    }

    public void setDailyRespect(int Value) {
        this.DailyRespect = Value;
    }

    public int getHome() {
        return this.HomeRoom;
    }

    public void setHome(int Value) {
        this.HomeRoom = Value;
    }

    public int getNameChanges() {
        return this.NameChanges;
    }

    public void setNameChanges(int Value) {
        this.NameChanges = Value;
    }

    public String getUsername() {
        return this.Username;
    }

    public void setUsername(String Value) {
        this.Username = Value;
    }

    public String getMail() {
        return this.Mail;
    }

    public void setMail(String Value) {
        this.Mail = Value;
    }

    public String getLook() {
        return this.Look;
    }

    public void setLook(String Value) {
        this.Look = Value;
    }

    public String getMotto() {
        return this.Motto;
    }

    public void setMotto(String Value) {
        this.Motto = Value;
    }

    public String getTicket() {
        return this.Ticket;
    }

    public void setTicket(String Value) {
        this.Ticket = Value;
    }

    public String getLastOnline() {
        return this.LastOnline;
    }

    public void setLastOnline(String Value) {
        this.LastOnline = Value;
    }

    public GenderType getGender() {
        return this.Gender;
    }

    public void setGender(GenderType Value) {
        this.Gender = Value;
    }

    public Guild getGuild() {
        return this.Guild;
    }

    public void setGuild(int ID) {
        if (ID != 0) {
            this.Guild = new Guild(ID);
        }
    }

    public void setGuild(Guild mGuild) {
        this.Guild = mGuild;
    }

    public ItemHandler getItems() {
        return Inventory;
    }

    public MessengerHandler getMessenger() {
        return Messenger;
    }

    public List<Integer> getIgnored() {
        return this.IgnoredUsers;
    }

    public TradeObject getTrade() {
        return this.TradeObject;
    }

    public void setTrade(TradeObject Obj) {
        this.TradeObject = Obj;
    }

    public List<Integer> getIgnorers() //The the users ignoring this user..
    {
        List<Integer> Return = new ArrayList<>();

        for (Session mSession : Grizzly.getHabboHotel().getSessions().getSessions().values()) {
            if (mSession.getHabbo().IgnoredUsers.contains(this.ID)) {
                Return.add(mSession.getHabbo().ID); //Basically compiles a list
            }
        }

        return Return;
    }

    public List<BadgeObject> getBadges() {
        return this.Badges;
    }

    public List<BadgeObject> getEquippedBadges() {
        List<BadgeObject> ReturnList = new ArrayList<>();

        for (BadgeObject Obj : this.Badges) {
            if (Obj.Equipped) {
                ReturnList.add(Obj);
            }
        }

        return ReturnList;
    }

    public boolean addBadge(String Code) {
        if (hasBadge(Code)) {
            return false;
        }

        Grizzly.getStorage().execute("INSERT INTO user_badges (user_id, badge_id) VALUES ('" + this.ID + "', '" + Code + "')");

        this.Badges.add(new BadgeObject(this.ID, Code));

        Grizzly.getHabboHotel().getSessions().getByID(this.ID).sendResponse(SendBadgesComposer.compose(Grizzly.getHabboHotel().getSessions().getByID(this.ID).getHabbo().getBadges(), Grizzly.getHabboHotel().getSessions().getByID(this.ID).getHabbo().getEquippedBadges()));
        return true;
    }

    public boolean hasBadge(String Code) {
        for (BadgeObject Obj : this.Badges) {
            if (Obj.Code.equals(Code)) {
                return true;
            }
        }

        return false;
    }

    public BadgeObject getBadgeByID(int ID) {
        for (BadgeObject Obj : this.Badges) {
            if (Obj.ID == ID) {
                return Obj;
            }
        }

        return null;
    }

    public BadgeObject getBadgeBySlot(int Slot) {
        for (BadgeObject Obj : this.Badges) {
            if (Obj.Slot == Slot) {
                return Obj;
            }
        }

        return null;
    }

    public BadgeObject getEquippedBadgeByCode(String Code) {
        for (BadgeObject Obj : getEquippedBadges()) {
            if (Obj.Code.equals(Code)) {
                return Obj;
            }
        }

        return null;
    }

    public boolean append() {
        Grizzly.getStorage().execute("UPDATE users SET " +
                "credits = '" + this.Credits + "'," +
                "activity_points = '" + this.Pixels + "'," +
                "currency = '" + this.Currency + "'," +
                "rank = '" + this.Rank + "'," +
                "username = '" + this.Username + "'," +
                "mail = '" + this.Mail + "'," +
                "look = '" + this.Look + "'," +
                "motto = '" + this.Motto + "'," +
                "gender = '" + this.Gender.toString().toUpperCase() + "'," +
                "respect = '" + this.Respect + "'," +
                "daily_respect_points = '" + this.DailyRespect + "'," +
                "active_name_changes = '" + this.NameChanges + "'," +
                "home_room = '" + this.HomeRoom + "' WHERE id = '" + this.ID + "'");
        return true;
    }

}
