using RobotNet.MapShares;
using RobotNet.MapShares.Dtos;
using RobotNet.MapShares.Enums;

namespace RobotNet.WebApp.Maps.Models;

public class ZoneModel(ZoneDto Data) : IDisposable
{
    public Guid Id => Data.Id;
    public Guid MapId => Data.MapId;
    public ZoneType Type => Data.Type;
    public string Name => Data.Name;

    public double X1 => Data.X1;
    public double Y1 => Data.Y1;
    public double X2 => Data.X2;
    public double Y2 => Data.Y2;
    public double X3 => Data.X3;
    public double Y3 => Data.Y3;
    public double X4 => Data.X4;
    public double Y4 => Data.Y4;

    public string Fill => Data.Type switch
    {
        ZoneType.Confined => "#c29ffa", // Vùng hoạt động hạn chế
        ZoneType.Forbidden => "#ea868f", // Vùng cấm di chuyển
        ZoneType.Operating => "#79dfc1", // Vùng hoạt động bình thường
        ZoneType.OperatingHazard => "#ffda6a", // Vùng hoạt động nguy hiểm
        ZoneType.Restricted => "#fd9843", // Vùng hoạt động giới hạn
        ZoneType.LoadTransfer => "#e685b5", // Vùng chuyển hàng
        _ => "none",
    };

    public int ActiveNode = -1;
    public event Action<ZoneModel, bool>? ActiveChanged;
    public event Func<Task>? ControlNodePosittionChanged;
    public event Action? TypeChanged;

    private (double X, double Y) StartMovePosition;
    public void Active()
    {
        if (ActiveNode == -1) ActiveNode = 5;
        ActiveChanged?.Invoke(this, true);
    }

    public void UnActive() => ActiveChanged?.Invoke(this, false);

    public void UpdateControlNode(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
    {
        Data.X1 = x1;
        Data.Y1 = y1;
        Data.X2 = x2;
        Data.Y2 = y2;
        Data.X3 = x3;
        Data.Y3 = y3;
        Data.X4 = x4;
        Data.Y4 = y4;
        ControlNodePosittionChanged?.Invoke();
    }

    public void UpdateData(ZoneUpdateModel data)
    {
        if (data.Type != Data.Type)
        {
            Data.Type = data.Type;
            TypeChanged?.Invoke();
        }
        if (data.Name != Data.Name) Data.Name = data.Name;
        UpdateControlNode(data.X1, data.Y1, data.X2, data.Y2, data.X3, data.Y3, data.X4, data.Y4);
    }

    public void SetStartMovePosition(double x, double y)
    {
        StartMovePosition.X = x;
        StartMovePosition.Y = y;
    }

    public void UpdateControlNode(int node, double x, double y)
    {
        double deltaX = x - StartMovePosition.X;
        double deltaY = y - StartMovePosition.Y;
        switch (node)
        {
            case 1:
                Data.X1 = x;
                Data.Y1 = y;
                break;
            case 2:
                Data.X2 = x;
                Data.Y2 = y;
                break;
            case 3:
                Data.X3 = x;
                Data.Y3 = y;
                break;
            case 4:
                Data.X4 = x;
                Data.Y4 = y;
                break;
            case 5:
                if (!MapEditorHelper.IsPointInside(StartMovePosition.X, StartMovePosition.Y, Data)) return;
                Data.X1 += deltaX;
                Data.Y1 += deltaY;
                Data.X2 += deltaX;
                Data.Y2 += deltaY;
                Data.X3 += deltaX;
                Data.Y3 += deltaY;
                Data.X4 += deltaX;
                Data.Y4 += deltaY;
                break;
        }
        StartMovePosition.X = x;
        StartMovePosition.Y = y;
        ControlNodePosittionChanged?.Invoke();
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}
