"""
간단한 Todo API 라우터
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from typing import List, Optional
from uuid import UUID
import logging
from datetime import datetime

from ...core.database import get_db
from ...models.user import User
from ...models.todo import Todo, TodoStatus
from ...schemas.todo import TodoCreate, TodoUpdate, TodoResponse
from ..dependencies import get_current_active_user

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/todos", tags=["todos"])


# ============================================================================
# Todo CRUD API
# ============================================================================

@router.post("/", response_model=TodoResponse)
async def create_todo(
    todo_data: TodoCreate,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """새 Todo 생성"""
    try:
        logger.info(f"Todo 생성 요청 - 사용자: {current_user.username}")
        logger.info(f"요청 데이터: {todo_data.dict()}")
        
        # 날짜 문자열 파싱 (한국 시간 형식)
        parsed_due_date = None
        if todo_data.due_date:
            try:
                # "2025-09-22T00:00:00+09:00" 형식 파싱
                parsed_due_date = datetime.fromisoformat(todo_data.due_date)
                logger.info(f"파싱된 날짜: {parsed_due_date}")
            except ValueError:
                logger.warning(f"Invalid date format: {todo_data.due_date}")
        
        # 이미지 URLs JSON 변환
        import json
        image_urls_json = None
        if todo_data.image_urls:
            image_urls_json = json.dumps(todo_data.image_urls)
        
        # 새 Todo 생성
        new_todo = Todo(
            user_id=current_user.id,
            title=todo_data.title,
            description=todo_data.description,
            category=todo_data.category,
            due_date=parsed_due_date,
            image_urls=image_urls_json,
            tags=todo_data.tags
        )
        
        db.add(new_todo)
        await db.commit()
        await db.refresh(new_todo)
        
        # 응답용 데이터 변환
        import json
        image_urls_list = None
        if new_todo.image_urls:
            try:
                image_urls_list = json.loads(new_todo.image_urls)
            except json.JSONDecodeError:
                image_urls_list = None
        
        response_data = {
            "id": new_todo.id,
            "user_id": new_todo.user_id,
            "title": new_todo.title,
            "description": new_todo.description,
            "category": new_todo.category,
            "status": new_todo.status,
            "created_at": new_todo.created_at,
            "updated_at": new_todo.updated_at,
            "due_date": new_todo.due_date.isoformat() if new_todo.due_date else None,
            "completed_at": new_todo.completed_at,
            "image_urls": image_urls_list,
            "tags": new_todo.tags
        }
        
        return response_data
        
    except Exception as e:
        await db.rollback()
        logger.error(f"Todo 생성 실패: {e}")
        logger.error(f"오류 타입: {type(e).__name__}")
        logger.error(f"오류 상세: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Todo 생성에 실패했습니다: {str(e)}"
        )


@router.get("/", response_model=List[TodoResponse])
async def get_todos(
    status: Optional[str] = Query(None, description="상태 필터 (pending, in_progress, completed)"),
    category: Optional[str] = Query(None, description="카테고리 필터 (todo, calendar, checklist)"),
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """Todo 목록 조회"""
    try:
        # 기본 쿼리
        query = select(Todo).where(Todo.user_id == current_user.id)
        
        # 필터 적용
        if status:
            query = query.where(Todo.status == status)
        if category:
            query = query.where(Todo.category == category)
            
        # 정렬 (생성일 역순)
        query = query.order_by(Todo.created_at.desc())
        
        result = await db.execute(query)
        todos = result.scalars().all()
        
        # 응답용 데이터 변환
        import json
        response_data = []
        for todo in todos:
            image_urls_list = None
            if todo.image_urls:
                try:
                    image_urls_list = json.loads(todo.image_urls)
                except json.JSONDecodeError:
                    image_urls_list = None
            
            response_data.append({
                "id": todo.id,
                "user_id": todo.user_id,
                "title": todo.title,
                "description": todo.description,
                "category": todo.category,
                "status": todo.status,
                "created_at": todo.created_at,
                "updated_at": todo.updated_at,
                "due_date": todo.due_date.isoformat() if todo.due_date else None,
                "completed_at": todo.completed_at,
                "image_urls": image_urls_list,
                "tags": todo.tags
            })
        
        return response_data
        
    except Exception as e:
        logger.error(f"Todo 목록 조회 실패: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Todo 목록 조회에 실패했습니다."
        )


@router.get("/{todo_id}", response_model=TodoResponse)
async def get_todo(
    todo_id: UUID,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """특정 Todo 조회"""
    try:
        result = await db.execute(
            select(Todo).where(
                and_(Todo.id == todo_id, Todo.user_id == current_user.id)
            )
        )
        todo = result.scalar_one_or_none()
        
        if not todo:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Todo를 찾을 수 없습니다."
            )
        
        # 응답용 데이터 변환
        import json
        image_urls_list = None
        if todo.image_urls:
            try:
                image_urls_list = json.loads(todo.image_urls)
            except json.JSONDecodeError:
                image_urls_list = None
        
        response_data = {
            "id": todo.id,
            "user_id": todo.user_id,
            "title": todo.title,
            "description": todo.description,
            "category": todo.category,
            "status": todo.status,
            "created_at": todo.created_at,
            "updated_at": todo.updated_at,
            "due_date": todo.due_date.isoformat() if todo.due_date else None,
            "completed_at": todo.completed_at,
            "image_urls": image_urls_list,
            "tags": todo.tags,
        }
            
        return response_data
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Todo 조회 실패: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Todo 조회에 실패했습니다."
        )


@router.put("/{todo_id}", response_model=TodoResponse)
async def update_todo(
    todo_id: UUID,
    todo_data: TodoUpdate,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """Todo 수정"""
    try:
        # Todo 조회
        result = await db.execute(
            select(Todo).where(
                and_(Todo.id == todo_id, Todo.user_id == current_user.id)
            )
        )
        todo = result.scalar_one_or_none()
        
        if not todo:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Todo를 찾을 수 없습니다."
            )
        
        # 업데이트할 필드만 수정
        import json
        update_data = todo_data.dict(exclude_unset=True)
        for field, value in update_data.items():
            if field == 'due_date' and value:
                # 날짜 문자열 파싱 (한국 시간 형식)
                try:
                    parsed_date = datetime.fromisoformat(value)
                    setattr(todo, field, parsed_date)
                except ValueError:
                    logger.warning(f"Invalid date format: {value}")
            elif field == 'image_urls' and value is not None:
                # 이미지 URLs를 JSON으로 변환
                setattr(todo, field, json.dumps(value))
            else:
                setattr(todo, field, value)
        
        # 완료 상태 변경 시 완료 시간 설정
        if todo_data.status == TodoStatus.COMPLETED and todo.completed_at is None:
            todo.completed_at = datetime.utcnow()
        elif todo_data.status != TodoStatus.COMPLETED:
            todo.completed_at = None
            
        await db.commit()
        await db.refresh(todo)
        
        # 응답용 데이터 변환
        image_urls_list = None
        if todo.image_urls:
            try:
                image_urls_list = json.loads(todo.image_urls)
            except json.JSONDecodeError:
                image_urls_list = None
        
        response_data = {
            "id": todo.id,
            "user_id": todo.user_id,
            "title": todo.title,
            "description": todo.description,
            "category": todo.category,
            "status": todo.status,
            "created_at": todo.created_at,
            "updated_at": todo.updated_at,
            "due_date": todo.due_date.isoformat() if todo.due_date else None,
            "completed_at": todo.completed_at,
            "image_urls": image_urls_list,
            "tags": todo.tags,
        }
        
        return response_data
        
    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        logger.error(f"Todo 수정 실패: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Todo 수정에 실패했습니다."
        )


@router.delete("/{todo_id}")
async def delete_todo(
    todo_id: UUID,
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """Todo 삭제"""
    try:
        # Todo 조회
        result = await db.execute(
            select(Todo).where(
                and_(Todo.id == todo_id, Todo.user_id == current_user.id)
            )
        )
        todo = result.scalar_one_or_none()
        
        if not todo:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Todo를 찾을 수 없습니다."
            )
        
        await db.delete(todo)
        await db.commit()
        
        return {"message": "Todo가 삭제되었습니다."}
        
    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        logger.error(f"Todo 삭제 실패: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Todo 삭제에 실패했습니다."
        )


@router.post("/{todo_id}/add-image")
async def add_image_to_todo(
    todo_id: UUID,
    image: UploadFile = File(...),
    current_user: User = Depends(get_current_active_user),
    db: AsyncSession = Depends(get_db)
):
    """기존 Todo에 이미지 추가 (최대 5개까지)"""
    try:
        # Todo 조회
        result = await db.execute(
            select(Todo).where(
                and_(Todo.id == todo_id, Todo.user_id == current_user.id)
            )
        )
        todo = result.scalar_one_or_none()
        
        if not todo:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Todo를 찾을 수 없습니다."
            )
        
        # 현재 이미지 개수 확인
        import json
        current_images = []
        if todo.image_urls:
            try:
                current_images = json.loads(todo.image_urls)
            except json.JSONDecodeError:
                current_images = []
        
        # 최대 5개 제한 확인
        if len(current_images) >= 5:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="최대 5개의 이미지만 저장할 수 있습니다."
            )
        
        # 파일 형식 확인
        if not image.content_type.startswith('image/'):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="이미지 파일만 업로드 가능합니다."
            )
        
        # 파일 크기 확인 (5MB 제한)
        contents = await image.read()
        if len(contents) > 5 * 1024 * 1024:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="파일 크기는 5MB를 초과할 수 없습니다."
            )
        
        # Base64로 변환하여 저장
        import base64
        base64_string = f"data:{image.content_type};base64,{base64.b64encode(contents).decode()}"
        
        # 파일 저장
        from ...services.file_service import save_base64_image
        file_url = save_base64_image(base64_string)
        if not file_url:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="이미지 저장에 실패했습니다."
            )
        
        # 기존 이미지 목록에 새 이미지 추가
        current_images.append(file_url)
        todo.image_urls = json.dumps(current_images)
        
        await db.commit()
        await db.refresh(todo)
        
        return {
            "message": "이미지가 추가되었습니다.",
            "url": file_url,
            "total_images": len(current_images),
            "max_images": 5
        }
        
    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        logger.error(f"이미지 추가 실패: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="이미지 추가에 실패했습니다."
        )

