package com.eu.habbo.habbohotel.catalog;

import com.eu.habbo.Emulator;
import com.eu.habbo.messages.ISerialize;
import com.eu.habbo.messages.ServerMessage;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.TimeZone;

public class ClubOffer implements ISerialize {
    public static final int WINDOW_HABBO_CLUB = 1;
    public static final int WINDOW_BUILDERS_CLUB = 2;
    public static final int WINDOW_BUILDERS_CLUB_ADDONS = 3;

    public enum OfferType {
        HC,
        VIP,
        BUILDERS_CLUB,
        BUILDERS_CLUB_ADDON;

        public static OfferType fromDatabase(String value) {
            if (value == null) {
                return HC;
            }

            for (OfferType type : OfferType.values()) {
                if (type.name().equalsIgnoreCase(value)) {
                    return type;
                }
            }

            return HC;
        }
    }

    private final int id;


    private final String name;


    private final int days;


    private final int credits;


    private final int points;


    private final int pointsType;

    private final OfferType type;


    private final boolean vip;


    private final boolean deal;

    private final boolean giftable;

    public ClubOffer(ResultSet set) throws SQLException {
        this.id = set.getInt("id");
        this.name = set.getString("name");
        this.days = set.getInt("days");
        this.credits = set.getInt("credits");
        this.points = set.getInt("points");
        this.pointsType = set.getInt("points_type");
        this.type = OfferType.fromDatabase(set.getString("type"));
        this.vip = this.type == OfferType.VIP;
        this.deal = set.getString("deal").equals("1");
        this.giftable = set.getString("giftable").equals("1");
    }

    public int getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public int getDays() {
        return this.days;
    }

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

    public int getPoints() {
        return this.points;
    }

    public int getPointsType() {
        return this.pointsType;
    }

    public OfferType getType() {
        return this.type;
    }

    public boolean isVip() {
        return this.vip;
    }

    public boolean isDeal() {
        return this.deal;
    }

    public boolean isGiftable() {
        return this.giftable;
    }

    public boolean isBuildersClubSubscription() {
        return this.type == OfferType.BUILDERS_CLUB;
    }

    public boolean isBuildersClubAddon() {
        return this.type == OfferType.BUILDERS_CLUB_ADDON;
    }

    public boolean isHabboClubOffer() {
        return this.type == OfferType.HC || this.type == OfferType.VIP;
    }

    public boolean isSubscriptionOffer() {
        return !this.isBuildersClubAddon();
    }

    public int getWindowId() {
        if (this.isBuildersClubAddon()) {
            return WINDOW_BUILDERS_CLUB_ADDONS;
        }

        if (this.isBuildersClubSubscription()) {
            return WINDOW_BUILDERS_CLUB;
        }

        return WINDOW_HABBO_CLUB;
    }

    public boolean belongsToWindow(int windowId) {
        return this.getWindowId() == windowId;
    }

    @Override
    public void serialize(ServerMessage message) {
        serialize(message, Emulator.getIntUnixTimestamp());
    }

    public void serialize(ServerMessage message, int expireTimestamp) {
        expireTimestamp = Math.max(Emulator.getIntUnixTimestamp(), expireTimestamp);
        message.appendInt(this.id);
        message.appendString(this.name);
        message.appendBoolean(false); //unused
        message.appendInt(this.credits);
        message.appendInt(this.points);
        message.appendInt(this.pointsType);
        message.appendBoolean(this.vip);

        long seconds = this.days * 86400L;

        long secondsTotal = seconds;

        int totalYears = (int) Math.floor(seconds / (86400.0 * 31 * 12));
        seconds -= totalYears * (86400 * 31 * 12);

        int totalMonths = (int) Math.floor(seconds / (86400.0 * 31));
        seconds -= totalMonths * (86400 * 31);

        int totalDays = (int) Math.floor(seconds / 86400.0);
        seconds -= totalDays * 86400L;

        message.appendInt(totalMonths);
        message.appendInt(totalDays);
        message.appendBoolean(this.giftable);
        message.appendInt(totalDays);

        if (this.isSubscriptionOffer()) {
            expireTimestamp += secondsTotal;
        }

        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
        cal.setTimeInMillis(expireTimestamp * 1000L);
        message.appendInt(cal.get(Calendar.YEAR));
        message.appendInt(cal.get(Calendar.MONTH) + 1);
        message.appendInt(cal.get(Calendar.DAY_OF_MONTH));
    }
}
