//! Emotion keybindings with localStorage persistence.

use chattyness_db::models::EmotionState;
use serde::{Deserialize, Serialize};

use crate::utils::LocalStoragePersist;

/// Key slot names for the 12 emotion keybindings.
/// Maps to e1, e2, ..., e9, e0, eq, ew
pub const KEYBINDING_SLOTS: [&str; 12] =
    ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "q", "w"];

/// Default emotion order for keybinding slots.
/// Slot 0 (e1) is always Happy (locked).
/// Remaining slots ordered by approximate utility/frequency.
pub const DEFAULT_EMOTION_ORDER: [EmotionState; 12] = [
    EmotionState::Happy,     // e1 - locked
    EmotionState::Laughing,  // e2
    EmotionState::Love,      // e3
    EmotionState::Wink,      // e4
    EmotionState::Surprised, // e5
    EmotionState::Thinking,  // e6
    EmotionState::Neutral,   // e7
    EmotionState::Confused,  // e8
    EmotionState::Sad,       // e9
    EmotionState::Angry,     // e0
    EmotionState::Crying,    // eq
    EmotionState::Sleeping,  // ew
];

/// All emotions available for selection.
pub const ALL_EMOTIONS: [EmotionState; 12] = [
    EmotionState::Neutral,
    EmotionState::Happy,
    EmotionState::Sad,
    EmotionState::Angry,
    EmotionState::Surprised,
    EmotionState::Thinking,
    EmotionState::Laughing,
    EmotionState::Crying,
    EmotionState::Love,
    EmotionState::Confused,
    EmotionState::Sleeping,
    EmotionState::Wink,
];

/// Emotion keybindings configuration.
///
/// Maps 12 key slots (e1-e0, eq, ew) to emotion states.
/// Slot 0 (e1) is always locked to Happy.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct EmotionKeybindings {
    /// The emotion assigned to each slot (0-11).
    pub slots: [EmotionState; 12],
}

impl Default for EmotionKeybindings {
    fn default() -> Self {
        Self {
            slots: DEFAULT_EMOTION_ORDER,
        }
    }
}

// Implement LocalStoragePersist trait for automatic load/save
impl LocalStoragePersist for EmotionKeybindings {
    const STORAGE_KEY: &'static str = "chattyness_emotion_keybindings";

    /// Ensure slot 0 is always Happy (enforce lock) after loading.
    fn post_load(&mut self) {
        self.slots[0] = EmotionState::Happy;
    }
}

impl EmotionKeybindings {
    /// Get the emotion for a given key (after 'e' was pressed).
    ///
    /// Keys: "1"-"9", "0", "q", "w"
    pub fn get_emotion_for_key(&self, key: &str) -> Option<EmotionState> {
        let index = match key {
            "1" => 0,
            "2" => 1,
            "3" => 2,
            "4" => 3,
            "5" => 4,
            "6" => 5,
            "7" => 6,
            "8" => 7,
            "9" => 8,
            "0" => 9,
            "q" | "Q" => 10,
            "w" | "W" => 11,
            _ => return None,
        };
        Some(self.slots[index])
    }

    /// Set the emotion for a slot (0-11).
    ///
    /// Slot 0 is locked to Happy and cannot be changed.
    pub fn set_slot(&mut self, index: usize, emotion: EmotionState) {
        if index == 0 {
            return; // Slot 0 is locked to Happy
        }
        if index < 12 {
            self.slots[index] = emotion;
        }
    }

    /// Reset all slots to default values.
    pub fn reset_to_defaults(&mut self) {
        self.slots = DEFAULT_EMOTION_ORDER;
    }

    /// Get the display label for a slot (e.g., "e1", "e0", "eq").
    pub fn slot_label(index: usize) -> &'static str {
        match index {
            0 => "e1",
            1 => "e2",
            2 => "e3",
            3 => "e4",
            4 => "e5",
            5 => "e6",
            6 => "e7",
            7 => "e8",
            8 => "e9",
            9 => "e0",
            10 => "eq",
            11 => "ew",
            _ => "??",
        }
    }
}
