using System.Collections.Generic;
using Verse;
using RimWorld;
using Verse.AI;
using Verse.AI.Group;

namespace ArachnaeSwarm
{
    public class CompSpawnPawnFromList : ThingComp
    {
        public CompProperties_SpawnPawnFromList Props => (CompProperties_SpawnPawnFromList)props;

        private int spawnUntilTick = -1;
        private PawnKindDef spawningPawnKind;
        private PawnKindDef selectedPawnKind;
        public bool IsHatching => spawnUntilTick > 0;
        
        public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
        {
            if (spawnUntilTick > 0)
            {
                yield break; // 正在延迟中，不显示菜单
            }

            if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef))
            {
                yield break;
            }

            if (Props.pawnKinds != null)
            {
                foreach (PawnKindDef pawnKind in Props.pawnKinds)
                {
                    yield return new FloatMenuOption("ARA_Incubate".Translate(pawnKind.label), () =>
                    {
                        Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_IncubateJob"), parent);
                        selectedPawnKind = pawnKind;
                        selPawn.jobs.TryTakeOrderedJob(job);
                    });
                }
            }
        }


        public void StartIncubation()
        {
            spawningPawnKind = selectedPawnKind;
            spawnUntilTick = Find.TickManager.TicksGame + Props.delay;
        }

        public override void CompTick()
        {
            base.CompTick();
            if (spawnUntilTick > 0 && Find.TickManager.TicksGame >= spawnUntilTick)
            {
                SpawnPawn(spawningPawnKind);
            }
        }



        private void SpawnPawn(PawnKindDef pawnKind)
        {
            try
            {
                if (pawnKind == null)
                {
                    Log.Warning("CompSpawnPawnFromList: Tried to spawn pawn but pawnKind is null.");
                    return;
                }

                if (!parent.Spawned || parent.Map == null)
                {
                    Log.Error($"CompSpawnPawnFromList: Cannot spawn pawn. Parent {parent} is not spawned or map is null.");
                    return;
                }

                int count = Props.spawnCount.RandomInRange;
                for (int i = 0; i < count; i++)
                {
                    Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnKind, parent.Faction));
                    if (pawn == null)
                    {
                        Log.Error($"CompSpawnPawnFromList: Failed to generate pawn of kind {pawnKind.defName} for faction {parent.Faction?.Name ?? "null"}.");
                        continue;
                    }

                    if (GenSpawn.Spawn(pawn, parent.Position, parent.Map) == null)
                    {
                        Log.Error($"CompSpawnPawnFromList: Failed to spawn pawn {pawn} at {parent.Position}.");
                        if (!pawn.Destroyed)
                        {
                            pawn.Destroy();
                        }
                        continue;
                    }

                    if (Props.lordJob != null)
                    {
                        try
                        {
                            LordJob lordJobInstance = (LordJob)System.Activator.CreateInstance(Props.lordJob);
                            Lord lord = LordMaker.MakeNewLord(parent.Faction, lordJobInstance, parent.Map);
                            lord.AddPawn(pawn);
                        }
                        catch (System.Exception e)
                        {
                            Log.Error($"CompSpawnPawnFromList: Error creating LordJob {Props.lordJob?.Name ?? "null"} or assigning pawn {pawn}. Exception: {e}");
                        }
                    }
                }

                if (Props.destroyOnSpawn)
                {
                    parent.Destroy(DestroyMode.Vanish);
                }
            }
            finally
            {
                spawnUntilTick = -1;
                spawningPawnKind = null;
            }
        }


        public override string CompInspectStringExtra()
        {
            if (spawnUntilTick > 0)
            {
                int remainingTicks = spawnUntilTick - Find.TickManager.TicksGame;
                if (remainingTicks > 0)
                {
                    return "Spawning {0} in: {1}".Translate(spawningPawnKind.label, remainingTicks.ToStringTicksToPeriod());
                }
            }
            else
            {
                return "ARA_NeedsInteraction".Translate();
            }
            return null;
        }

        public override void PostExposeData()
        {
            base.PostExposeData();
            Scribe_Values.Look(ref spawnUntilTick, "spawnUntilTick", -1);
            Scribe_Defs.Look(ref spawningPawnKind, "spawningPawnKind");
            Scribe_Defs.Look(ref selectedPawnKind, "selectedPawnKind");
        }
    }
}