using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;
using System.Xml;

#if UNITY_IOS
using UnityEditor.iOS.Xcode;
#endif

public class WortisePostProcess
{
    [PostProcessBuild]
    public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
    {
        WortiseSettings settings = Resources.Load<WortiseSettings>("WortiseSettings");

        if (settings == null)
        {
            Debug.LogError("Could not load Wortise settings. Make sure they exist at Resources/WortiseSettings.asset");
            return;
        }

        if (buildTarget == BuildTarget.Android)
        {
            ProcessAndroidBuild(settings, buildPath);
        }
#if UNITY_IOS
        else if (buildTarget == BuildTarget.iOS)
        {
            ProcessIOSBuild(settings, buildPath);
        }
#endif

        AssetDatabase.Refresh();
    }

    private static void ProcessAndroidBuild(WortiseSettings settings, string buildPath)
    {
        ProcessAndroidManifest(settings);
    }

    private static void ProcessAndroidManifest(WortiseSettings settings)
    {
        string manifestPath = Path.Combine(Application.dataPath, "Wortise/Plugins/Android/WortiseManifest.androidlib/src/main/AndroidManifest.xml");

        try
        {
            XmlDocument manifest = new XmlDocument();
            manifest.Load(manifestPath);

            XmlNamespaceManager nsManager = new XmlNamespaceManager(manifest.NameTable);
            nsManager.AddNamespace("android", "http://schemas.android.com/apk/res/android");

            XmlNode applicationNode = manifest.SelectSingleNode("/manifest/application");
            if (applicationNode == null)
            {
                applicationNode = manifest.CreateElement("application");
                manifest.SelectSingleNode("/manifest").AppendChild(applicationNode);
            }

            if (!string.IsNullOrEmpty(settings.googleAndroidAppId))
            {
                XmlNode existingMetaData = applicationNode.SelectSingleNode(
                    "meta-data[@android:name='com.google.android.gms.ads.APPLICATION_ID']", nsManager);

                if (existingMetaData != null)
                {
                    XmlAttribute valueAttr = existingMetaData.Attributes["android:value"];
                    if (valueAttr != null)
                    {
                        valueAttr.Value = settings.googleAndroidAppId;
                    }
                    else
                    {
                        valueAttr = manifest.CreateAttribute("android", "value", "http://schemas.android.com/apk/res/android");
                        valueAttr.Value = settings.googleAndroidAppId;
                        existingMetaData.Attributes.Append(valueAttr);
                    }
                }
                else
                {
                    XmlElement metaData = manifest.CreateElement("meta-data");

                    XmlAttribute nameAttr = manifest.CreateAttribute("android", "name", "http://schemas.android.com/apk/res/android");
                    nameAttr.Value = "com.google.android.gms.ads.APPLICATION_ID";
                    metaData.Attributes.Append(nameAttr);

                    XmlAttribute valueAttr = manifest.CreateAttribute("android", "value", "http://schemas.android.com/apk/res/android");
                    valueAttr.Value = settings.googleAndroidAppId;
                    metaData.Attributes.Append(valueAttr);

                    applicationNode.AppendChild(metaData);
                }
            }

            manifest.Save(manifestPath);
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Error modifying AndroidManifest.xml: {e.Message}\n{e.StackTrace}");
        }
    }

#if UNITY_IOS
    private static void ProcessIOSBuild(WortiseSettings settings, string buildPath)
    {
        ProcessIOSProject(buildPath);
        ProcessIOSInfoPlist(settings, buildPath);
    }

    private static void ProcessIOSInfoPlist(WortiseSettings settings, string buildPath)
    {
        string plistPath = Path.Combine(buildPath, "Info.plist");
        
        PlistDocument plist = new PlistDocument();
        plist.ReadFromFile(plistPath);

        if (!string.IsNullOrEmpty(settings.googleIosAppId))
        {
            plist.root.SetString("GADApplicationIdentifier", settings.googleIosAppId);
        }

        PlistElementArray skAdNetworkItems = plist.root.CreateArray("SKAdNetworkItems");

        string[] skAdNetworkIds = new string[]
        {
            "cstr6suwn9.skadnetwork",
            "4fzdc2evr5.skadnetwork",
            "4pfyvq9l8r.skadnetwork",
            "2fnua5tdw4.skadnetwork",
            "ydx93a7ass.skadnetwork",
            "5a6flpkh64.skadnetwork",
            "p78axxw29g.skadnetwork",
            "v72qych5uu.skadnetwork",
            "ludvb6z3bs.skadnetwork",
            "cp8zw746q7.skadnetwork",
            "c6k4g5qg8m.skadnetwork",
            "s39g8k73mm.skadnetwork",
            "3qy4746246.skadnetwork",
            "3sh42y64q3.skadnetwork",
            "f38h382jlk.skadnetwork",
            "hs6bdukanm.skadnetwork",
            "prcb7njmu6.skadnetwork",
            "v4nxqhlyqp.skadnetwork",
            "wzmmz9fp6w.skadnetwork",
            "yclnxrl5pm.skadnetwork",
            "t38b2kh725.skadnetwork",
            "7ug5zh24hu.skadnetwork",
            "9rd848q2bz.skadnetwork",
            "y5ghdn5j9k.skadnetwork",
            "n6fk4nfna4.skadnetwork",
            "v9wttpbfk9.skadnetwork",
            "n38lu8286q.skadnetwork",
            "47vhws6wlr.skadnetwork",
            "kbd757ywx3.skadnetwork",
            "9t245vhmpl.skadnetwork",
            "a2p9lx4jpn.skadnetwork",
            "22mmun2rn5.skadnetwork",
            "4468km3ulz.skadnetwork",
            "2u9pt9hc89.skadnetwork",
            "8s468mfl3y.skadnetwork",
            "av6w8kgt66.skadnetwork",
            "klf5c3l5u5.skadnetwork",
            "ppxm28t8ap.skadnetwork",
            "424m5254lk.skadnetwork",
            "ecpz2srf59.skadnetwork",
            "uw77j35x4d.skadnetwork",
            "mlmmfzh3r3.skadnetwork",
            "578prtvx9j.skadnetwork",
            "4dzt52r2t5.skadnetwork",
            "gta9lk7p23.skadnetwork",
            "e5fvkxwrpn.skadnetwork",
            "8c4e2ghe7u.skadnetwork",
            "zq492l623r.skadnetwork",
            "3rd42ekr43.skadnetwork",
            "3qcr597p9d.skadnetwork"
        };

        foreach (string networkId in skAdNetworkIds)
        {
            PlistElementDict dict = skAdNetworkItems.AddDict();
            dict.SetString("SKAdNetworkIdentifier", networkId.Trim());
        }

        plist.WriteToFile(plistPath);
    }

    private static void ProcessIOSProject(string buildPath)
    {
        string projectPath = buildPath + "/Unity-iPhone.xcodeproj/project.pbxproj";

        PBXProject project = new PBXProject();
        project.ReadFromFile(projectPath);

        string unityFrameworkGuid = project.GetUnityFrameworkTargetGuid();

        project.AddBuildProperty(unityFrameworkGuid, "DEFINES_MODULE", "YES");

        string moduleFile = buildPath + "/UnityFramework/UnityFramework.modulemap";

        if (!File.Exists(moduleFile))
        {
            FileUtil.CopyFileOrDirectory("Assets/Wortise/Plugins/iOS/Source/UnityFramework.modulemap", moduleFile);
            project.AddFile(moduleFile, "UnityFramework/UnityFramework.modulemap");
            project.AddBuildProperty(unityFrameworkGuid, "MODULEMAP_FILE", "$(SRCROOT)/UnityFramework/UnityFramework.modulemap");
        }

        string unityInterfaceGuid = project.FindFileGuidByProjectPath("Classes/Unity/UnityInterface.h");
        project.AddPublicHeaderToBuild(unityFrameworkGuid, unityInterfaceGuid);

        string unityForwardDeclsGuid = project.FindFileGuidByProjectPath("Classes/Unity/UnityForwardDecls.h");
        project.AddPublicHeaderToBuild(unityFrameworkGuid, unityForwardDeclsGuid);

        string unityRenderingGuid = project.FindFileGuidByProjectPath("Classes/Unity/UnityRendering.h");
        project.AddPublicHeaderToBuild(unityFrameworkGuid, unityRenderingGuid);

        string unitySharedDeclsGuid = project.FindFileGuidByProjectPath("Classes/Unity/UnitySharedDecls.h");
        project.AddPublicHeaderToBuild(unityFrameworkGuid, unitySharedDeclsGuid);

        project.WriteToFile(projectPath);
    }
#endif
}