from datetime import datetime, timezone
from typing import Optional

from fastapi import HTTPException
from sqlalchemy.orm import Session

from models import QuizRecord, Word, User

ACCUMULATION_BOOK_ID = 0


def utc_now_iso() -> str:
    return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


def calc_mastery_score(correct: int, wrong: int) -> int:
    total = correct + wrong
    if total == 0:
        return 0
    return round(correct / total * 100)


class WordService:
    def create_word(self, db: Session, user: User, data: dict) -> Word:
        book_id = data.get("book_id") or ACCUMULATION_BOOK_ID
        existing = (
            db.query(Word)
            .filter(
                Word.user_id == user.id,
                Word.book_id == book_id,
                Word.source_text == data["source_text"],
                Word.target_text == data["target_text"],
            )
            .first()
        )
        if existing:
            raise HTTPException(status_code=400, detail="该单词已存在")

        word = Word(
            user_id=user.id,
            book_id=book_id,
            book_entry_id=data.get("book_entry_id"),
            source_text=data["source_text"],
            target_text=data["target_text"],
            source_lang=data["source_lang"],
            target_lang=data["target_lang"],
            phonetic=data.get("phonetic"),
            example_en=data.get("example_en"),
            example_cn=data.get("example_cn"),
            status="new",
            correct_count=0,
            wrong_count=0,
            consecutive_correct_count=0,
            mastery_score=0,
            review_due_date=datetime.now(timezone.utc).strftime("%Y-%m-%d"),
            created_at=utc_now_iso(),
        )
        db.add(word)
        db.commit()
        db.refresh(word)
        return word

    def list_words(
        self,
        db: Session,
        user: User,
        status: Optional[str] = None,
        book_id: Optional[int] = None,
    ) -> list[Word]:
        q = db.query(Word).filter(Word.user_id == user.id)
        if book_id is None:
            q = q.filter(Word.book_id == ACCUMULATION_BOOK_ID)
        elif book_id > 0:
            q = q.filter(Word.book_id == book_id)
        if status:
            q = q.filter(Word.status == status)
        return q.order_by(Word.created_at.desc()).all()

    def get_word(self, db: Session, user: User, word_id: int) -> Word:
        word = db.query(Word).filter(Word.id == word_id, Word.user_id == user.id).first()
        if not word:
            raise HTTPException(status_code=404, detail="单词不存在")
        return word

    def delete_word(self, db: Session, user: User, word_id: int) -> None:
        word = self.get_word(db, user, word_id)
        db.query(QuizRecord).filter(QuizRecord.word_id == word.id).delete(
            synchronize_session=False
        )
        db.flush()
        db.delete(word)
        db.commit()

    def update_word(self, db: Session, user: User, word_id: int, data: dict) -> Word:
        word = self.get_word(db, user, word_id)
        if "status" in data and data["status"]:
            word.status = data["status"]
        db.commit()
        db.refresh(word)
        return word


word_service = WordService()
