using ActionGame.GameArtifacts.Models.Characters;
using ActionGame.GameArtifacts.Models.Game;
using ActionGame.GameResources.Models;
using ActionGame.RawResources.Manager;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using System;


namespace ActionGame.GameArtifacts.Intelligence.NonPlayerCharacterMovement
{
    public class TeleportMovement : INonPlayerCharacterMovement
    {
        private ICharacter moveableObject;
        private TimeSpan lastMovementUpdate;
        private GameData gameData;


        public TeleportMovement(ICharacter moveableObject, GameData gameData)
        {
            this.moveableObject = moveableObject;
            this.gameData = gameData;
        }


        public void Act(GameTime gameTime)
        {
            if (lastMovementUpdate == null) lastMovementUpdate = gameTime.TotalGameTime;

            if ((gameTime.TotalGameTime - lastMovementUpdate).TotalSeconds > 4)
            {
                WorldPosition originalPosition = moveableObject.WorldPosition.Copy();
                Random rand = new Random();
                WorldMapCell mapCell = gameData.GetWorldMapCell(gameData.GameState.Player.WorldPosition); 
                Int32 x = gameData.GameState.Player.WorldPosition.PositionX;
                Int32 y = gameData.GameState.Player.WorldPosition.PositionY;
                Vector2 direction = new Vector2(0, 1);


                for (Int32 i = 0; i < 50; i++)
                {
                    Boolean change = false;

                    Int32 xn = x;
                    Int32 yn = y;

                    if (rand.Next(0, 2) == 0)
                    {
                        //change x
                        xn = rand.Next(0, mapCell.GetMaxX() + 1);

                        if(xn > x) direction = new Vector2(-1, 0);
                        else direction = new Vector2(1, 0);
                        
                        if(CanCharacterMove(mapCell, moveableObject.GetCollisionAreaAtPosition(xn,yn))) 
                        {
                            change = true;
                        }
                    }
                    else
                    {
                        //change y
                        yn = rand.Next(0, mapCell.GetMaxY() + 1);

                        if (yn > y) direction = new Vector2(0, -1);
                        else direction = new Vector2(0, 1);

                        if (CanCharacterMove(mapCell, moveableObject.GetCollisionAreaAtPosition(xn, yn)))
                        {
                            change = true;
                        }
                    }

                    if (GetLinearDistance(x, xn, y, yn) < 50) change = false;

                    if(change)
                    {
                        moveableObject.WorldPosition.PositionX = xn;
                        moveableObject.WorldPosition.PositionY = yn;
                        moveableObject.CharacterSet.SetDirection(direction);

                        //sound effect
                        SoundEffect sound = gameData.RawContentManager.SoundEffectRepository.GetContent(@"soundeffects\teleport");
                        sound.Play();

                        break;
                    }
                }

                lastMovementUpdate = gameTime.TotalGameTime;
            }
        }


        private Int32 GetLinearDistance(Int32 xp, Int32 xn, Int32 yp, Int32 yn)
        {
            Int32 d = 0;

            d = ((xp - xn) * (xp - xn)) + ((yp - yn) * (yp - yn));
            d = (Int32)Math.Sqrt((Double)d);

            return d;
        }


        private Boolean CanCharacterMove(WorldMapCell worldMapCell, Rectangle characterCollisionArea)
        {
            Int32 maxX = worldMapCell.GetMaxTileX();
            Int32 maxY = worldMapCell.GetMaxTileY();
            TileSet tileSet = null;

            for (Int32 x = 0; x < maxX; x++)
            {
                for (Int32 y = 0; y < maxY; y++)
                {
                    Rectangle tileBounds = new Rectangle(x * TileSet.DRAW_WIDTH, y * TileSet.DRAW_HEIGHT, TileSet.DRAW_WIDTH, TileSet.DRAW_HEIGHT);

                    if (characterCollisionArea.Intersects(tileBounds))
                    {
                        tileSet = worldMapCell.TilesLayer1[x][y];
                        if (tileSet.Passable == false) return false;

                        tileSet = worldMapCell.TilesLayer2[x][y];
                        if (tileSet?.Passable == false) return false;
                    }
                }
            }

            return true;
        }


        public void PostMovementAct(GameTime gameTime)
        {

        }
    }
}
