"""
Confirm Card Repository

确认卡片持久化仓储 - JSON文件存储
"""
from pathlib import Path
from typing import List, Optional
import json
import uuid
from datetime import datetime

from app.models.confirm_card import (
    ConfirmCard, ConfirmCardStatus, ConfirmCardOption
)
from app.utils.logger import get_logger

logger = get_logger(__name__)

# 数据文件路径
DATA_DIR = Path(__file__).parent.parent.parent / "data"
CONFIRM_CARDS_FILE = DATA_DIR / "confirm_cards.json"


class ConfirmCardRepository:
    """确认卡片仓储"""

    def __init__(self):
        self.file_path = CONFIRM_CARDS_FILE
        self._cards: Dict[str, ConfirmCard] = {}
        self._ensure_data_dir()
        self._load()

    def _ensure_data_dir(self):
        """确保数据目录存在"""
        self.file_path.parent.mkdir(parents=True, exist_ok=True)

    def _load(self):
        """从文件加载"""
        if self.file_path.exists():
            try:
                content = self.file_path.read_text(encoding="utf-8")
                if content.strip():
                    data = json.loads(content)
                    for card_id, card_data in data.items():
                        # 转换选项列表
                        if "options" in card_data and isinstance(card_data["options"], list):
                            card_data["options"] = [
                                ConfirmCardOption(**opt) for opt in card_data["options"]
                            ]
                        # 确保datetime正确转换
                        if isinstance(card_data.get("created_at"), str):
                            card_data["created_at"] = datetime.fromisoformat(
                                card_data["created_at"].replace('Z', '+00:00')
                            )
                        if isinstance(card_data.get("confirmed_at"), str):
                            card_data["confirmed_at"] = datetime.fromisoformat(
                                card_data["confirmed_at"].replace('Z', '+00:00')
                            )
                        if isinstance(card_data.get("expires_at"), str):
                            card_data["expires_at"] = datetime.fromisoformat(
                                card_data["expires_at"].replace('Z', '+00:00')
                            )
                        self._cards[card_id] = ConfirmCard(**card_data)
            except Exception as e:
                logger.error(f"加载确认卡片失败: {e}")

    def _save(self):
        """保存到文件"""
        try:
            data = {}
            for card_id, card in self._cards.items():
                card_dict = card.dict()
                # 确保datetime正确序列化
                if isinstance(card_dict.get("created_at"), datetime):
                    card_dict["created_at"] = card_dict["created_at"].isoformat()
                if isinstance(card_dict.get("confirmed_at"), datetime):
                    card_dict["confirmed_at"] = card_dict["confirmed_at"].isoformat()
                if isinstance(card_dict.get("expires_at"), datetime):
                    card_dict["expires_at"] = card_dict["expires_at"].isoformat()
                data[card_id] = card_dict

            self.file_path.write_text(
                json.dumps(data, ensure_ascii=False, indent=2),
                encoding="utf-8"
            )
        except Exception as e:
            logger.error(f"保存确认卡片失败: {e}")
            raise

    async def create(self, card: ConfirmCard) -> ConfirmCard:
        """创建确认卡片"""
        if not card.id:
            card.id = str(uuid.uuid4())

        self._cards[card.id] = card
        self._save()
        logger.info(f"创建确认卡片: {card.id}")
        return card

    async def get(self, card_id: str) -> Optional[ConfirmCard]:
        """获取单个卡片"""
        return self._cards.get(card_id)

    async def list_by_project(
        self,
        project_id: str,
        status: Optional[ConfirmCardStatus] = None,
        include_expired: bool = False
    ) -> List[ConfirmCard]:
        """列出项目的确认卡片"""
        cards = [
            card for card in self._cards.values()
            if card.project_id == project_id
        ]

        if status:
            cards = [c for c in cards if c.status == status]

        if not include_expired:
            now = datetime.now()
            cards = [c for c in cards if not c.expires_at or c.expires_at > now]

        # 按创建时间倒序
        cards = sorted(cards, key=lambda c: c.created_at, reverse=True)
        return cards

    async def update_status(
        self,
        card_id: str,
        status: ConfirmCardStatus,
        selected_option_id: Optional[str] = None,
        custom_response: Optional[str] = None,
        user_notes: Optional[str] = None
    ) -> Optional[ConfirmCard]:
        """更新确认卡片状态"""
        card = self._cards.get(card_id)
        if not card:
            return None

        card.status = status
        card.selected_option_id = selected_option_id
        card.custom_response = custom_response
        card.user_notes = user_notes
        card.confirmed_at = datetime.now()

        self._cards[card_id] = card
        self._save()

        logger.info(f"更新确认卡片状态: {card_id} -> {status}")
        return card

    async def delete(self, card_id: str) -> bool:
        """删除确认卡片"""
        if card_id in self._cards:
            del self._cards[card_id]
            self._save()
            return True
        return False

    async def cleanup_expired(self) -> int:
        """清理过期的确认卡片"""
        now = datetime.now()
        expired_ids = [
            card_id for card_id, card in self._cards.items()
            if card.expires_at and card.expires_at < now
        ]

        for card_id in expired_ids:
            self._cards[card_id].status = ConfirmCardStatus.EXPIRED

        if expired_ids:
            self._save()
            logger.info(f"标记 {len(expired_ids)} 个确认卡片为过期")

        return len(expired_ids)


# 全局单例
_confirm_card_repo = None


def get_confirm_card_repo() -> ConfirmCardRepository:
    """获取确认卡片仓储单例"""
    global _confirm_card_repo
    if _confirm_card_repo is None:
        _confirm_card_repo = ConfirmCardRepository()
    return _confirm_card_repo


# 导入Dict类型
from typing import Dict
