using Multiplayer.API;
using Multiplayer.Common;
using System.Collections.Generic;
using System.Linq;
using Multiplayer.Common.Networking.Packet;
using UnityEngine;
using Verse;

namespace Multiplayer.Client;

public class PlayerInfo : IPlayerInfo
{
    public static readonly Vector3 Invalid = new(-1, 0, -1);

    public int id;
    public string username;
    public int latency;
    public int ticksBehind;
    public bool simulating;
    public float frameTime;
    public PlayerType type;
    public PlayerStatus status;
    public Color color;
    public Material selectionBracketMaterial;
    public int factionId;

    public ulong steamId;
    public string steamPersonaName;

    public byte cursorSeq;
    public byte map = byte.MaxValue;
    public Vector3 cursor;
    public Vector3 lastCursor;
    public double updatedAt;
    public double lastDelta;
    public byte cursorIcon;
    public Vector3 dragStart = Invalid;

    public Dictionary<int, float> selectedThings = new();

    public int Id => id;
    public string Username => username;
    public bool IsArbiter => type == PlayerType.Arbiter;
    public int CurrentMapIndex => map;
    public Map CurrentMap => Find.Maps.Find(m => m.Index == map);
    public IReadOnlyList<int> SelectedThingsByIds => selectedThings
        .Select(x => x.Key)
        .ToList()
        .AsReadOnly();
    public IReadOnlyList<Thing> SelectedThings => selectedThings
        .Select(x => Multiplayer.ThingsById.TryGetValue(x.Key, out var thing) ? thing : null)
        .Where(x => x != null)
        .ToList()
        .AsReadOnly();

    private PlayerInfo(int id, string username, int latency, PlayerType type)
    {
        this.id = id;
        this.username = username;
        this.latency = latency;
        this.type = type;
    }

    public static PlayerInfo FromNet(ServerPlayerListPacket.PlayerInfo info)
    {
        var color = new Color(info.r / 255f, info.g / 255f, info.b / 255f);
        return new PlayerInfo(id: info.id, username: info.username, latency: info.latency, type: info.type)
        {
            status = info.status,

            steamId = info.steamId,
            steamPersonaName = info.steamPersonaName,

            ticksBehind = info.ticksBehind,
            simulating = info.simulating,

            color = color,
            selectionBracketMaterial = MaterialPool.MatFrom("UI/Overlays/SelectionBracket", ShaderDatabase.MetaOverlay, color * new Color(1, 1, 1, 0.5f)),

            factionId = info.factionId,
        };
    }
}
