// ─── Enchanting Tick Handlers ─────────────────────────────────────────────────
// Design → Prepare → Application tick processing for the enchanting pipeline.
// Extracted from gameStore.ts to keep the coordinator under the 400-line limit.
//
// IMPORTANT: This function reads from the ctx snapshot and returns writes.
// It must NOT call useCraftingStore.setState() directly — that would bypass
// the tick pipeline's snapshot-and-batch-write pattern and cause race conditions.

import { HOURS_PER_TICK } from '../../constants';
import type { ComputedEffects } from '../../effects/upgrade-effects.types';
import { calculateDesignProgress, createCompletedDesignFromProgress } from '../../crafting-design';
import { calculatePreparationTick, completePreparation } from '../../crafting-prep';
import { calculateApplicationTick, applyEnchantments, updateEnchanterAttunement } from '../../crafting-apply';
import { getEnchantingEfficiencyBonus } from '../../effects/discipline-effects';
import type { TickContext, TickWrites } from '../tick-pipeline';

interface EnchantingTickParams {
  ctx: TickContext;
  effects: ComputedEffects;
  rawMana: number;
  addLog: (msg: string) => void;
}

export function processEnchantingTicks(
  params: EnchantingTickParams,
): { rawMana: number; writes: Partial<TickWrites> } {
  const { ctx, effects, rawMana: initialRawMana, addLog } = params;
  let rawMana = initialRawMana;
  const writes: Partial<TickWrites> = {};
  const currentAction = ctx.combat.currentAction;

  // Helper to merge crafting writes
  const mergeCrafting = (partial: Partial<typeof ctx.crafting>) => {
    writes.crafting = { ...(writes.crafting || {}), ...partial } as typeof writes.crafting;
  };

  // ── Phase 1: Design ──────────────────────────────────────────────────────
  if (currentAction === 'design') {
    const designProgress = ctx.crafting.designProgress;
    const designProgress2 = ctx.crafting.designProgress2;
    if (!designProgress && !designProgress2) {
      writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
    } else {
      const activeProgress = designProgress || designProgress2!;
      const isRepeatDesign = ctx.crafting.completedEnchantmentDesigns.some(
        (d) => d.name === activeProgress.name,
      );
      const designResult = calculateDesignProgress(
        activeProgress.progress,
        activeProgress.required,
        effects,
        isRepeatDesign,
      );
      if (designResult.isComplete) {
        const completedDesign = createCompletedDesignFromProgress(
          {
            designId: activeProgress.designId,
            name: activeProgress.name,
            equipmentType: activeProgress.equipmentType,
            effects: activeProgress.effects,
            required: activeProgress.required,
          },
          getEnchantingEfficiencyBonus(),
        );
        // Return write instead of calling store directly
        mergeCrafting({
          completedEnchantmentDesigns: [...ctx.crafting.completedEnchantmentDesigns, completedDesign],
          designProgress: designProgress ? null : undefined,
          designProgress2: designProgress2 ? null : undefined,
        });
        addLog('Design "' + completedDesign.name + '" completed!');
        writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
      } else {
        // Return write instead of calling store directly
        if (designProgress) {
          mergeCrafting({
            designProgress: {
              ...designProgress,
              progress: designResult.progress,
            },
          });
        } else if (designProgress2) {
          mergeCrafting({
            designProgress2: {
              ...designProgress2,
              progress: designResult.progress,
            },
          });
        }
      }
    }
  }

  // ── Phase 2: Preparation ─────────────────────────────────────────────────
  if (currentAction === 'prepare') {
    const prepProgress = ctx.crafting.preparationProgress;
    if (!prepProgress) {
      writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
    } else {
      const instance = ctx.crafting.equipmentInstances[prepProgress.equipmentInstanceId];
      if (!instance) {
        mergeCrafting({ preparationProgress: null });
        writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
        addLog('Preparation failed: equipment not found.');
      } else {
        const manaPerTick = (instance.totalCapacity * 10) / (2 + Math.floor(instance.totalCapacity / 50)) * HOURS_PER_TICK;
        const prepResult = calculatePreparationTick(
          prepProgress.progress,
          prepProgress.required,
          prepProgress.manaCostPaid,
          manaPerTick,
        );
        if (prepResult.manaConsumed > 0) {
          rawMana = Math.max(0, rawMana - prepResult.manaConsumed);
        }
        if (prepResult.isComplete) {
          const completionResult = completePreparation(instance);
          const newInstances = { ...ctx.crafting.equipmentInstances };
          newInstances[prepProgress.equipmentInstanceId] = completionResult.updatedInstance;
          mergeCrafting({
            equipmentInstances: newInstances,
            preparationProgress: null,
          });
          writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
          addLog(completionResult.logMessage);
        } else {
          mergeCrafting({
            preparationProgress: {
              ...prepProgress,
              progress: prepResult.progress,
              manaCostPaid: prepResult.manaCostPaid,
            },
          });
        }
      }
    }
  }

  // ── Phase 3: Application ─────────────────────────────────────────────────
  if (currentAction === 'enchant') {
    const appProgress = ctx.crafting.applicationProgress;
    if (!appProgress || appProgress.paused) {
      if (!appProgress) {
        writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
      }
    } else {
      const instance = ctx.crafting.equipmentInstances[appProgress.equipmentInstanceId];
      const design = ctx.crafting.completedEnchantmentDesigns.find((d) => d.id === appProgress.designId);
      if (!instance || !design) {
        mergeCrafting({ applicationProgress: null });
        writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
        addLog('Enchantment failed: equipment or design not found.');
      } else {
        const totalStacks = design.effects.reduce((s, e) => s + e.stacks, 0);
        const manaPerTick = (20 + 5 * totalStacks) * HOURS_PER_TICK;
        const appResult = calculateApplicationTick(
          appProgress.progress,
          appProgress.required,
          appProgress.manaSpent,
          manaPerTick,
          effects,
        );
        if (appResult.manaConsumed > 0) {
          rawMana = Math.max(0, rawMana - appResult.manaConsumed);
        }
        if (appResult.isComplete) {
          const applyResult = applyEnchantments(instance, design, effects);
          const newInstances = { ...ctx.crafting.equipmentInstances };
          newInstances[appProgress.equipmentInstanceId] = applyResult.updatedInstance;
          mergeCrafting({
            equipmentInstances: newInstances,
            applicationProgress: null,
          });
          const updatedAttunements = updateEnchanterAttunement(
            ctx.attunement.attunements,
            applyResult.xpGained,
          );
          writes.attunement = { ...(writes.attunement || {}), attunements: updatedAttunements };
          writes.combat = { ...(writes.combat || {}), currentAction: 'meditate' };
          addLog(applyResult.logMessage);
          if (appResult.triggeredFreeEnchant) {
            addLog('Free enchantment triggered! No mana consumed this tick.');
          }
        } else {
          mergeCrafting({
            applicationProgress: {
              ...appProgress,
              progress: appResult.progress,
              manaSpent: appResult.manaSpent,
            },
          });
        }
      }
    }
  }

  return { rawMana, writes };
}
