// Copyright (c) 2026 EzAdmin. All rights reserved.
// Licensed under the EzAdmin Client License. See LICENSE-CLIENT.txt.

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace EzAdmin.Client
{

#pragma warning disable 0067, 0414
    [DisallowMultipleComponent]
    public sealed class EzAdminAntiCheat : MonoBehaviour
    {
        public enum Response { ReportOnly, CloseGame, EventOnly }

        [EzAdminGroup("Testing")]
        [Tooltip("Lets Report and ReportCheck send to EzAdmin while you play in the Unity editor, so you can see a " +
                 "report arrive on the dashboard. The automatic checks stay off in the editor either way.")]
        [SerializeField] private bool _sendTestReportsFromEditor = true;

        public static bool SendTestReportsFromEditor = false;

        [EzAdminGroup("Checks")]
        [SerializeField] private bool _modLoaders = true;
        [SerializeField] private bool _injectedCode = true;
        [SerializeField] private bool _debuggers = true;
        [SerializeField] private bool _memoryEditing = true;
        [SerializeField] private bool _rootedDevices = true;
        [SerializeField] private bool _hookingTools = true;
        [Tooltip("Keep scanning for DLLs and libraries injected into the game, code mapped in without a file, " +
                 "and patches written into the game's own code.")]
        [SerializeField] private bool _deepScan = true;
        [Tooltip("Windows: report cheat and debugging tools that are open while the game runs, such as Cheat Engine.")]
        [SerializeField] private bool _cheatTools = true;

        [EzAdminGroup("Assemblies and files")]
        [Tooltip("Assembly names that mean a mod loader or cheat tool is in the game. Remove one your " +
                 "own game uses (some games ship Harmony).")]
        [SerializeField] private List<string> _blockedAssemblies = new List<string>
        {
            "MelonLoader", "BepInEx", "UnityExplorer", "UniverseLib", "Il2CppInterop", "UnhollowerBaseLib",
            "UnhollowerRuntimeLib", "Il2CppAssemblyUnhollower", "Doorstop", "SharpMonoInjector",
            "MonoMod.RuntimeDetour", "0Harmony",
        };

        [EzAdminGroup("Android")]
        [Tooltip("The SHA-256 fingerprint of the certificate your released APK is signed with. With Google " +
                 "Play App Signing, copy \"App signing key certificate\" SHA-256 from Play Console. An APK " +
                 "signed with anything else is a modified copy. Colons and spaces are fine. Empty: not checked.")]
        [SerializeField] private string _expectedCertificate = "";
        [Tooltip("Report a copy that was not installed by one of the stores below (a sideloaded APK). " +
                 "Leave off while you test builds you install yourself.")]
        [SerializeField] private bool _requireStoreInstall = false;
        [SerializeField] private List<string> _allowedInstallers = new List<string>
        {
            "com.android.vending", "com.amazon.venezia", "com.sec.android.app.samsungapps",
            "com.huawei.appmarket", "com.oculus.horizon", "com.oculus.ocms",
        };
        [Tooltip("Report the game running in an Android emulator. Off by default: plenty of honest players use one.")]
        [SerializeField] private bool _emulators = false;

        [EzAdminGroup("When something is found")]
        [Tooltip("Close the game after reporting an injection tool: a mod loader, injected code, a hooking " +
                 "tool, a debugger or a modified copy. Rooted devices and speed are only reported.")]
        [SerializeField] private bool _closeOnInjection = true;
        [Tooltip("ReportOnly: tell your Discord and nothing else. CloseGame: also close the game. " +
                 "EventOnly: tell your Discord and fire On Detected for your own code.")]
        [SerializeField] private Response _response = Response.ReportOnly;
        [SerializeField] private DetectedEvent _onDetected = new DetectedEvent();

        [Serializable] public class DetectedEvent : UnityEvent<string, string> { }

        public static event Action<string, string> Detected;

        public static string Fingerprint { get; private set; } = "";
        public static bool FingerprintReady { get; private set; }
        public static bool Present { get; private set; }
        public static bool Quiet { get; internal set; }

        public static string DeviceSignals { get; private set; } = "";
        public static int Scans { get; private set; }
        public static string Flags => "";

        public static void SetTimeScale(float scale)
        {
            Time.timeScale = scale;
        }

        public static void Report(string detail)
        {
            Locked();
        }

        public static void ReportCheck(string check, string detail)
        {
            Locked();
        }

        internal static void MemoryTampered(string what)
        {
        }

        internal static string Proof(string nonce)
        {
            return "";
        }

        internal static string Proof(string nonce, string code)
        {
            return "";
        }

        private static bool _told;

        private static void Locked()
        {
            if (_told) return;
            _told = true;
            Debug.Log("EzAdmin: anti tamper comes with a paid plan. Download the package from your dashboard " +
                      "(Game files) after upgrading and this file is replaced with the full anti tamper.");
        }

        private void Awake()
        {
            FingerprintReady = true;
            Locked();
        }
    }
#pragma warning restore 0067, 0414
}
