package com.alterdekim.hearthhack.component.processor.client.request.generic;

import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.dbf.DBFCard;
import com.alterdekim.hearthhack.dbf.DBFField;
import com.alterdekim.hearthhack.game.GameTag;
import com.alterdekim.hearthhack.game.TagRarity;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.xml.XMLTag;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.CARD_VALUES;

@Slf4j
public class CardValues extends GenericParser {

    @Override
    public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
         Protocol.CardValues.Builder cardVals = Protocol.CardValues.newBuilder();

        conn.getDbfConfig().getFormattedCards().getObjects().forEach(f -> {
            DBFCard c = f.getDbfCard();
            RarityValues val = RarityValues.fromInt(f.getEntity().getTags().stream().filter(p -> p.getEnumID().intValue() == GameTag.RARITY.getValue().intValue()).findFirst().orElse(new XMLTag(0,"", 0, "")).getValue());
            if( val == RarityValues.INVALID ) return;
            List<DBFField> fields = c.getFields();
            if (!fields.stream().filter(p -> p.getColumn().equals("IS_COLLECTIBLE")).findFirst().get().getVal().equals("True"))
                return;
            cardVals.addCards(Protocol.CardValue.newBuilder()
                    .setCard(
                            Protocol.CardDef.newBuilder()
                                    .setAsset(
                                            Integer.parseInt(
                                                    fields.stream()
                                                            .filter(p -> p.getColumn().equals("ID"))
                                                            .findFirst()
                                                            .get()
                                                            .getVal()
                                            )
                                    )
                                    .setPremium(1)
                                    .build()
                    )
                    .setBuy(val.getCraftGold())
                    .setSell(val.getSellGold())
                    .setNerfed(false));
            cardVals.addCards(Protocol.CardValue.newBuilder()
                    .setCard(
                            Protocol.CardDef.newBuilder()
                                    .setAsset(
                                            Integer.parseInt(
                                                    fields.stream()
                                                            .filter(p -> p.getColumn().equals("ID"))
                                                            .findFirst()
                                                            .get()
                                                            .getVal()
                                            )
                                    )
                                    .setPremium(0)
                                    .build()
                    )
                    .setBuy(val.getCraft())
                    .setSell(val.getSell())
                    .setNerfed(false));
         });

        Protocol.CardValues vals = cardVals.setCardNerfIndex(5).build();

        Protocol.Notification n = generateNotification(260, vals.toByteString(), vals.getSerializedSize());

        Protocol.Header header = Protocol.Header.newBuilder()
                .setServiceId(4)
                .setMethodId(1)
                .setToken(conn.nextToken())
                .setObjectId(0)
                .setSize(n.getSerializedSize())
                .setStatus(0)
                .build();

        conn.send(new BattleNetPacket(header, n.toByteArray()));
    }

    @Override
    public int getId() {
        return CARD_VALUES.getValue();
    }


    @Getter
    private enum RarityValues {
        INVALID(0, 0, 0, 0),
        COMMON(40, 5, 400, 50),
        FREE(0, 0, 0, 0),
        RARE(100, 20, 800, 100),
        EPIC(400, 100, 1600, 400),
        LEGENDARY(1600, 400, 3200, 1600);

        private final int craft;
        private final int sell;
        private final int craftGold;
        private final int sellGold;

        RarityValues(int craft, int sell, int craftGold, int sellGold) {
            this.craft = craft;
            this.sell = sell;
            this.craftGold = craftGold;
            this.sellGold = sellGold;
        }

        public static RarityValues fromTagRarity(TagRarity rarity) {
            return RarityValues.values()[rarity.ordinal()];
        }

        public static RarityValues fromInt(Integer i) {
            return i > 5 ? RarityValues.INVALID : RarityValues.values()[i];
        }
    }
}
