#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using IGP.UnitySDK.Abstractions;
using IGP.UnitySDK.Models;

namespace IGP.UnitySDK
{
    public partial class IGPRuntimeManager
    {

        public async Task<IGPAntiAddictionStatus> RefreshAntiAddictionStatusAsync(int? appIdOverride = null)
        {
            var appId = ResolveDesktopAppId(appIdOverride);
            if (!appId.HasValue)
            {
                throw new IGPSDKException("IGP appId is required", IGPErrorCodes.ERR_APP_ID_REQUIRED);
            }

            var session = await EnsureDesktopSessionAsync(appId.Value);
            var status = await session.GetDesktopAntiAddictionStatusAsync(RuntimeCancellationToken);
            ApplyAntiAddictionStatus(status);
            return status;
        }

        public async Task<IGPAntiAddictionRealNameWebSession> CreateAntiAddictionRealNameWebSessionAsync(int? appIdOverride = null)
        {
            var appId = ResolveDesktopAppId(appIdOverride);
            if (!appId.HasValue)
            {
                throw new IGPSDKException("IGP appId is required", IGPErrorCodes.ERR_APP_ID_REQUIRED);
            }

            var session = await EnsureDesktopSessionAsync(appId.Value);
            return await session.CreateDesktopAntiAddictionRealNameUrlAsync(
                appId.Value,
                RuntimeCancellationToken);
        }

        private void HandleDesktopAntiAddictionChanged(IGPAntiAddictionStatus status)
        {
            ApplyAntiAddictionStatus(status);
        }

        private void ApplyAntiAddictionStatus(IGPAntiAddictionStatus status)
        {
            if (status == null)
            {
                return;
            }

            var previous = currentAntiAddictionStatus;
            currentAntiAddictionStatus = status;
            if (!isDestroyed && !AntiAddictionStatusEquals(previous, status))
            {
                AntiAddictionChanged?.Invoke(status);
            }
        }

        private static bool AntiAddictionStatusEquals(
            IGPAntiAddictionStatus? left,
            IGPAntiAddictionStatus right)
        {
            return left != null &&
                left.enabled == right.enabled &&
                left.canPlayNow == right.canPlayNow &&
                string.Equals(left.state, right.state, StringComparison.Ordinal) &&
                string.Equals(left.reasonCode, right.reasonCode, StringComparison.Ordinal) &&
                string.Equals(left.reasonMessage, right.reasonMessage, StringComparison.Ordinal) &&
                left.isMinor == right.isMinor &&
                string.Equals(left.ageBand, right.ageBand, StringComparison.Ordinal) &&
                string.Equals(left.evaluatedAt, right.evaluatedAt, StringComparison.Ordinal) &&
                string.Equals(left.playableUntil, right.playableUntil, StringComparison.Ordinal) &&
                string.Equals(left.nextPlayableAt, right.nextPlayableAt, StringComparison.Ordinal) &&
                string.Equals(left.nextStatusChangeAt, right.nextStatusChangeAt, StringComparison.Ordinal);
        }
    }
}
