using UnityEngine;
using UnityEngine.UIElements;
using System.Linq;

/// <summary>
/// Controls the travel UI and integrates with TeamTravelSystem for route planning and execution.
/// Uses the existing travel UI elements from MapWithTravelUI.uxml
/// </summary>
[RequireComponent(typeof(UIDocument))]
public class TravelUIController : MonoBehaviour
{
    [Header("UI References")]
    public UIDocument uiDocument;

    [Header("Settings")]
    public bool showDebugLogs = false;

    // UI Elements
    private VisualElement travelContainer;
    private VisualElement travelPanel;
    private Button closeButton;
    private Label distanceLabel;
    private Label timeLabel;
    private Label specialCostsLabel;
    private Button startTravelButton;

    // Route selection (if available)
    private VisualElement routeOptionsContainer;
    private RadioButtonGroup routeSelection;

    // System references
    private TeamTravelSystem travelSystem;
    private SimpleTeamPlacement teamPlacement;

    // Current state
    private TravelRoute selectedRoute;
    private bool isUIVisible = false;

    void Awake()
    {
        if (uiDocument == null)
            uiDocument = GetComponent<UIDocument>();
    }

    void Start()
    {
        // Find system references
        travelSystem = TeamTravelSystem.Instance;
        teamPlacement = SimpleTeamPlacement.Instance;

        if (travelSystem == null)
        {
            Debug.LogError("❌ TeamTravelSystem not found! TravelUIController requires it.");
            return;
        }

        // Setup UI
        SetupUIElements();
        SetupEventHandlers();

        // Hide UI initially
        HideTravelUI();
    }

    void Update()
    {
        // Monitor for travel planning
        if (travelSystem != null && travelSystem.GetPlannedDestination().HasValue && !isUIVisible)
        {
            ShowTravelUI();
        }
        else if (travelSystem != null && !travelSystem.GetPlannedDestination().HasValue && isUIVisible)
        {
            HideTravelUI();
        }
    }

    /// <summary>
    /// Sets up references to UI elements
    /// </summary>
    private void SetupUIElements()
    {
        if (uiDocument?.rootVisualElement == null)
        {
            Debug.LogError("❌ UIDocument root not available");
            return;
        }

        var root = uiDocument.rootVisualElement;

        // Find main UI elements
        travelContainer = root.Q("TravelContainer");
        travelPanel = root.Q("TravelPanel");
        closeButton = root.Q<Button>("CloseButton");
        distanceLabel = root.Q<Label>("DistanceLabel");
        timeLabel = root.Q<Label>("TimeLabel");
        specialCostsLabel = root.Q<Label>("SpecialCostsLabel");
        startTravelButton = root.Q<Button>("StartTravelButton");

        // Optional route selection elements
        routeOptionsContainer = root.Q("RouteOptions");
        routeSelection = root.Q<RadioButtonGroup>("RouteSelection");
    }

    /// <summary>
    /// Sets up event handlers for UI interactions
    /// </summary>
    private void SetupEventHandlers()
    {
        // Close button
        if (closeButton != null)
        {
            closeButton.clicked += OnCloseButtonClicked;
        }

        // Start travel button
        if (startTravelButton != null)
        {
            startTravelButton.clicked += OnStartTravelClicked;
        }

        // Route selection (if available)
        if (routeSelection != null)
        {
            routeSelection.RegisterValueChangedCallback(OnRouteSelectionChanged);
        }

        if (showDebugLogs)
        {

        }
    }

    /// <summary>
    /// Shows the travel UI and updates it with current route information
    /// </summary>
    public void ShowTravelUI()
    {
        if (travelContainer == null) return;

        travelContainer.style.display = DisplayStyle.Flex;
        isUIVisible = true;

        // Update UI with current travel information
        UpdateTravelInformation();

        if (showDebugLogs)
        {

        }
    }

    /// <summary>
    /// Hides the travel UI
    /// </summary>
    public void HideTravelUI()
    {
        if (travelContainer == null) return;

        travelContainer.style.display = DisplayStyle.None;
        isUIVisible = false;

        if (showDebugLogs)
        {

        }
    }

    /// <summary>
    /// Updates the travel information display with current route data
    /// </summary>
    private void UpdateTravelInformation()
    {
        if (travelSystem == null) return;

        var routes = travelSystem.GetAvailableRoutes();
        if (routes.Count == 0)
        {
            ShowNoRoutesMessage();
            return;
        }

        // Select the best route by default (lowest cost)
        selectedRoute = routes.OrderBy(r => r.totalCost).First();

        // Update basic information
        UpdateBasicRouteInfo(selectedRoute);

        // Update route options if available
        UpdateRouteOptions(routes);

        // Update start button
        UpdateStartButton(selectedRoute);
    }

    /// <summary>
    /// Updates the basic route information display
    /// </summary>
    private void UpdateBasicRouteInfo(TravelRoute route)
    {
        if (distanceLabel != null)
        {
            distanceLabel.text = $"Distance: {route.totalDistance:F1} leagues";
        }

        if (timeLabel != null)
        {
            distanceLabel.text = $"Travel Time: {route.estimatedTime:F1} hours";
        }

        if (specialCostsLabel != null)
        {
            if (route.specialCosts.Count > 0)
            {
                var costStrings = route.specialCosts.Select(kvp => $"{kvp.Value} {kvp.Key}");
                specialCostsLabel.text = $"Special Costs: {string.Join(", ", costStrings)}";
                specialCostsLabel.style.color = new StyleColor(Color.yellow);
            }
            else
            {
                specialCostsLabel.text = "Special Costs: None";
                specialCostsLabel.style.color = new StyleColor(Color.white);
            }
        }
    }

    /// <summary>
    /// Updates route selection options if multiple routes are available
    /// </summary>
    private void UpdateRouteOptions(System.Collections.Generic.List<TravelRoute> routes)
    {
        if (routeOptionsContainer == null || routes.Count <= 1)
        {
            // Hide route options if not available or only one route
            if (routeOptionsContainer != null)
                routeOptionsContainer.style.display = DisplayStyle.None;
            return;
        }

        routeOptionsContainer.style.display = DisplayStyle.Flex;

        // TODO: Implement route selection UI if needed
        // For now, we'll just use the best route automatically
    }

    /// <summary>
    /// Updates the start travel button with appropriate text and state
    /// </summary>
    private void UpdateStartButton(TravelRoute route)
    {
        if (startTravelButton == null) return;

        // Check if player can afford the route
        bool canAfford = CanAffordRoute(route);

        startTravelButton.SetEnabled(canAfford);

        if (canAfford)
        {
            if (route.specialCosts.Count > 0)
            {
                var totalCost = route.specialCosts.Values.Sum();
                startTravelButton.text = $"Start Journey ({totalCost} gold)";
            }
            else
            {
                startTravelButton.text = "Start Journey (Free)";
            }
        }
        else
        {
            startTravelButton.text = "Insufficient Resources";
        }
    }

    /// <summary>
    /// Checks if the player can afford the selected route
    /// </summary>
    private bool CanAffordRoute(TravelRoute route)
    {
        // TODO: Implement player resource checking
        // For now, assume player can always afford free routes
        return route.specialCosts.Count == 0 || route.specialCosts.Values.Sum() <= 100; // Placeholder
    }

    /// <summary>
    /// Shows a message when no routes are available
    /// </summary>
    private void ShowNoRoutesMessage()
    {
        if (distanceLabel != null)
            distanceLabel.text = "Distance: No route available";

        if (timeLabel != null)
            timeLabel.text = "Travel Time: --";

        if (specialCostsLabel != null)
            specialCostsLabel.text = "Cannot reach destination";

        if (startTravelButton != null)
        {
            startTravelButton.text = "No Route Available";
            startTravelButton.SetEnabled(false);
        }
    }

    /// <summary>
    /// Event handler for close button
    /// </summary>
    private void OnCloseButtonClicked()
    {
        if (travelSystem != null)
        {
            travelSystem.CancelTravelPlanning();
        }

        HideTravelUI();

        if (showDebugLogs)
        {

        }
    }

    /// <summary>
    /// Event handler for start travel button
    /// </summary>
    private void OnStartTravelClicked()
    {
        if (selectedRoute == null || travelSystem == null)
        {
            Debug.LogWarning("Cannot start travel: no route selected or travel system unavailable");
            return;
        }

        if (!CanAffordRoute(selectedRoute))
        {
            Debug.LogWarning("Cannot start travel: insufficient resources");
            return;
        }

        // Start the travel
        travelSystem.StartTravel(selectedRoute);

        // Hide UI
        HideTravelUI();

        if (showDebugLogs)
        {

        }
    }

    /// <summary>
    /// Event handler for route selection changes
    /// </summary>
    private void OnRouteSelectionChanged(ChangeEvent<int> evt)
    {
        if (travelSystem == null) return;

        var routes = travelSystem.GetAvailableRoutes();
        if (evt.newValue >= 0 && evt.newValue < routes.Count)
        {
            selectedRoute = routes[evt.newValue];
            UpdateBasicRouteInfo(selectedRoute);
            UpdateStartButton(selectedRoute);

            if (showDebugLogs)
            {

            }
        }
    }

    /// <summary>
    /// Public methods for external control
    /// </summary>
    public bool IsUIVisible() => isUIVisible;
    public TravelRoute GetSelectedRoute() => selectedRoute;

    /// <summary>
    /// Context menu methods for debugging
    /// </summary>
    [ContextMenu("Show Travel UI (Test)")]
    public void TestShowTravelUI()
    {
        ShowTravelUI();
    }

    [ContextMenu("Hide Travel UI (Test)")]
    public void TestHideTravelUI()
    {
        HideTravelUI();
    }
}
