using UnityEngine;
using System.Collections;

public class Arrow : MonoBehaviour
{
    [Header("Arrow Settings")]
    public float flightSpeed = 20f;
    public GameObject arrowModel; // Assign arrow 3D model

    private Vector3 targetPosition;
    private Character targetCharacter;
    private int damage;

    private bool isFlying = false;
    private bool hasLanded = false;

    private Vector3 impactDirection;
    private Collider targetCollider;

    private Vector3 arrowStartPosition;

    public void Initialize(Vector3 startPos, Vector3 hitPoint, Character target, int damageAmount)
    {
        transform.position = startPos;
        arrowStartPosition = startPos;
        targetCharacter = target;
        targetPosition = hitPoint;
        damage = damageAmount;

        // Store direction and collider for later
        impactDirection = (hitPoint - startPos).normalized;
        targetCollider = target.GetComponent<Collider>();

        transform.LookAt(targetPosition);

        StartCoroutine(FlyToTarget());
    }

    public void InitializeMiss(Vector3 startPos, Vector3 missPos)
    {
        transform.position = startPos;
        arrowStartPosition = startPos;
        targetCharacter = null;

        // Raycast down from missPos to find ground
        RaycastHit groundHit;
        if (Physics.Raycast(missPos + Vector3.up * 10f, Vector3.down, out groundHit, 50f, LayerMask.GetMask("Ground")))
        {
            targetPosition = groundHit.point;
        }
        else
        {
            // No ground found, destroy arrow
            Destroy(gameObject);
            return;
        }

        // Point arrow toward miss position on ground
        Vector3 direction = (targetPosition - startPos).normalized;
        transform.LookAt(targetPosition);

        StartCoroutine(FlyToTarget());
    }

    private IEnumerator FlyToTarget()
    {
        isFlying = true;
        Vector3 startPosition = transform.position;
        float journeyLength = Vector3.Distance(startPosition, targetPosition);
        float journeyTime = journeyLength / flightSpeed;
        float elapsedTime = 0f;

        while (elapsedTime < journeyTime && !hasLanded)
        {
            elapsedTime += Time.deltaTime;
            float fractionOfJourney = elapsedTime / journeyTime;

            // Move arrow toward target
            transform.position = Vector3.Lerp(startPosition, targetPosition, fractionOfJourney);

            yield return null;
        }

        // Arrow has reached target
        Land(journeyLength);
    }

    private void Land(float journeyLength = 2f)
    {
        isFlying = false;
        hasLanded = true;

        // If we hit a character, apply damage
        if (targetCharacter != null && targetCharacter.IsTargetable && damage > 0)
        {
            targetCharacter.TakeDamage(damage);
            Debug.Log($"=== ARROW IMPACT ===");
            Debug.Log($"Arrow hits {targetCharacter.CharacterName} for {damage} damage!");
            Debug.Log($"Target Health After: {targetCharacter.CurrentHealth}/{targetCharacter.MaxHealth}");
            Debug.Log($"=== END ARROW IMPACT ===");

            // Raycast from current arrow position forward to find actual hit point on collider
            Vector3 rayOrigin = arrowStartPosition;
            Vector3 rayDir = impactDirection;
            RaycastHit hitInfo;
            Vector3 finalHitPoint = transform.position;

            if (targetCollider != null && targetCollider.Raycast(new Ray(rayOrigin, rayDir), out hitInfo, journeyLength))
            {
                finalHitPoint = hitInfo.point;
            }

            // Move arrow to the actual hit point
            transform.position = finalHitPoint;

            // Stick arrow to target at the hit point and preserve world position/rotation
            Quaternion worldRot = transform.rotation;
            transform.SetParent(targetCharacter.transform, true);
            transform.position = finalHitPoint;
            transform.rotation = worldRot;

            Debug.Log($"Arrow hits {targetCharacter.CharacterName} at {finalHitPoint} for {damage} damage!");
        }
        else
        {
            Debug.Log("=== ARROW MISS ===");
            Debug.Log("Arrow misses and lands on the ground!");
            Debug.Log($"=== END ARROW MISS ===");
        }

        // Make arrow inactive but visible
        Collider arrowCollider = GetComponent<Collider>();
        if (arrowCollider != null)
        {
            arrowCollider.enabled = false;
        }

        // Disable rigidbody if present
        Rigidbody arrowRb = GetComponent<Rigidbody>();
        if (arrowRb != null)
        {
            arrowRb.isKinematic = true;
        }
    }

    public bool IsFlying => isFlying;
    public bool HasLanded => hasLanded;
}
