using System;
using System.Collections.Generic;
using System.IO;
using Decimation.Content.NPCs.Arachnus;
using Decimation.Content.NPCs.DuneWyrm;
using Decimation.Content.NPCs.DuneWyrm.AncientTombCrawler;
using Decimation.Content.UI;
using Decimation.Lib.Util;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.UI;

namespace Decimation.Content
{
    public class Decimation : Mod
    {
        public static AmuletSlotState amuletSlotState;
        private UserInterface amuletSlotInterface;

        internal UserInterface skeletonUserInterface;

        public Decimation()
        {
            Instance = this;

            Properties = new ModProperties
            {
                Autoload = true,
                AutoloadGores = true,
                AutoloadSounds = true
            };

            References.mod = this;
        }

        public static Decimation Instance { set; get; }

        public override void Load()
        {
            if (!Main.dedServ)
            {
                amuletSlotState = new AmuletSlotState();
                amuletSlotState.Activate();
                amuletSlotInterface = new UserInterface();
                amuletSlotInterface.SetState(amuletSlotState);

                skeletonUserInterface = new UserInterface();
            }
        }

        public override void UpdateUI(GameTime gameTime)
        {
            Player player = Main.LocalPlayer;
            if (player.GetModPlayer<DecimationPlayer>().necrosisStoneEquipped && player.respawnTimer != 0)
                player.respawnTimer -= 1;

            amuletSlotInterface?.Update(gameTime);
            skeletonUserInterface?.Update(gameTime);
        }

        public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
        {
            int inventoryIndex = layers.FindIndex(layer => layer.Name.Equals("Vanilla: Inventory"));

            if (inventoryIndex != -1)
            {
                layers.Insert(inventoryIndex + 1, new LegacyGameInterfaceLayer(
                    "Decimation: Amulet Slot",
                    delegate
                    {
                        if (Main.playerInventory)
                            amuletSlotInterface.Draw(Main.spriteBatch, new GameTime());
                        return true;
                    },
                    InterfaceScaleType.UI)
                );

                layers.Insert(inventoryIndex + 2, new LegacyGameInterfaceLayer(
                    "Decimation: Skeleton UI",
                    delegate
                    {
                        skeletonUserInterface.Draw(Main.spriteBatch, new GameTime());
                        return true;
                    },
                    InterfaceScaleType.UI)
                );
            }
        }

        public override void PostSetupContent()
        {
            Mod bossChecklist = ModLoader.GetMod("BossChecklist");
            if (bossChecklist != null)
            {
                bossChecklist.Call("AddBossWithInfo", "The Bloodshot Eye", 2.5f,
                    (Func<bool>) (() => DecimationWorld.downedBloodshotEye), "INSERT LATER");
                bossChecklist.Call("AddBossWithInfo", "The Great Dune Wyrm", 5.7f,
                    (Func<bool>) (() => DecimationWorld.downedDuneWyrm), "INSERT LATER");
                bossChecklist.Call("AddBossWithInfo", "Arachnus", 20f,
                    (Func<bool>) (() => DecimationWorld.downedArachnus), "INSERT LATER");
            }
        }

        public override void AddRecipeGroups()
        {
            RecipeGroup gems = new RecipeGroup(() => Lang.misc[37] + " Gem", ItemID.Amethyst, ItemID.Topaz,
                ItemID.Emerald, ItemID.Sapphire, ItemID.Ruby, ItemID.Diamond);

            RecipeGroup threads = new RecipeGroup(() => Lang.misc[37] + " Thread", ItemID.BlackThread,
                ItemID.GreenThread, ItemID.PinkThread);

            RecipeGroup.RegisterGroup("AnyGem", gems);
            RecipeGroup.RegisterGroup("AnyThread", threads);
        }

        public override void HandlePacket(BinaryReader reader, int whoAmI)
        {
            DecimationModMessageType msgType = (DecimationModMessageType) reader.ReadByte();

            switch (msgType)
            {
                case DecimationModMessageType.Arachnus:
                    Arachnus arachnus = (Arachnus) Main.npc[reader.ReadInt32()].modNPC;
                    if (arachnus != null && arachnus.npc.active) arachnus.HandlePacket(reader);
                    break;
                case DecimationModMessageType.DuneWyrm:
                    DuneWyrmHead duneWyrm = (DuneWyrmHead) Main.npc[reader.ReadInt32()].modNPC;
                    if (duneWyrm != null && duneWyrm.npc.active) duneWyrm.HandlePacket(reader);
                    break;
                case DecimationModMessageType.AncientTombCrawler:
                    AncientTombCrawler tombCrawler = (AncientTombCrawler) Main.npc[reader.ReadInt32()].modNPC;
                    if (tombCrawler != null && tombCrawler.npc.active) tombCrawler.HandlePacket(reader);
                    break;
                case DecimationModMessageType.SpawnBoss:
                    int type = reader.ReadInt32();
                    int player = reader.ReadInt32();
                    Main.PlaySound(15, (int) Main.player[player].position.X, (int) Main.player[player].position.Y, 0);
                    if (Main.netMode != 1)
                        NPC.SpawnOnPlayer(player, type);
                    break;
            }
        }
    }

    internal enum DecimationModMessageType : byte
    {
        Arachnus,
        DuneWyrm,
        AncientTombCrawler,
        SpawnBoss
    }
}