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

namespace ArachnaeSwarm
{
    public class JobGiver_Grower : ThinkNode_JobGiver
    {
        private WorkGiver_GrowerHarvest _workGiverHarvest;
        private WorkGiver_Scanner _workGiverPlantsCut; // 通用扫描器类型
        private WorkGiver_ArachnaeSow _workGiverArachnaeSow;

        protected override Job TryGiveJob(Pawn pawn)
        {
            if (_workGiverHarvest == null)
            {
                _workGiverHarvest = WorkGiverDefOf.GrowerHarvest.Worker as WorkGiver_GrowerHarvest;
                _workGiverPlantsCut = WorkGiverDefOf.PlantsCut.Worker as WorkGiver_Scanner;
                _workGiverArachnaeSow = new WorkGiver_ArachnaeSow();

                if (_workGiverHarvest == null || _workGiverPlantsCut == null)
                {
                    Log.ErrorOnce("JobGiver_Grower: Failed to get a required WorkGiver. DefOfs might not be initialized.", 123458);
                    return null;
                }
            }

            // 1. 优先收获（自动）
            IntVec3 bestHarvestCell = FindClosestHarvestableCell(pawn);
            if (bestHarvestCell.IsValid)
            {
                return _workGiverHarvest.JobOnCell(pawn, bestHarvestCell);
            }

            // 2. 其次处理手动指定的砍伐/收获任务
            Thing bestCuttable = FindClosestWorkableThing(pawn, _workGiverPlantsCut);
            if (bestCuttable != null)
            {
                return _workGiverPlantsCut.JobOnThing(pawn, bestCuttable);
            }

            // 3. 最后播种（自动，并清理障碍）
            (IntVec3 bestSowCell, ThingDef plantToSow) = FindClosestSowableCellAndPlant(pawn, _workGiverArachnaeSow);
            if (bestSowCell.IsValid && plantToSow != null)
            {
                return _workGiverArachnaeSow.JobOnCell(pawn, bestSowCell);
            }
            
            return null;
        }

        private Thing FindClosestWorkableThing(Pawn pawn, WorkGiver_Scanner scanner)
        {
            return GenClosest.ClosestThing_Global(
                pawn.Position,
                scanner.PotentialWorkThingsGlobal(pawn),
                maxDistance: 9999f,
                validator: t => t != null && !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t) && pawn.CanReach(t, PathEndMode.Touch, Danger.Deadly)
            );
        }

        private IntVec3 FindClosestHarvestableCell(Pawn pawn)
        {
            IntVec3 bestCell = IntVec3.Invalid;
            float bestDistSq = float.MaxValue;

            foreach (Zone zone in pawn.Map.zoneManager.AllZones)
            {
                if (zone is Zone_Growing growingZone)
                {
                    foreach (IntVec3 cell in growingZone.Cells)
                    {
                        float distSq = pawn.Position.DistanceToSquared(cell);
                        if (distSq < bestDistSq && pawn.CanReach(cell, PathEndMode.ClosestTouch, Danger.Deadly))
                        {
                            if (_workGiverHarvest.HasJobOnCell(pawn, cell))
                            {
                                bestDistSq = distSq;
                                bestCell = cell;
                            }
                        }
                    }
                }
            }
            return bestCell;
        }

        private (IntVec3, ThingDef) FindClosestSowableCellAndPlant(Pawn pawn, WorkGiver_ArachnaeSow scanner)
        {
            IntVec3 bestCell = IntVec3.Invalid;
            ThingDef bestPlantToSow = null;
            float bestDistSq = float.MaxValue;
            
            foreach (Zone zone in pawn.Map.zoneManager.AllZones)
            {
                if (zone is Zone_Growing growingZone)
                {
                    ThingDef wantedPlant = growingZone.GetPlantDefToGrow();
                    if (wantedPlant == null) continue;

                    foreach (IntVec3 cell in growingZone.Cells)
                    {
                        float distSq = pawn.Position.DistanceToSquared(cell);
                        if (distSq < bestDistSq && pawn.CanReach(cell, PathEndMode.ClosestTouch, Danger.Deadly))
                        {
                            if (scanner.HasJobOnCell(pawn, cell))
                            {
                                bestDistSq = distSq;
                                bestCell = cell;
                                bestPlantToSow = wantedPlant;
                            }
                        }
                    }
                }
            }
            return (bestCell, bestPlantToSow);
        }
    }
}

[DefOf]
public static class WorkGiverDefOf
{
    public static WorkGiverDef GrowerHarvest;
    public static WorkGiverDef PlantsCut;
 
    static WorkGiverDefOf()
    {
        DefOfHelper.EnsureInitializedInCtor(typeof(WorkGiverDefOf));
    }
}