"""Config, inbox state, and history for Superpitch."""

from __future__ import annotations

import json
import re
from datetime import datetime

from superpitch.app_paths import CONFIG_FILE, HISTORY_FILE


def default_config():
    return {
        "onboarding_complete": False,
        "onboarding_version":  0,
        "signed_in":           False,
        "session_token":       "",
        "user_email":          "",
        "user_slug":           "",
        "thesis":              "",
        "anthropic_api_key":   "",
        "receive_address":     "",
        "last_synced_at":      "",
        "auto_reply":          True,
    }


def load_config() -> dict:
    if not CONFIG_FILE.exists():
        return default_config()
    with open(CONFIG_FILE) as f:
        data = json.load(f)
    return {**default_config(), **data}


def save_config(config: dict) -> None:
    CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
    with open(CONFIG_FILE, "w") as f:
        json.dump(config, f, indent=2)


# ── History ───────────────────────────────────────────────────────────────────

def normalize_history_item(item: dict) -> dict:
    """Ensure all expected fields exist, handling both old and new schema."""
    # New schema fields
    action = item.get("action") or _migrate_action(item)
    return {
        **item,
        "action":        action,
        "confidence":    item.get("confidence", 0.0),
        "action_reason": item.get("action_reason", ""),
        "company":       item.get("company") or item.get("one_liner", "")[:60],
        "one_liner":     item.get("one_liner", ""),
        "sector":        item.get("sector", ""),
        "stage":         item.get("stage", ""),
        "geography":     item.get("geography", ""),
        "ask":           item.get("ask"),
        "traction":      item.get("traction", ""),
        "team":          item.get("team", ""),
        "thesis_fit":    item.get("thesis_fit", ""),
        "research":      item.get("research") or [],
        "missing":       item.get("missing") or [],
        "questions":     item.get("questions") or [],
        "unsure":            item.get("unsure", False),
        "questions_sent_at": item.get("questions_sent_at"),
        "awaiting_reply":    item.get("awaiting_reply", False),
        "reply_count":       item.get("reply_count", 0),
        "opened_at":         item.get("opened_at"),
        "decision_state": item.get("decision_state"),
        "decided_at":    item.get("decided_at"),
        "source_label":  item.get("source_label", ""),
        "raw_email_id":  item.get("raw_email_id"),
        "cloud_pitch_id": item.get("cloud_pitch_id"),
        "replies":       item.get("replies") or [],
    }


def _migrate_action(item: dict) -> str:
    """Derive action from old-format final_action if present."""
    old = item.get("final_action", "").upper()
    if old == "APPROVE":
        return "ESCALATE"
    if old == "REVIEW":
        return "REVIEW"
    return "PASS"


def load_history(limit: int | None = None) -> list[dict]:
    if not HISTORY_FILE.exists():
        return []
    items = []
    with open(HISTORY_FILE) as f:
        for line in f:
            line = line.strip()
            if line:
                items.append(normalize_history_item(json.loads(line)))
    if limit is not None:
        return items[-limit:]
    return items


def save_history(items: list[dict]) -> None:
    HISTORY_FILE.parent.mkdir(parents=True, exist_ok=True)
    with open(HISTORY_FILE, "w") as f:
        for item in items:
            f.write(json.dumps(item) + "\n")


def update_history_item(index: int, item: dict) -> None:
    items = load_history()
    if 0 <= index < len(items):
        items[index] = item
        save_history(items)


def save_evidence_entry(
    packet: dict,
    raw_email_id: str | None = None,
    source_label: str = "",
    cloud_pitch_id: str | None = None,
) -> dict:
    """Save a processed evidence packet to history."""
    HISTORY_FILE.parent.mkdir(parents=True, exist_ok=True)
    record = {
        "timestamp":     datetime.now().isoformat(),
        "source_label":  source_label,
        "one_liner":     packet.get("one_liner", ""),
        "company":       packet.get("company", ""),
        "founder_name":  packet.get("founder_name"),
        "founder_email": packet.get("founder_email"),
        "stage":         packet.get("stage", ""),
        "sector":        packet.get("sector", ""),
        "geography":     packet.get("geography"),
        "ask":           packet.get("ask"),
        "traction":      packet.get("traction", ""),
        "team":          packet.get("team", ""),
        "business_model": packet.get("business_model", ""),
        "thesis_fit":    packet.get("thesis_fit", ""),
        "research":      packet.get("research") or [],
        "missing":       packet.get("missing") or [],
        "questions":     packet.get("questions") or [],
        "action":        packet.get("action", "REVIEW"),
        "confidence":    float(packet.get("confidence", 0.0)),
        "action_reason": packet.get("action_reason", ""),
        "unsure":        bool(packet.get("unsure", False)),
        "opened_at":     None,
        "decision_state": None,
        "decided_at":    None,
        "raw_email_id":  raw_email_id,
        "cloud_pitch_id": cloud_pitch_id,
    }
    with open(HISTORY_FILE, "a") as f:
        f.write(json.dumps(record) + "\n")
    return record


def mark_pitch_opened(real_index: int, item: dict) -> dict:
    if item.get("opened_at") is None:
        item["opened_at"] = datetime.now().isoformat()
        update_history_item(real_index, item)
    return item


def history_bucket(item: dict) -> str:
    if item.get("decision_state"):
        return "decided"
    if item.get("opened_at"):
        return "seen"
    return "new"


# ── Ranking ───────────────────────────────────────────────────────────────────

_ACTION_RANK = {"ESCALATE": 0, "REVIEW": 1, "PASS": 2}


def build_ranked_items(items: list[dict]) -> list[tuple[int, dict]]:
    """Return (real_index, item) sorted: undecided first by action + confidence, decided last."""
    queue = [(i, item) for i, item in enumerate(items) if history_bucket(item) != "decided"]
    done  = [(i, item) for i, item in enumerate(items) if history_bucket(item) == "decided"]

    queue.sort(key=lambda e: (
        _ACTION_RANK.get(e[1].get("action", "PASS"), 9),
        -float(e[1].get("confidence", 0)),
        e[1].get("timestamp", ""),
    ))
    done.sort(key=lambda e: e[1].get("decided_at") or e[1].get("timestamp", ""), reverse=True)

    return queue + done


# ── Config helpers ────────────────────────────────────────────────────────────

def profile_status_line(config: dict) -> str:
    if config.get("signed_in") and config.get("user_email"):
        addr = config.get("receive_address", "")
        return f"signed in  ·  {config['user_email']}" + (f"  ·  {addr}" if addr else "")
    return "not signed in"
