"""Zustand, Wachstum, Hunger und gelerntes Wissen."""

from __future__ import annotations

import json
import random
import time
from dataclasses import asdict, dataclass, field
from pathlib import Path
from typing import Any

DATA_DIR = Path(__file__).resolve().parent.parent / "data"
STATE_FILE = DATA_DIR / "jam_state.json"


@dataclass
class JamState:
    name: str = "Jam"
    owner_name: str = "David"
    age_days: float = 0.0
    xp: int = 0
    hunger: float = 0.35
    happiness: float = 0.7
    stage: int = 0
    size_scale: float = 0.78
    visual_theme: str = "base"
    visual_accessory: str = ""
    appearance_tint: list[int] = field(default_factory=lambda: [108, 42, 168])
    appearance_depth_boost: float = 0.0
    visual_evolution_step: int = 0
    visual_evolution_count: int = 0
    last_visual_evolve: float = 0.0
    learned_words: list[str] = field(default_factory=list)
    learned_sentences: list[str] = field(default_factory=list)
    sentence_learn_count: int = 0
    last_sentence_learn: float = 0.0
    learned_commands: dict[str, str] = field(default_factory=dict)
    memory_notes: list[str] = field(default_factory=list)
    play_sessions: int = 0
    last_fed: float = field(default_factory=time.time)
    last_interaction: float = field(default_factory=time.time)
    created_at: float = field(default_factory=time.time)
    total_speech_events: int = 0
    traits: dict[str, float] = field(default_factory=dict)
    rules: list[dict] = field(default_factory=list)
    praise_count: int = 0
    scold_count: int = 0
    discipline: float = 0.5
    last_thought: str = ""
    thought_log: list[str] = field(default_factory=list)
    last_action: str = ""
    last_feedback: str = ""
    last_feedback_at: float = 0.0
    cursor_sessions: list[dict] = field(default_factory=list)
    cursor_last_open: float = 0.0
    cursor_opens_total: int = 0
    cursor_self_improve_count: int = 0
    last_cursor_self_improve: float = 0.0
    music_love: float = 0.82
    last_youtube_open: float = 0.0
    youtube_opens: int = 0
    youtube_pick_index: int = 0
    last_youtube_query: str = ""
    last_tiktok_open: float = 0.0
    tiktok_friend_searches: int = 0
    tiktok_pick_index: int = 0
    last_tiktok_query: str = ""
    tiktok_like_celebrations: int = 0
    tiktok_account: str = "socialmedia.mentor"
    tiktok_connected: bool = False
    tiktok_connected_at: float = 0.0
    fiverr_connected: bool = False
    fiverr_username: str = ""
    fiverr_connected_at: float = 0.0
    fiverr_connect_count: int = 0
    fiverr_gig_push_count: int = 0
    last_fiverr_gig_push_at: float = 0.0
    jam_delegate_mode: bool = False
    jam_delegate_since: float = 0.0
    jam_delegate_grant_count: int = 0
    last_delegate_mission_at: float = 0.0
    delegate_mission_count: int = 0
    delegate_background_cycles: int = 0
    jam_urgent_offers_log: list = field(default_factory=list)
    urgent_offers_count: int = 0
    last_urgent_offer_at: float = 0.0
    fiverr_assist_count: int = 0
    last_fiverr_assist_at: float = 0.0
    tiktok_connect_count: int = 0
    last_music_reaction: float = 0.0
    last_music_sing_at: float = 0.0
    free_orders_count: int = 0
    last_free_order_at: float = 0.0
    last_free_browse_at: float = 0.0
    free_orders_log: list = field(default_factory=list)
    dance_sessions: int = 0
    last_idle_show_at: float = 0.0
    idle_shows_count: int = 0
    last_idle_show_kind: str = ""
    last_ki_studio_present: float = 0.0
    ki_studio_presents: int = 0
    last_learn_open: float = 0.0
    learn_opens: int = 0
    last_learn_site: str = ""
    learn_sites_history: list[str] = field(default_factory=list)
    learn_wants: list[str] = field(default_factory=list)
    last_curiosity_learn: float = 0.0
    internet_learn_count: int = 0
    money_venture_count: int = 0
    last_money_venture_at: float = 0.0
    money_potential_total: float = 0.0
    money_ventures_log: list = field(default_factory=list)
    paypal_donate_opens: int = 0
    last_paypal_donate_at: float = 0.0
    donations_asked_count: int = 0
    paypal_income_total: float = 0.0
    paypal_reward_count: int = 0
    last_paypal_reward_at: float = 0.0
    paypal_income_log: list = field(default_factory=list)
    cursor_business_count: int = 0
    last_cursor_business_at: float = 0.0
    cursor_business_log: list = field(default_factory=list)
    pc_control_enabled: bool = False
    pc_control_enabled_at: float = 0.0
    pc_control_actions: int = 0
    last_pc_control_at: float = 0.0
    gaming_fund_enabled: bool = True
    gaming_fund_goal_eur: float = 60.0
    gaming_fund_raised_eur: float = 0.0
    gaming_fund_cycles: int = 0
    last_gaming_fund_at: float = 0.0
    jam_sales_log: list = field(default_factory=list)
    jam_sale_count: int = 0
    last_jam_sale_at: float = 0.0
    last_jam_sale_price: float = 0.0
    jam_price_history: list = field(default_factory=list)
    jam_negotiate_count: int = 0
    last_negotiate_at: float = 0.0
    jam_next_price_target: float = 0.0
    jam_platforms_logged_in: bool = False
    jam_logged_in_at: float = 0.0
    jam_auto_fetch_enabled: bool = True
    jam_downloads_count: int = 0
    jam_upload_count: int = 0
    jam_upload_log: list = field(default_factory=list)
    last_auto_ops_at: float = 0.0
    owner_bond: float = 0.55
    jam_care_checks: int = 0
    last_care_at: float = 0.0
    jam_play_friends: list = field(default_factory=list)
    friend_match_count: int = 0
    last_friend_match_at: float = 0.0
    jam_in_room: bool = False
    jam_max_earn_mode: bool = True
    jam_active_sell_mode: bool = True
    sell_push_count: int = 0
    last_sell_push_at: float = 0.0
    jam_world_earn_mode: bool = True
    world_earn_count: int = 0
    last_world_earn_at: float = 0.0
    world_markets_opened: list = field(default_factory=list)
    jam_cent_total: float = 0.0
    jam_micro_wins_count: int = 0
    last_max_earn_at: float = 0.0
    max_earn_burst_count: int = 0
    jam_always_on: bool = True
    jam_earn_night_mode: bool = True
    jam_keep_awake_since: float = 0.0
    last_night_earn_pulse: float = 0.0
    night_earn_pulses: int = 0
    jam_night_focus: str = ""
    jam_night_intensity: float = 1.0
    jam_night_focus_until: float = 0.0
    jam_night_focus_started_at: float = 0.0
    jam_night_focus_cycles: int = 0
    jam_night_learn_enabled: bool = True
    jam_night_learn_count: int = 0
    jam_platform_learn_count: int = 0
    jam_platform_signup_mode: bool = False
    jam_platform_signup_until: float = 0.0
    jam_platform_signup_index: int = 0
    jam_platform_signup_attempts: int = 0
    jam_platform_signup_log: list = field(default_factory=list)
    last_platform_signup_at: float = 0.0
    jam_owner_auth_granted: bool = False
    jam_owner_auth_granted_at: float = 0.0
    last_firefox_captcha_at: float = 0.0
    telegram_shop_ready: bool = False
    telegram_setup_at: float = 0.0
    telegram_channel_link: str = ""
    last_telegram_ad_at: float = 0.0
    telegram_ad_count: int = 0
    freelancer_connected: bool = False
    freelancer_connected_at: float = 0.0
    freelancer_assist_count: int = 0
    last_freelancer_assist_at: float = 0.0
    jam_owner_rest_mode: bool = False
    jam_owner_rest_since: float = 0.0
    jam_browser_minimal: bool = False
    jam_auto_publish: bool = False
    last_auto_publish_at: float = 0.0
    auto_publish_count: int = 0
    fiverr_publish_attempted: bool = False
    gumroad_publish_count: int = 0
    jam_money_all_in_mode: bool = False
    jam_money_all_in_since: float = 0.0
    money_all_in_blitz_count: int = 0
    last_money_blitz_at: float = 0.0
    jam_outbound_sales_mode: bool = False
    jam_outbound_log: list = field(default_factory=list)
    outbound_prospect_count: int = 0
    last_outbound_at: float = 0.0
    jam_full_contact_grant: bool = False
    jam_contact_auto: bool = False
    last_contact_auto_at: float = 0.0
    contact_auto_count: int = 0
    jam_memory_budget_on: bool = False
    jam_memory_target_pct: float = 0.0
    jam_resource_mode: str = ""
    jam_ad_earn_mode: bool = False
    last_ad_earn_at: float = 0.0
    ad_earn_count: int = 0
    jam_ad_last_site: str = ""
    jam_ad_last_url: str = ""
    jam_ad_sites_log: list = field(default_factory=list)
    jam_deadline_mode: bool = False
    jam_deadline_until: float = 0.0
    jam_deadline_label: str = ""
    jam_deadline_since: float = 0.0
    last_deadline_sprint_at: float = 0.0
    deadline_sprint_count: int = 0
    jam_human_voice: bool = True
    jam_human_voice_since: float = 0.0
    jam_browser_autopilot: bool = False
    jam_browser_auto_since: float = 0.0
    last_jam_browser_auto_at: float = 0.0
    jam_browser_auto_count: int = 0
    jam_auto_email_mode: bool = False
    last_auto_email_at: float = 0.0
    auto_email_count: int = 0
    jam_survey_earn_mode: bool = False
    last_survey_earn_at: float = 0.0
    survey_earn_count: int = 0
    jam_sell_only_mode: bool = False
    jam_master_shop_url: str = ""
    jam_master_shop_count: int = 0
    jam_master_shop_built_at: float = 0.0
    last_master_shop_promo_at: float = 0.0
    jam_shop_page_views: int = 0
    jam_shop_buy_clicks: int = 0
    jam_shop_stats_at: float = 0.0
    jam_shop_top_products: list = field(default_factory=list)
    jam_pc_mining_on: bool = False
    jam_mining_started_at: float = 0.0
    jam_mining_device: str = ""
    jam_gpu_mining_on: bool = False
    jam_gpu_power_percent: int = 90
    jam_btc_address: str = ""
    jam_pc_activity_learn: bool = True
    pc_learn_session: dict = field(default_factory=dict)
    pc_activity_log: list = field(default_factory=list)
    pc_activity_totals: dict = field(default_factory=dict)
    pc_activity_interests: dict = field(default_factory=dict)
    pc_activity_events: int = 0
    last_pc_activity_tick_at: float = 0.0
    last_pc_activity_learn_at: float = 0.0
    jam_torchwood_watch: bool = True
    torchwood_mod_seconds: float = 0.0
    torchwood_mod_sessions: int = 0
    last_torchwood_mod_at: float = 0.0
    torchwood_announced: bool = False
    jam_torchwood_chat_read: bool = True
    torchwood_chat_learned: list = field(default_factory=list)
    torchwood_chat_messages_seen: int = 0
    torchwood_chat_seen_hashes: list = field(default_factory=list)
    jam_world_shop_mode: bool = False
    jam_master_shop_public_url: str = ""
    jam_reach_build_at: float = 0.0
    jam_reach_build_count: int = 0
    jam_world_shop_since: float = 0.0
    jam_programming_stopped: bool = False
    jam_pace_percent: int = 100
    jam_sell_focus_mode: bool = False
    jam_no_product_build: bool = False
    jam_all_tasks_stopped: bool = False
    jam_tiktok_post_schedule: bool = False
    jam_tiktok_niche: str = ""
    jam_tiktok_post_log: dict = field(default_factory=dict)
    jam_tiktok_post_count: int = 0
    last_tiktok_post_at: float = 0.0
    jam_tiktok_full_access: bool = False
    jam_tiktok_browser_logged_in: bool = False
    jam_tiktok_browser_logged_in_at: float = 0.0
    jam_tiktok_growth_sprint: bool = False
    jam_tiktok_follower_goal: int = 0
    jam_tiktok_followers_start: int = 0
    jam_tiktok_followers_current: int = 0
    jam_tiktok_goal_started_at: float = 0.0
    jam_tiktok_goal_deadline: float = 0.0
    jam_fiverr_focus_mode: bool = False
    jam_shop_always_on: bool = False
    jam_shop_heavy_promo: bool = False
    last_heavy_shop_promo_at: float = 0.0
    heavy_shop_promo_rounds: int = 0
    stream_scheduled_at: float = 0.0
    stream_prep_active: bool = False
    stream_live_announced: bool = False
    stream_prep_count: int = 0
    last_stream_prep_at: float = 0.0
    jam_earnings_report: list = field(default_factory=list)
    jam_earnings_total: float = 0.0
    jam_earnings_count: int = 0
    last_earning_record_at: float = 0.0
    extreme_learn_count: int = 0
    last_extreme_learn_at: float = 0.0
    extreme_learn_log: list = field(default_factory=list)
    last_fortnite_close: float = 0.0
    fortnite_closes: int = 0
    last_gaming_roast: float = 0.0
    gaming_roasts: int = 0
    last_apex_coach: float = 0.0
    apex_coach_count: int = 0
    apex_foreground_mode: bool = False
    last_apex_focus_at: float = 0.0
    last_bg_browser_url: str = ""
    last_line_spoken_at: float = 0.0
    last_line_spoken: str = ""
    last_line_shown_at: float = 0.0
    last_line_shown: str = ""
    recent_shown_lines: list = field(default_factory=list)

    def stage_from_xp(self) -> int:
        if self.xp < 80:
            return 0
        if self.xp < 250:
            return 1
        if self.xp < 600:
            return 2
        if self.xp < 1200:
            return 3
        return 4

    def apply_growth(self) -> None:
        self.stage = self.stage_from_xp()
        base = 0.72 + self.stage * 0.14 + min(self.age_days * 0.002, 0.28)
        self.size_scale = min(1.38, base)

    def tick_age(self) -> None:
        elapsed = time.time() - self.created_at
        self.age_days = elapsed / 86400.0
        self.apply_growth()

    def tick_hunger(self, dt_hours: float = 0.05) -> None:
        self.hunger = min(1.0, self.hunger + dt_hours * 0.08)
        if self.hunger > 0.85:
            self.happiness = max(0.1, self.happiness - 0.02)

    def feed(self, amount: float = 0.45) -> str:
        self.hunger = max(0.0, self.hunger - amount)
        self.happiness = min(1.0, self.happiness + 0.2)
        self.xp += 8
        self.last_fed = time.time()
        self.apply_growth()
        return random.choice(
            [
                "Mmh lecker! Danke!",
                "Nom nom nom!",
                "Boah, das war gut!",
                "Ich wachse gleich ein bisschen!",
            ]
        )

    def play(self) -> str:
        self.happiness = min(1.0, self.happiness + 0.25)
        self.xp += 12
        self.play_sessions += 1
        self.apply_growth()
        return random.choice(
            [
                "Juhu! Spielen!",
                "Ich hüpfe!",
                "Fang mich doch!",
                "Wheee!",
            ]
        )

    def add_xp(self, n: int) -> None:
        self.xp += n
        self.apply_growth()

    def learn_word(self, word: str) -> None:
        w = word.strip().lower()
        if w and w not in self.learned_words:
            self.learned_words.append(w)
            self.xp += 3

    def learn_command(self, phrase: str, action: str) -> None:
        key = phrase.strip().lower()
        if key:
            self.learned_commands[key] = action.strip()
            self.xp += 15
            self.memory_notes.append(f"Befehl: {key} -> {action}")

    def remember(self, note: str) -> None:
        if note.strip():
            self.memory_notes.append(note.strip()[:500])
            if len(self.memory_notes) > 200:
                self.memory_notes = self.memory_notes[-200:]
            self.xp += 5


class JamBrain:
    def __init__(self) -> None:
        DATA_DIR.mkdir(parents=True, exist_ok=True)
        self.state = self._load()

    def _load(self) -> JamState:
        if not STATE_FILE.exists():
            s = JamState()
            self._normalize(s)
            return s
        try:
            raw = json.loads(STATE_FILE.read_text(encoding="utf-8"))
            state = JamState(**{k: v for k, v in raw.items() if k in JamState.__dataclass_fields__})
            self._normalize(state)
            return state
        except (json.JSONDecodeError, TypeError):
            s = JamState()
            self._normalize(s)
            return s

    def _normalize(self, state: JamState) -> None:
        from jam.owner import DEFAULT_OWNER
        from jam.upbringing import DEFAULT_TRAITS, ensure_traits

        ensure_traits(state)
        if not state.traits:
            state.traits = dict(DEFAULT_TRAITS)
        if not (getattr(state, "owner_name", None) or "").strip():
            state.owner_name = DEFAULT_OWNER

    def add_xp(self, n: int) -> None:
        self.state.add_xp(n)

    def save(self) -> None:
        self.state.tick_age()
        STATE_FILE.write_text(
            json.dumps(asdict(self.state), ensure_ascii=False, indent=2),
            encoding="utf-8",
        )

    def tick(self) -> None:
        self.state.tick_age()
        self.state.tick_hunger()
        self.state.last_interaction = time.time()

    def export_for_ai(self) -> dict[str, Any]:
        return asdict(self.state)
