"""History management service."""

import json
import os
from datetime import datetime
from pathlib import Path
from typing import List, Optional
from ..config import get_config_dir


def get_history_file() -> Path:
    """Get the history file path."""
    return get_config_dir() / "history.json"


def load_history() -> List[dict]:
    """Load history from file."""
    history_file = get_history_file()
    if not history_file.exists():
        return []

    try:
        with open(history_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    except (json.JSONDecodeError, Exception):
        return []


def save_history(history: List[dict]) -> None:
    """Save history to file."""
    history_file = get_history_file()
    with open(history_file, 'w', encoding='utf-8') as f:
        json.dump(history, f, indent=2, ensure_ascii=False)


def add_to_history(
    id: str,
    title: str,
    url: str,
    file_path: str,
    duration: Optional[str] = None,
    thumbnail: Optional[str] = None,
    initial_cost: Optional[dict] = None
) -> dict:
    """Add a new item to history."""
    history = load_history()

    item = {
        'id': id,
        'title': title,
        'url': url,
        'file_path': file_path,
        'created_at': datetime.now().isoformat(),
        'duration': duration,
        'thumbnail': thumbnail,
        'analysis': None,  # Will store analysis results
        'translations': {},  # Will store translations by language
        'qa_history': [],  # Q&A exchanges
        'resources': None,  # Saved resources/citations
        'costs': {
            'entries': [],
            'total_cost': 0.0
        }
    }

    # Add initial cost if provided (e.g., transcription cost)
    if initial_cost:
        item['costs']['entries'].append(initial_cost)
        item['costs']['total_cost'] = initial_cost.get('cost_usd', 0)

    # Add to beginning of list
    history.insert(0, item)

    # Keep only last 100 items
    history = history[:100]

    save_history(history)
    return item


def update_history_item(id: str, **kwargs) -> Optional[dict]:
    """Update a history item with new data."""
    history = load_history()

    for i, item in enumerate(history):
        if item.get('id') == id:
            item.update(kwargs)
            history[i] = item
            save_history(history)
            return item
    return None


def get_history(search: Optional[str] = None, limit: int = 50, offset: int = 0) -> tuple:
    """
    Get history items with optional search.
    Searches in title and transcription text content.

    Returns (items, total_count)
    """
    history = load_history()

    if search:
        search_lower = search.lower()
        filtered = []
        for item in history:
            # Search in title
            if search_lower in item.get('title', '').lower():
                filtered.append(item)
                continue
            # Search in transcription text
            file_path = item.get('file_path')
            if file_path:
                text = get_transcription_text(file_path)
                if text and search_lower in text.lower():
                    filtered.append(item)
        history = filtered

    total = len(history)
    items = history[offset:offset + limit]

    return items, total


def get_history_item(id: str) -> Optional[dict]:
    """Get a specific history item by ID."""
    history = load_history()
    for item in history:
        if item.get('id') == id:
            return item
    return None


def delete_history_item(id: str) -> bool:
    """Delete a history item by ID."""
    history = load_history()
    original_len = len(history)

    history = [item for item in history if item.get('id') != id]

    if len(history) < original_len:
        save_history(history)
        return True
    return False


def clear_history() -> None:
    """Clear all history."""
    save_history([])


def get_transcription_text(file_path: str) -> Optional[str]:
    """Read transcription text from file."""
    try:
        if os.path.exists(file_path):
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                # Skip header if present
                if content.startswith('Title:'):
                    lines = content.split('\n')
                    # Find the separator line and skip past it
                    for i, line in enumerate(lines):
                        if line.startswith('==='):
                            return '\n'.join(lines[i+2:]).strip()
                return content
    except Exception:
        pass
    return None


def add_cost_entry(item_id: str, cost_entry: dict) -> Optional[dict]:
    """
    Add a cost entry to an item and update total.

    Args:
        item_id: The history item ID
        cost_entry: Cost entry dict with operation, provider, model, cost_usd, timestamp

    Returns:
        Updated item or None if not found
    """
    history = load_history()

    for i, item in enumerate(history):
        if item.get('id') == item_id:
            # Ensure costs structure exists
            if 'costs' not in item:
                item['costs'] = {'entries': [], 'total_cost': 0.0}

            # Add entry
            item['costs']['entries'].append(cost_entry)
            item['costs']['total_cost'] += cost_entry.get('cost_usd', 0)
            item['costs']['total_cost'] = round(item['costs']['total_cost'], 6)

            history[i] = item
            save_history(history)
            return item

    return None


def add_qa_entry(item_id: str, question: str, answer: str, cost_info: dict = None, references: dict = None) -> Optional[dict]:
    """
    Add a Q&A exchange to an item's history.

    Args:
        item_id: The history item ID
        question: The question asked
        answer: The answer received
        cost_info: Optional cost info for this Q&A
        references: Optional references/citations

    Returns:
        Updated item or None if not found
    """
    history = load_history()

    for i, item in enumerate(history):
        if item.get('id') == item_id:
            # Ensure qa_history exists
            if 'qa_history' not in item:
                item['qa_history'] = []

            qa_entry = {
                'question': question,
                'answer': answer,
                'timestamp': datetime.now().isoformat()
            }

            if cost_info:
                qa_entry['cost_info'] = cost_info
            if references:
                qa_entry['references'] = references

            item['qa_history'].append(qa_entry)

            # Also add cost to costs if provided
            if cost_info:
                if 'costs' not in item:
                    item['costs'] = {'entries': [], 'total_cost': 0.0}
                cost_entry = {**cost_info, 'operation': 'qa'}
                item['costs']['entries'].append(cost_entry)
                item['costs']['total_cost'] += cost_entry.get('cost_usd', 0)
                item['costs']['total_cost'] = round(item['costs']['total_cost'], 6)

            history[i] = item
            save_history(history)
            return item

    return None


def save_resources(item_id: str, resources: dict, cost_info: dict = None) -> Optional[dict]:
    """
    Save resources/citations to an item.

    Args:
        item_id: The history item ID
        resources: Resources dict with answer, citations, etc.
        cost_info: Optional cost info for this request

    Returns:
        Updated item or None if not found
    """
    history = load_history()

    for i, item in enumerate(history):
        if item.get('id') == item_id:
            item['resources'] = resources

            # Add cost if provided
            if cost_info:
                if 'costs' not in item:
                    item['costs'] = {'entries': [], 'total_cost': 0.0}
                cost_entry = {**cost_info, 'operation': 'resources'}
                item['costs']['entries'].append(cost_entry)
                item['costs']['total_cost'] += cost_entry.get('cost_usd', 0)
                item['costs']['total_cost'] = round(item['costs']['total_cost'], 6)

            history[i] = item
            save_history(history)
            return item

    return None


def get_item_costs(item_id: str) -> dict:
    """Get all costs for an item."""
    item = get_history_item(item_id)
    if not item:
        return {'entries': [], 'total_cost': 0.0}
    return item.get('costs', {'entries': [], 'total_cost': 0.0})


def get_full_item(item_id: str) -> Optional[dict]:
    """
    Get complete item data including transcription text, all analysis, Q&A history, resources, and costs.

    Args:
        item_id: The history item ID

    Returns:
        Full item dict or None if not found
    """
    item = get_history_item(item_id)
    if not item:
        return None

    # Get transcription text
    text = get_transcription_text(item.get('file_path', ''))

    # Ensure all fields exist with defaults
    return {
        **item,
        'transcription': text,
        'qa_history': item.get('qa_history', []),
        'resources': item.get('resources'),
        'costs': item.get('costs', {'entries': [], 'total_cost': 0.0}),
        'analysis': item.get('analysis'),
        'translations': item.get('translations', {})
    }
