using System.Collections.Generic;

namespace AvatarRefinery.Editor.Core
{
    internal static class EnglishKnowledgeBase
    {
        internal static readonly Dictionary<string, Explanation> Map = new Dictionary<string, Explanation>
        {
            ["env.unity_version"] = E(
                "This project is not using VRChat's supported Unity version",
                "The upload may fail, or the avatar may not load correctly in VRChat.",
                "VRChat currently accepts avatar content made with Unity 2022.3.22f1.",
                "Content saved with another Unity version can be rejected or behave incorrectly.",
                new[] { "Install Unity 2022.3.22f1 in Unity Hub.", "Reopen the project from VCC or ALCOM with Unity 2022.3.22f1.", "If the project was saved in another version, check the Console for errors after reopening it." },
                "https://creators.vrchat.com/sdk/upgrade/current-unity-version/"),
            ["env.sdk_missing"] = E(
                "VRChat SDK was not found (general-purpose checks only)",
                "Performance rank and VRChat-specific checks such as the Descriptor, expressions, and PhysBones are unavailable.",
                "VRChat SDK - Avatars is not installed in this project.",
                "Only general geometry, material, and rig checks were run.",
                new[] { "Add VRChat SDK - Avatars to the project in VCC or ALCOM.", "Run the preflight check again to enable the VRChat-specific checks." },
                "https://vcc.docs.vrchat.com/"),
            ["env.sdk_version"] = E(
                "The VRChat SDK is too old for uploads",
                "The SDK Builder blocks uploads made with unsupported SDK versions.",
                "VRChat requires a newer supported VRChat SDK release.",
                "You cannot upload until the SDK is updated.",
                new[] { "Update VRChat SDK - Avatars from the project's Manage Packages screen in VCC or ALCOM.", "Reopen Unity, clear any Console errors, and run the check again." },
                "https://creators.vrchat.com/sdk/upgrade/"),
            ["env.legacy_dynamic_bone"] = E(
                "Legacy Dynamic Bone components are still present",
                "The SDK may warn during build, and the affected hair or clothing will not move in VRChat.",
                "VRChat uses PhysBones. Legacy Dynamic Bone components are ignored unless converted.",
                "The parts configured with Dynamic Bone will not move as intended.",
                new[] { "Use the conversion or Auto Fix action in VRChat SDK > Show Control Panel > Builder.", "Confirm that no Dynamic Bone components remain after conversion.", "Retune PhysBone Pull, Spring, and Stiffness if the motion changed." },
                "https://creators.vrchat.com/avatars/avatar-dynamics/physbones/"),

            ["vrc.descriptor_missing"] = E(
                "VRC Avatar Descriptor is missing (the avatar cannot be uploaded)",
                "The SDK Builder does not list this object as an avatar.",
                "VRChat identifies an avatar by the VRC Avatar Descriptor component on its root.",
                "The avatar cannot be uploaded.",
                new[] { "Select the avatar root and add VRC Avatar Descriptor in the Inspector.", "Place View Position between the eyes and slightly in front of the face.", "Configure LipSync and Eye Look, then run the check again." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/"),
            ["vrc.view_position"] = E(
                "View Position is far from the avatar's eyes",
                "Your viewpoint can be inside the floor, outside the body, or far above the head.",
                "View Position must be placed manually and does not always follow the head after avatar editing.",
                "It changes the first-person view and also affects Avatar Scaling.",
                new[] { "Click Edit next to View Position in VRC Avatar Descriptor.", "Move the sphere between the eyes and about 3–5 cm in front of the face.", "Click Return to finish, then run the check again." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/",
                intentional: "An unusual position can be intentional for very short, very tall, or headless avatars."),
            ["vrc.viseme_broken"] = E(
                "LipSync has a broken Viseme configuration",
                "The mouth does not move while speaking, or the SDK Builder reports a Viseme warning.",
                "Viseme Blend Shape mode is selected, but the Face Mesh is missing or one or more configured BlendShape names no longer exist.",
                "The avatar can upload, but lip sync will not work correctly.",
                new[] { "Assign the face SkinnedMeshRenderer to VRC Avatar Descriptor > LipSync > Face Mesh.", "Click Auto Detect! if the mesh uses standard names such as vrc.v_aa.", "Manually choose a matching BlendShape for any Viseme that remains empty." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/"),
            ["vrc.eyelook_broken"] = E(
                "Eye Look contains broken references",
                "The eyes do not track, blinking stops, or the SDK Builder shows an Eye Look warning.",
                "Eye Look is enabled, but an eye bone, eyelid mesh, or blink reference is empty.",
                "Automatic eye tracking or blinking will not work.",
                new[] { "Assign LeftEye and RightEye under VRC Avatar Descriptor > Eye Look.", "If you use Eyelids, assign the eyelid mesh and valid Blink BlendShapes.", "If fixed eyes are intentional, disable Eye Look." },
                "https://creators.vrchat.com/avatars/",
                intentional: "Fixed-eye designs can safely disable Eye Look."),
            ["vrc.expression_params_over"] = E(
                "Expression Parameters exceed the 256-bit limit",
                "The SDK Builder reports an error and blocks upload.",
                "Synced Expression Parameters can use at most 256 bits (Bool = 1; Int or Float = 8). Outfits and prefabs can push the total over the limit.",
                "The avatar cannot be uploaded until the synchronized cost is reduced.",
                new[] { "Open the Expression Parameters asset and remove parameters you no longer use.", "Turn off Synced for values that only need to work locally.", "Review whether Int or Float values can be represented with fewer parameters.", "Remember that Modular Avatar and similar tools may add parameters during the NDMF build." },
                "https://creators.vrchat.com/avatars/animator-parameters/",
                autoFixable: true),
            ["vrc.expression_refs_missing"] = E(
                "Expression Menu and Expression Parameters are missing or only one is assigned",
                "The Expressions menu is empty in VRChat, or the SDK reports a warning.",
                "Custom Expressions requires both a Menu asset and a Parameters asset.",
                "Expression controls such as facial expressions and outfit toggles will be unavailable.",
                new[] { "Enable Customize under VRC Avatar Descriptor > Expressions.", "Assign both a Menu and a Parameters asset, creating them from Create > VRChat > Avatars if needed.", "If Modular Avatar generates both during build, inspect the built result before changing the source avatar." },
                "https://creators.vrchat.com/avatars/expression-menu-and-controls/",
                intentional: "A source avatar can look incomplete when Modular Avatar creates these assets during the NDMF build."),
            ["vrc.fx_write_defaults_mixed"] = E(
                "Write Defaults is mixed in the FX controller",
                "Expressions can remain stuck, blend with other states, or make outfit toggles unreliable.",
                "States with Write Defaults ON and OFF restore unanimated values differently. This check inspects the FX layer; some advanced setups deliberately use exceptions.",
                "The avatar can upload, but animation behavior may be inconsistent.",
                new[] { "Open the FX Animator Controller and identify whether the system expects Write Defaults ON or OFF.", "Make the states consistent, except where the prefab or tool documentation explicitly requires another setting.", "If you use Modular Avatar, review its Write Defaults handling before editing generated controllers." },
                "https://creators.vrchat.com/avatars/",
                intentional: "Some Direct Blend Tree and tool-generated systems deliberately mix settings. Ignore this check if the system documentation requires it and behavior is correct."),
            ["vrc.missing_script"] = E(
                "Missing Scripts remain and may block upload",
                "The Inspector shows “The associated script can not be loaded,” and the SDK build may fail.",
                "A required package is absent or a component was left behind after removing an older tool such as Dynamic Bone.",
                "The SDK may block upload. Removing the component is safe only after you confirm the original package is not required.",
                new[] { "Check the avatar or prefab documentation and install any required packages first.", "If the component is obsolete, remove Missing (Mono Script) from the affected object.", "Use the Pro preview to review all targets before batch removal. Missing Script removal can only be restored immediately with Unity Undo; see the warning in the preview." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/",
                autoFixable: true),
            ["vrc.expression_blink_conflict"] = E(
                "An expression animation conflicts with blinking",
                "The eyes can become half-closed, show white, or stop mid-blink while an expression is active.",
                "The FX animation and automatic eyelid tracking both drive the same Blink BlendShapes.",
                "This is a visual issue; upload remains possible.",
                new[] { "Add VRC Animator Tracking Control to the expression state and set Eyes & Eyelids to Animation, then restore Tracking in the exit state.", "Alternatively, remove Blink BlendShape curves from the expression clip.", "Check the blink-control option in the expression tool that generated the animation." },
                "https://creators.vrchat.com/avatars/state-behaviors/",
                intentional: "This can be intentional when the expression state controls the eyelids explicitly."),
            ["vrc.expression_viseme_conflict"] = E(
                "An expression animation conflicts with lip sync",
                "The mouth stops moving or remains partly open while a specific expression is active.",
                "The FX animation and Viseme lip sync both drive the same mouth BlendShapes.",
                "This is a visual issue; upload remains possible.",
                new[] { "For an expression that intentionally fixes the mouth, set Mouth & Jaw to Animation with VRC Animator Tracking Control and restore Tracking in the exit state.", "Otherwise, remove Viseme curves such as vrc.v_aa from the expression clip." },
                "https://creators.vrchat.com/avatars/state-behaviors/",
                intentional: "A fixed mouth can be intentional for expressions such as a kiss or yawn."),
            ["vrc.expression_menu_broken"] = E(
                "Expression Menu contains broken or ineffective controls",
                "A control may do nothing, open an empty submenu, or fail to drive its intended feature.",
                "A submenu is missing, a referenced parameter is absent, or a menu contains too many controls.",
                "The avatar can upload, but the affected controls will not work.",
                new[] { "Open each path listed under Detected and assign the missing submenu or parameter.", "Add missing names to Expression Parameters only when the connected animator or prefab actually uses them.", "Keep each Expression Menu page within the VRChat control limit." },
                "https://creators.vrchat.com/avatars/expression-menu-and-controls/"),
            ["vrc.physbone_invalid"] = E(
                "One or more PhysBones have invalid or wasteful settings",
                "Affected parts may not move, two PhysBones may fight over the same chain, or empty components may consume performance budget.",
                "The Root Transform, collider list, ignore list, endpoint, or affected hierarchy is inconsistent.",
                "Motion may be incorrect and the avatar may use more PhysBone budget than necessary.",
                new[] { "Select each detected PhysBone and verify that Root Transform is inside the avatar hierarchy.", "Remove empty entries from Colliders and Ignore Transforms.", "Avoid overlapping PhysBones unless the setup is intentional.", "Delete components that have no child chain and no Endpoint Position." },
                "https://creators.vrchat.com/avatars/avatar-dynamics/physbones/",
                intentional: "Some advanced PhysBone setups intentionally overlap or use unusual roots."),

            ["material.missing_shader"] = E(
                "A material has a missing or unsupported shader",
                "The affected surface appears bright pink in Unity or VRChat.",
                "The material references a shader that is not installed or is unsupported on the active platform.",
                "The surface will render incorrectly.",
                new[] { "Install the shader package required by the avatar or outfit.", "If the shader is installed, reassign it on the material and restore the original settings.", "For Quest or mobile, replace unsupported shaders with a VRChat/Mobile shader and check the appearance." },
                "https://creators.vrchat.com/avatars/shader-fallback-system/"),
            ["material.slot_empty"] = E(
                "A Renderer has an empty material slot",
                "Part of the mesh can be invisible or render incorrectly.",
                "A material slot is set to None, often after deleting or moving an asset.",
                "The submesh assigned to that slot will not render correctly.",
                new[] { "Select the Renderer and assign the intended material to each empty slot.", "Compare the component with the original prefab if you are unsure which material belongs there." },
                "https://docs.unity3d.com/Manual/Materials.html"),
            ["texture.streaming_mipmaps_off"] = E(
                "Streaming Mip Maps is disabled on one or more textures",
                "The SDK Builder warns about Streaming Mip Maps and may block upload.",
                "VRChat expects mipmapped avatar textures to use Streaming Mip Maps so lower-resolution mip levels can be loaded when appropriate.",
                "The upload may be blocked until the setting is enabled.",
                new[] { "Use Auto Fix in the VRChat SDK Builder, or review the targets in the Pro fix preview.", "To change one texture manually, enable Streaming Mipmaps under its Texture Import Settings and click Apply." },
                "https://creators.vrchat.com/avatars/avatar-optimizing-tips/",
                autoFixable: true),
            ["texture.uncompressed"] = E(
                "Uncompressed textures are using excessive texture memory",
                "Texture Memory can push the avatar's performance rank down to Very Poor.",
                "Formats such as RGBA32 use roughly four to eight times as much VRAM as common compressed formats.",
                "The avatar uses more viewer VRAM and is more likely to be hidden by performance limits.",
                new[] { "Set Compression to Normal Quality and review the imported preview for artifacts.", "Lower Max Size for textures that do not need full resolution.", "Crunch reduces download size, not runtime Texture Memory.", "Extract textures embedded in a VRM before changing their import settings." },
                "https://creators.vrchat.com/avatars/avatar-optimizing-tips/",
                autoFixable: true),
            ["texture.oversized"] = E(
                "One or more textures are 4096 pixels or larger",
                "Texture Memory and download size may be higher than needed.",
                "A 4K texture uses four times the pixel memory of a 2K texture.",
                "Large textures can reduce performance rank, especially on Quest or mobile.",
                new[] { "Set Max Size to 2048 and check the avatar at the viewing distances you care about.", "Keep higher resolution only for assets that genuinely need close-up detail." },
                "https://creators.vrchat.com/avatars/avatar-optimizing-tips/",
                autoFixable: true,
                intentional: "High-resolution textures can be appropriate for close-up photography."),

            ["rig.animator_missing"] = E(
                "Animator or Avatar definition is missing",
                "The SDK may not recognize the avatar, or the model may remain in a T-pose.",
                "The avatar root has no Animator, or its Avatar field is empty.",
                "The avatar cannot be uploaded correctly.",
                new[] { "Add an Animator to the root and assign the Avatar sub-asset generated from the model.", "Set the model's Rig > Animation Type to Humanoid and click Apply." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/"),
            ["rig.not_humanoid"] = E(
                "The rig is not configured as Humanoid",
                "The SDK reports an error, or the avatar's limbs do not move.",
                "The model's Rig import setting is Generic or None.",
                "VRChat avatars require a valid Humanoid rig.",
                new[] { "Select the model asset and set Rig > Animation Type to Humanoid.", "Open Configure... and resolve every red bone-mapping error." },
                "https://creators.vrchat.com/avatars/creating-your-first-avatar/"),
            ["rig.bones_missing"] = E(
                "Required Humanoid bones are missing",
                "Limbs may not move, the body can deform incorrectly, or the SDK can block upload.",
                "One or more required Humanoid bones are not mapped.",
                "The avatar cannot upload correctly until the mapping is valid.",
                new[] { "Open the model's Rig > Configure... screen and assign each missing required bone.", "If the source model has no corresponding bone, add and weight it in a modeling tool such as Blender." },
                "https://docs.unity3d.com/Manual/ConfiguringtheAvatar.html"),
            ["rig.no_fingers"] = E(
                "No finger bones are assigned",
                "Standard VRChat hand gestures will not bend the fingers.",
                "The Humanoid mapping contains no finger bones. VRChat permits this, but built-in finger animation cannot work.",
                "Upload remains possible; only hand animation is affected.",
                new[] { "If the model has finger bones, assign them under Rig > Configure... > Left Hand and Right Hand.", "If the model intentionally has no fingers, no change is required." },
                "https://creators.vrchat.com/avatars/rig-requirements/",
                intentional: "This is normal for fingerless designs or avatars that animate hands another way."),
            ["render.anchor_override_mixed"] = E(
                "Parts of the avatar may be lit differently because Anchor Override is inconsistent",
                "The face, body, hair, or outfit can appear brighter or darker than adjacent meshes and may flicker while moving.",
                "Renderers sample lighting from different Anchor Override positions or from their individual Bounds centers.",
                "This affects appearance, not geometry or performance rank.",
                new[] { "Assign the same Anchor Override, usually Hips or Chest, to the avatar's live Renderers.", "Apply the same anchor when adding outfits or props.", "If Modular Avatar or another NDMF tool manages anchors, inspect its built result before editing the source." },
                "https://lilxyzw.github.io/lilToon/en_US/",
                autoFixable: true),
            ["render.bounds_abnormal"] = E(
                "Renderer Bounds are abnormal",
                "Hair or clothing can disappear at some angles, or a mesh can keep rendering while far off-screen.",
                "SkinnedMeshRenderer Bounds are extremely small, extremely large, far from the avatar, or Update When Offscreen is enabled.",
                "Small Bounds cause visible pop-out; oversized Bounds can increase unnecessary rendering.",
                new[] { "Set Bounds large enough to contain the mesh through its expected animations.", "Check extreme poses in the Scene view after changing the value.", "If AAO or another tool manages Bounds, compare the built result before editing the source." },
                "https://docs.unity3d.com/Manual/class-SkinnedMeshRenderer.html",
                autoFixable: true),
            ["render.mesh_missing"] = E(
                "A Renderer has a missing mesh reference",
                "The affected part is invisible and the Mesh field is None.",
                "The mesh asset was deleted, moved, or failed to import.",
                "That part will remain missing after upload.",
                new[] { "Restore the mesh from the original model or prefab.", "Delete the empty Renderer only if the part is intentionally unused." },
                "https://docs.unity3d.com/Manual/class-SkinnedMeshRenderer.html"),

            ["perf.pc"] = E(
                "One or more categories are lowering the PC performance rank",
                "Depending on another user's Avatar Performance settings, the avatar may be replaced by an impostor or fallback.",
                "The overall rank is determined by the worst individual performance category.",
                "Very Poor avatars are more likely to be hidden; Poor or better reaches more viewers.",
                new[] { "Start with the category showing the worst rank.", "Compress or resize textures when Texture Memory is high.", "Use AAO or another trusted workflow to reduce material and mesh overhead when appropriate.", "Remove unused PhysBones and other components." },
                "https://creators.vrchat.com/avatars/avatar-performance-ranking-system/"),
            ["perf.android"] = E(
                "One or more categories are lowering the Quest/mobile performance rank",
                "Quest and mobile users may see an impostor by default, and components above mobile limits can be removed at runtime.",
                "Quest/mobile performance limits are substantially stricter than PC limits.",
                "A PC avatar usually needs a separate Quest/mobile variant to meet those limits.",
                new[] { "Ignore this item if the avatar is intentionally PC-only.", "For a Quest/mobile version, create and test a separate conversion using tools such as VRCQuestTools.", "Reduce textures, meshes, materials, and download size, then verify the mobile build." },
                "https://creators.vrchat.com/platforms/android/quest-content-limitations/",
                intentional: "No change is required for an intentionally PC-only avatar."),
            ["ndmf.build_error"] = E(
                "An NDMF tool reported a build error",
                "Upload may fail, or an outfit or prefab may not be assembled as intended.",
                "Modular Avatar, AAO, or another NDMF plugin reported an error while producing the built avatar.",
                "The result depends on the reported error; inspect the Detected message.",
                new[] { "Read the Detected message and identify the tool and object involved.", "Open Tools > NDM Framework > Show error report for the full NDMF report.", "Correct the source setup using that tool's documentation, then run the check again." },
                "https://modular-avatar.nadena.dev/"),
            ["ndmf.build_warning"] = E(
                "An NDMF tool reported a warning",
                "The build succeeds, but a tool found a setting that may not match your intent.",
                "A non-fatal warning was produced during the NDMF build.",
                "The avatar may still work, but the built result should be checked.",
                new[] { "Review the Detected message and the indicated tool or object.", "If the built result is intentional, you can ignore this item." },
                "https://modular-avatar.nadena.dev/",
                intentional: "Ignore the warning only after confirming the built result is intentional."),
            ["vrm.imported_state"] = E(
                "This appears to be a freshly imported VRM that has not been converted for VRChat",
                "Spring bones, expressions, Quest materials, and performance settings may not work as expected.",
                "VRM uses different conventions for secondary motion, materials, and expressions.",
                "Basic upload may become possible after adding a Descriptor, but unconverted features will remain missing or inefficient.",
                new[] { "Use a maintained VRM-to-VRChat conversion workflow for SpringBone, PhysBone, expressions, and Visemes.", "Extract and compress embedded textures.", "For Quest/mobile, replace MToon with supported VRChat/Mobile shaders and verify the appearance." },
                "https://vrm.dev/",
                intentional: "Ignore this if the avatar was converted manually and only VRM metadata remains."),
        };

        private static Explanation E(string title, string symptom, string cause, string impact, string[] steps, string url, bool autoFixable = false, string intentional = null)
        {
            return new Explanation
            {
                Title = title,
                Symptom = symptom,
                Cause = cause,
                Impact = impact,
                FixSteps = steps,
                DocUrl = url,
                AutoFixable = autoFixable,
                MaybeIntentional = intentional,
            };
        }
    }
}
