using Fleck;
using Microsoft.Extensions.Logging;
using SharpChat.SockChat;
using System.Net;

namespace SharpChat;

public class Connection(ILogger logger, IWebSocketConnection sock, IPEndPoint remoteEndPoint) : IDisposable {
    public static readonly TimeSpan SessionTimeOut = TimeSpan.FromMinutes(5);

    public ILogger Logger { get; } = logger;
    public IWebSocketConnection Socket { get; } = sock;
    public IPEndPoint RemoteEndPoint { get; } = remoteEndPoint;

    public bool IsDisposed { get; private set; }
    public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
    public User? User { get; set; }

    private int CloseCode { get; set; } = 1000;

    public IPAddress RemoteAddress => RemoteEndPoint.Address;
    public ushort RemotePort => (ushort)RemoteEndPoint.Port;

    public bool IsAlive => !IsDisposed && !HasTimedOut;

    public async Task Send(S2CPacket packet) {
        if(!Socket.IsAvailable)
            return;

        string data = packet.Pack();
        if(!string.IsNullOrWhiteSpace(data))
            await Socket.Send(data);
    }

    public void BumpPing() {
        LastPing = DateTimeOffset.Now;
    }

    public bool HasTimedOut
        => DateTimeOffset.Now - LastPing > SessionTimeOut;

    public void PrepareForRestart() {
        CloseCode = 1012;
    }

    ~Connection() {
        DoDispose();
    }

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

    private void DoDispose() {
        if(IsDisposed)
            return;

        IsDisposed = true;
        Socket.Close(CloseCode);
    }
}