package com.tiedup.remake.personality;

import java.util.EnumMap;
import java.util.Map;

/**
 * Centralized lookup table for personality ↔ job interactions.
 * Avoids scattered switch statements in each goal.
 */
public final class JobPersonalityModifiers {

    private JobPersonalityModifiers() {}

    /**
     * Per-personality job modifier entry.
     */
    private record JobModEntry(
        float efficiencyMod,
        NpcCommand preferredJob,
        NpcCommand dislikedJob,
        float moodModifier
    ) {}

    /**
     * Map of (PersonalityType, NpcCommand) → efficiency modifier.
     * Only non-default entries are stored; default is 1.0.
     */
    private static final Map<
        PersonalityType,
        Map<NpcCommand, Float>
    > EFFICIENCY_TABLE = new EnumMap<>(PersonalityType.class);

    /** Preferred jobs per personality */
    private static final Map<PersonalityType, NpcCommand> PREFERRED_JOBS =
        new EnumMap<>(PersonalityType.class);

    /** Disliked jobs per personality */
    private static final Map<PersonalityType, NpcCommand> DISLIKED_JOBS =
        new EnumMap<>(PersonalityType.class);

    static {
        // GENTLE: Good at breeding/farming, bad at mining
        putEfficiency(PersonalityType.GENTLE, NpcCommand.BREED, 1.3f);
        putEfficiency(PersonalityType.GENTLE, NpcCommand.FARM, 1.2f);
        putEfficiency(PersonalityType.GENTLE, NpcCommand.MINE, 0.7f);
        PREFERRED_JOBS.put(PersonalityType.GENTLE, NpcCommand.BREED);
        DISLIKED_JOBS.put(PersonalityType.GENTLE, NpcCommand.MINE);

        // FIERCE: Good at guarding/mining, bad at cooking
        putEfficiency(PersonalityType.FIERCE, NpcCommand.GUARD, 1.3f);
        putEfficiency(PersonalityType.FIERCE, NpcCommand.MINE, 1.2f);
        putEfficiency(PersonalityType.FIERCE, NpcCommand.COOK, 0.7f);
        PREFERRED_JOBS.put(PersonalityType.FIERCE, NpcCommand.GUARD);
        DISLIKED_JOBS.put(PersonalityType.FIERCE, NpcCommand.COOK);

        // CURIOUS: Good at collecting, bad at patrol
        putEfficiency(PersonalityType.CURIOUS, NpcCommand.COLLECT, 1.3f);
        putEfficiency(PersonalityType.CURIOUS, NpcCommand.PATROL, 0.8f);
        PREFERRED_JOBS.put(PersonalityType.CURIOUS, NpcCommand.COLLECT);
        DISLIKED_JOBS.put(PersonalityType.CURIOUS, NpcCommand.PATROL);

        // PLAYFUL: Good at breeding/collecting, bad at sorting
        putEfficiency(PersonalityType.PLAYFUL, NpcCommand.BREED, 1.2f);
        putEfficiency(PersonalityType.PLAYFUL, NpcCommand.COLLECT, 1.1f);
        putEfficiency(PersonalityType.PLAYFUL, NpcCommand.SORT, 0.8f);
        PREFERRED_JOBS.put(PersonalityType.PLAYFUL, NpcCommand.BREED);
        DISLIKED_JOBS.put(PersonalityType.PLAYFUL, NpcCommand.SORT);

        // PROUD: Good at guarding/patrolling, bad at collecting
        putEfficiency(PersonalityType.PROUD, NpcCommand.GUARD, 1.2f);
        putEfficiency(PersonalityType.PROUD, NpcCommand.PATROL, 1.1f);
        putEfficiency(PersonalityType.PROUD, NpcCommand.COLLECT, 0.7f);
        PREFERRED_JOBS.put(PersonalityType.PROUD, NpcCommand.GUARD);
        DISLIKED_JOBS.put(PersonalityType.PROUD, NpcCommand.COLLECT);

        // TIMID: Good at fishing (peaceful), bad at guarding
        putEfficiency(PersonalityType.TIMID, NpcCommand.FISH, 1.2f);
        putEfficiency(PersonalityType.TIMID, NpcCommand.FARM, 1.1f);
        putEfficiency(PersonalityType.TIMID, NpcCommand.GUARD, 0.7f);
        PREFERRED_JOBS.put(PersonalityType.TIMID, NpcCommand.FISH);
        DISLIKED_JOBS.put(PersonalityType.TIMID, NpcCommand.GUARD);

        // SUBMISSIVE: Good at all jobs (obedient), slight preference for sorting
        putEfficiency(PersonalityType.SUBMISSIVE, NpcCommand.SORT, 1.2f);
        putEfficiency(PersonalityType.SUBMISSIVE, NpcCommand.TRANSFER, 1.1f);
        PREFERRED_JOBS.put(PersonalityType.SUBMISSIVE, NpcCommand.SORT);
        DISLIKED_JOBS.put(PersonalityType.SUBMISSIVE, NpcCommand.MINE);

        // CALM: Balanced, slight cooking bonus
        putEfficiency(PersonalityType.CALM, NpcCommand.COOK, 1.1f);
        putEfficiency(PersonalityType.CALM, NpcCommand.FARM, 1.1f);
        PREFERRED_JOBS.put(PersonalityType.CALM, NpcCommand.COOK);
        DISLIKED_JOBS.put(PersonalityType.CALM, NpcCommand.MINE);

        // DEFIANT: Bad at most jobs (resistant), decent at mining (physical outlet)
        putEfficiency(PersonalityType.DEFIANT, NpcCommand.MINE, 1.1f);
        putEfficiency(PersonalityType.DEFIANT, NpcCommand.FARM, 0.7f);
        putEfficiency(PersonalityType.DEFIANT, NpcCommand.SORT, 0.6f);
        PREFERRED_JOBS.put(PersonalityType.DEFIANT, NpcCommand.MINE);
        DISLIKED_JOBS.put(PersonalityType.DEFIANT, NpcCommand.SORT);

        // MASOCHIST: Good at hard labor
        putEfficiency(PersonalityType.MASOCHIST, NpcCommand.MINE, 1.2f);
        putEfficiency(PersonalityType.MASOCHIST, NpcCommand.FARM, 1.1f);
        PREFERRED_JOBS.put(PersonalityType.MASOCHIST, NpcCommand.MINE);
        DISLIKED_JOBS.put(PersonalityType.MASOCHIST, NpcCommand.FISH);

        // SADIST: Good at guarding (intimidation), bad at breeding (no patience)
        putEfficiency(PersonalityType.SADIST, NpcCommand.GUARD, 1.3f);
        putEfficiency(PersonalityType.SADIST, NpcCommand.BREED, 0.7f);
        PREFERRED_JOBS.put(PersonalityType.SADIST, NpcCommand.GUARD);
        DISLIKED_JOBS.put(PersonalityType.SADIST, NpcCommand.BREED);
    }

    private static void putEfficiency(
        PersonalityType type,
        NpcCommand cmd,
        float mod
    ) {
        EFFICIENCY_TABLE.computeIfAbsent(type, k ->
            new EnumMap<>(NpcCommand.class)
        ).put(cmd, mod);
    }

    /**
     * Get the efficiency modifier for a personality performing a specific job.
     *
     * @param personality NPC personality type
     * @param command     Job command being performed
     * @return Efficiency multiplier (0.6 to 1.3, default 1.0)
     */
    public static float getEfficiencyModifier(
        PersonalityType personality,
        NpcCommand command
    ) {
        Map<NpcCommand, Float> personalityMods = EFFICIENCY_TABLE.get(
            personality
        );
        if (personalityMods == null) return 1.0f;
        return personalityMods.getOrDefault(command, 1.0f);
    }

    /**
     * Get the preferred job for a personality type.
     *
     * @param personality NPC personality type
     * @return Preferred NpcCommand, or FARM as default
     */
    public static NpcCommand getPreferredJob(PersonalityType personality) {
        return PREFERRED_JOBS.getOrDefault(personality, NpcCommand.FARM);
    }

    /**
     * Get the disliked job for a personality type.
     *
     * @param personality NPC personality type
     * @return Disliked NpcCommand, or NONE as default
     */
    public static NpcCommand getDislikedJob(PersonalityType personality) {
        return DISLIKED_JOBS.getOrDefault(personality, NpcCommand.NONE);
    }

    /**
     * Get the mood modifier for a personality performing a specific job.
     * Positive if preferred, negative if disliked, 0 otherwise.
     *
     * @param personality NPC personality type
     * @param command     Job command being performed
     * @return Mood modifier (-0.1 to +0.1)
     */
    public static float getJobMoodModifier(
        PersonalityType personality,
        NpcCommand command
    ) {
        if (command == getPreferredJob(personality)) {
            return 0.1f;
        }
        if (command == getDislikedJob(personality)) {
            return -0.1f;
        }
        return 0.0f;
    }
}
