﻿using HarmonyLib;
using System;
using UnityEngine;
using System.Reflection;
using System.Collections.Generic;

namespace undead_universal_patch.Patches
{
    public class Photon
    {
        public static object Patch() 
        {
            Plugin.Log.LogInfo("Attempting Photon patch.");
            Type serverSettingsType = AccessTools.TypeByName("ServerSettings");

            Type hostingOptionType = AccessTools.Inner(serverSettingsType, "HostingOption");
            if (serverSettingsType == null)
            {
                Plugin.Log.LogFatal("Photon patch failed early, this Photon client is unsupported!");
                return null;
            }

            string[] possibleNames = ["PHMMPAMMFLB", "PIHPJGJOPJA", "JDFMBDBEMCJ", "IECCGIPNGLF"];
            if (hostingOptionType == null) foreach (string type in possibleNames)
                {
                    Plugin.Log.LogDebug($"Checking {type}");
                    hostingOptionType = AccessTools.Inner(serverSettingsType, type);
                    if (hostingOptionType == null) continue;
                    else break;
                }
            if (hostingOptionType == null)
            {
                Plugin.Log.LogFatal("Photon patch failed early, this Photon client (HostingOption) is unsupported!");
                return null;
            }
            ScriptableObject settingsInstance = ScriptableObject.CreateInstance(serverSettingsType);

            object realPhotonServerSettings = Resources.Load("PhotonServerSettings", serverSettingsType);

            try
            {
                var rpcListField = AccessTools.Field(serverSettingsType, "RpcList");
                if (rpcListField == null)
                {
                    Plugin.Log.LogFatal("Photon patch failed (serverSettingsType did not have an RpcList), this Photon client is unsupported!");
                    return null;
                }
                if (realPhotonServerSettings == null)
                {
                    Plugin.Log.LogFatal("Photon patch failed (existing photon settings was null, is the patch event set to 'Awake'?), this Photon client is unsupported!");
                    return null;
                }
                var existingRpcList = (List<string>)rpcListField.GetValue(realPhotonServerSettings);
                rpcListField.SetValue(settingsInstance, existingRpcList);
            }
            catch (Exception e)
            {
                Plugin.Log.LogFatal("Photon patch failed (RpcList), this Photon client is unsupported!");
                Plugin.Log.LogDebug(e);
                return null;
            }

            var appIdField = AccessTools.Field(serverSettingsType, "AppID");
            appIdField.SetValue(settingsInstance, PhotonConfig.AppID.Value);
            var voiceAppIdField = AccessTools.Field(serverSettingsType, "VoiceAppID");
            voiceAppIdField.SetValue(settingsInstance, PhotonConfig.VoiceAppID.Value);

            var hostTypeField = AccessTools.Field(serverSettingsType, "HostType");
            if (hostTypeField != null && hostingOptionType != null && hostingOptionType.IsEnum)
            {
                try
                {
                    object enumValue = Enum.Parse(hostingOptionType, "PhotonCloud");
                    hostTypeField.SetValue(settingsInstance, enumValue);
                }
                catch (ArgumentException ex)
                {
                    Plugin.Log.LogFatal($"Photon patch failed, cannot set HostingOption: {ex.Message}");
                    return null;
                }
            }

            // Save to property
            Type photonNetworkType = AccessTools.TypeByName("PhotonNetwork");
            if (photonNetworkType == null)
            {
                string[] possibleTypeNames = ["GEFAIHCLLBI", "IHFKMIAHBFP", "DAHGDBPKKAJ"];
                foreach (string possibleTypeName in possibleTypeNames)
                {
                    photonNetworkType = AccessTools.TypeByName(possibleTypeName);
                    if (photonNetworkType == null) continue;
                    else break;
                }
                if (photonNetworkType == null)
                {
                    Plugin.Log.LogFatal("Photon patch will not work (class not found). Is this build supported?");
                    return null;
                }
            }
            FieldInfo photonServerSettingsField = photonNetworkType.GetField("PhotonServerSettings");
            if (photonServerSettingsField == null)
            {
                string[] possibleTypeNames = ["OCOJPLFBNOG", "PBKGCAGGOLJ", "FJHKNHIIABD"];
                foreach (string possibleTypeName in possibleTypeNames)
                {
                    photonServerSettingsField = photonNetworkType.GetField(possibleTypeName);
                    if (photonServerSettingsField == null) continue;
                    else break;
                }
                if (photonServerSettingsField == null)
                {
                    Plugin.Log.LogFatal("Photon patch will not work (property not found). Is this build supported?");
                    return null;
                }
            }
            photonServerSettingsField.SetValue(serverSettingsType, settingsInstance);

            Plugin.Log.LogInfo("Photon patch was successful.");
            return settingsInstance;
        }
    }
}
