using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace LunaLightXMG
{
    public class Enemy
    {
        public Level Level
        {
            get { return level; }
        }
        Level level;

        private float hsp;          // Horizontal speed
        private float hspPrev;
        private float vsp;          // Vertical speed
        private float hsp_frac;     // Horizontal fractional speed
        private float vsp_frac;     // Vertical fractional speed
        private float vspJump;
        private bool grounded;
        private bool walled;
        private float grv;
        private Texture2D texture;
        public Vector2 position;
        public BoundingBox boundingBox { get; private set; }
        private CollisionManager collisionManager;
        private static Random random;

        public Enemy(Vector2 initPosition, float initHsp)
        {
            hsp = initHsp;
            vsp = 0;
            hsp_frac = 0;
            vsp_frac = 0;
            vspJump = -4f;
            grounded = false;
            walled = false;
            grv = 0.2f;
            position = initPosition;
            boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 8));
            collisionManager = new CollisionManager();
            random = new Random(42);
        }

        public Enemy(Level level, Vector2 initPosition, float initHsp, ContentManager Content)
        {
            this.level = level;
            hsp = initHsp;
            vsp = 0;
            hsp_frac = 0;
            vsp_frac = 0;
            vspJump = -4f;
            grounded = false;
            walled = false;
            grv = 0.2f;
            position = initPosition;
            boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 8));
            collisionManager = new CollisionManager();
            random = new Random(42);
            LoadContent(Content);
        }

        public void LoadContent(ContentManager content)
        {
            texture = content.Load<Texture2D>("enemy");
        }

        public void Update(GameTime gameTime, Player player, Platform[] platforms)
        {
            Movement();
            boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height);
            DumpFractions();
            CollisionChecks(platforms, player);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (hsp <= 1 && hsp >= -1)
            {
                spriteBatch.Draw(texture, position, Color.White);
            }
            else 
            {
                spriteBatch.Draw(texture, position, Color.Red);
            }
        }

        // Method Implementation -------------------------------------------------------------------------------
        private void Movement()
        {
            if (hsp == 0) { hsp = hspPrev; }
            if (walled) { hsp = -hsp; }
            if (!grounded) { vsp += grv; }
            if (RandomJump() && grounded) { vsp = vspJump; }
        }

        private void CollisionChecks(Platform[] platforms, Player player)
        {
            // Remember hsp
            hspPrev = hsp;
            // Horizontal collision prediction
            float onePixh = Math.Sign(hsp);
            if (CollisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms))
            {
                while (!CollisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms))
                {
                    position.X += onePixh;
                }
                hsp = 0;
            }
            position.X += hsp; // Horizontal move

            // Vertical collision prediction
            float onePixv = Math.Sign(vsp);
            if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms))
            {
                while (!CollisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms))
                {
                    position.Y += onePixv;
                }
                vsp = 0;
            }
            position.Y += vsp; // Vertical move

            // Grounded?
            grounded = CollisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms);

            // Walled?
            walled = CollisionManager.WallCheck(position, boundingBox, platforms);

            // Check for collision with player
            if (boundingBox.Intersects(player.boundingBox) && player.vsp > 0)
            {
                // Player jumps on top of the enemy, enemy dies
                Die();
            }
        }

        // Enemy dies
        private void Die()
        {
            // Logic for enemy death (e.g., remove from game, play animation, etc.)
            // Here we just move the enemy off-screen as a simple example
            position = new Vector2(-100, -100);
        }

        private void DumpFractions()
        {
            if (grounded)
            {
                float adjustedPosX = (float)Math.Round(position.X);
                float adjustedPosY = (float)Math.Round(position.Y);
                position.X = adjustedPosX;
                position.Y = adjustedPosY;
            }

            if (vsp >= 0)
            {
                hsp += hsp_frac;
                vsp += vsp_frac;
                hsp_frac = hsp - (float)Math.Floor(hsp);
                vsp_frac = vsp - (float)Math.Floor(vsp);
                hsp -= hsp_frac;
                vsp -= vsp_frac;
            }
        }
        public static bool RandomJump()
        {
            return (1 + 2 * random.NextDouble() > 2) ? true : false;
        }
    }
}

