using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Ship : SpaceObject
{
    Vector3 previousPosition;
    public Vector3 direction;

    public Animator animator;
    public Toggle enginesToggle;
    bool isEngineOn;
    public float engineThrustAmount, fuelAmount, fuelDepletionSpeed, blackHoleDeathSpeed;
    public bool isDead { get; private set; }
    private bool isDeathFinished, isEscaped;
    float deathProgress;
    Vector3 deathStartPosition, deathEndPosition;
    TrailRenderer trail;

    protected override void Awake()
    {
        base.Awake();        
        animator = GetComponent<Animator>();
        trail = GetComponent<TrailRenderer>();
    }

    private new void FixedUpdate()
    {
        base.FixedUpdate();

        UpdateFacing();
        ApplyEngineThrust();
        CheckCollisions();

        if (isDead && isDeathFinished == false)
        {
            deathProgress += blackHoleDeathSpeed;
            if (deathProgress >= 1f)
            {
                deathProgress = 1f;
                isDeathFinished = true;
                SoundManager.instance.PlayBlackHolePop();
                GameManager.instance.endPanel.BlackHole();
            }
            transform.localScale = new Vector3(1f - deathProgress, 1f - deathProgress, 1);
            transform.position = Vector3.Lerp(deathStartPosition, deathEndPosition, deathProgress);
        }
    }

    private void LateUpdate()
    {
        if (isDead)
            velocity = Vector3.zero;
    }

    public void RefreshTrail()
    {
        if (GameManager.instance.cameraControl.zoomLevel == 1)
            trail.startWidth = 4;
        if (GameManager.instance.cameraControl.zoomLevel == 2)
            trail.startWidth = 5f;
        if (GameManager.instance.cameraControl.zoomLevel == 3)
            trail.startWidth = 6;

        trail.endWidth = 1;
    }

    public void BlackHoleDeath()
    {
        isDead = true;
        deathStartPosition = transform.position;
        deathEndPosition = GameManager.instance.blackHole.transform.position;
    }

    protected override void GentlyRotate()
    {
        // don't
    }

    private void UpdateFacing()
    {
        if (isDead) return;
        Vector3 difference = transform.position - previousPosition;
        direction = difference.normalized;
        
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

        previousPosition = transform.position;
    }

    private void ApplyEngineThrust()
    {
        if (isEngineOn == false) return;
        fuelAmount -= fuelDepletionSpeed;
        if (fuelAmount <= 0f)
        {
            fuelAmount = 0f;
            RefreshEngineAnimation();
        }
        else
        {
            ApplyThrust(engineThrustAmount);
        }

        GameManager.instance.engine.RefreshFuelStatus();
    }

    private void ApplyThrust(float force)
    {
        velocity += direction * force;
    }

    private void ApplyReverseThrust(float force)
    {
        velocity -= direction * force;
    }

    public void EjectObjectForward()
    {
        EjectObject(true);
    }

    public void EjectObjectBackward()
    {        
        EjectObject(false);
    }

    private void EjectObject(bool isForward)
    {
        SpaceObject ejectedObject 
            = GameManager.instance.inventory.RemoveFromInventory(GameManager.instance.inventory.selectedSlot.spaceObject);

        if (ejectedObject is Cat)
        {
            SoundManager.instance.PlayEjectCat();
        }
        else
        {
            SoundManager.instance.PlayEject();
        }

        GameManager.instance.inventory.selectedSlot.RemoveItem();
        GameManager.instance.inventory.SetSelectedInventorySlot(null);

        ejectedObject.transform.position = transform.position;
        ejectedObject.RegisterAsEjected();

        if (isForward)
        {
            ApplyReverseThrust(ejectedObject.ejectForce * 0.1f);
            ejectedObject.velocity = direction * 5f;
        }

        else
        {
            ApplyThrust(ejectedObject.ejectForce * 0.1f);
            ejectedObject.velocity = -(direction * 4f);
        }
    }
       
    public void EnginesOn()
    {
        isEngineOn = true;
        RefreshEngineAnimation();
        
    }

    public void EnginesOff()
    {
        isEngineOn = false;
        RefreshEngineAnimation();

    }

    public void EnginesToggle()
    {
        isEngineOn = enginesToggle.isOn;
        RefreshEngineAnimation();
    }

    private void RefreshEngineAnimation()
    {
        if (fuelAmount <= 0f)
        {
            animator.SetBool("isEngine", false);
            SoundManager.instance.StopEngineSound();
        }
        else
        {
            animator.SetBool("isEngine", isEngineOn);
            if (isEngineOn)
                SoundManager.instance.StartEngineSound();
            else
                SoundManager.instance.StopEngineSound();
        }
    }

    private void CheckCollisions()
    {
        if (aCollider2D.IsTouching(GameManager.instance.blackHole.aCollider2D))
        {
            EnterBlackHole();
        }

        foreach(SpaceObject spaceObject in GameManager.instance.spaceObjects)
        {
            if (spaceObject.hasRecentlyBeenEjected) continue;

            if (GameManager.instance.inventory.items.Contains(spaceObject)) continue;

            if (aCollider2D.IsTouching(spaceObject.aCollider2D))
            {
                foreach (InventorySlot slot in GameManager.instance.inventorySlots)
                {
                    if (slot.IsOccupied()) continue;
                    slot.SetItem(spaceObject);
                    GameManager.instance.inventory.AddToInventory(spaceObject);
                    if (spaceObject is Cat)
                    {
                        SoundManager.instance.PlayCollectCat();
                    }
                    else
                    {
                        SoundManager.instance.PlayCollect();
                    }
                    return;
                }
            }
        }
    }

    private void EnterBlackHole()
    {

    }
}
