# app/api/v1/endpoints/messages.py
from typing import List
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks, UploadFile, File, Form
from sqlalchemy.orm import Session
from sqlalchemy import func, case
from app.api import deps
from app.schemas.message import MessageCreate, MessageResponse
from app.models.message import Message
from app.models.user import User
from app.services import message_service
from app.services.notification_service import create_chat_notification
from app.services.media_service import MediaService, Settings
from app.core.time import now
from app.core.firebase_config import initialize_firebase
import logging
import os
import uuid
from pathlib import Path

logger = logging.getLogger("adimsayar")

router = APIRouter()

# Define the upload path for chat images
CHAT_IMAGES_PATH = "chat_images"

# Initialize media service
settings = Settings()
media_service = MediaService(settings.STORAGE_BASE_PATH, settings.BASE_URL)

# Ensure the upload directory exists
os.makedirs(os.path.join(settings.STORAGE_BASE_PATH, CHAT_IMAGES_PATH), exist_ok=True)

@router.post("/", response_model=MessageResponse)
async def send_message(
    payload: MessageCreate,
    background_tasks: BackgroundTasks,
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    Allows the currently logged-in user to send a new message.
    The sender_id is derived from the authenticated user's ID,
    and the message is saved based on the receiver_id and content from the payload.
    """
    # Firebase 초기화 확인 (푸시 알림을 위해)
    initialize_firebase()
    
    message = await message_service.create_message(db, current_user.id, payload.receiver_id, payload.content)
    
    # 푸시 알림은 message_service 내에서 처리됨
    return message

@router.get("/", response_model=List[MessageResponse])
def get_messages(
    friend_id: int,
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    Retrieves the conversation history between the current user and a friend.
    """
    messages = message_service.get_messages_between_users(db, current_user.id, friend_id)
    if not messages:
        raise HTTPException(status_code=404, detail="No conversation found")
    return messages

@router.get("/unread", response_model=List[MessageResponse])
def get_unread_messages(
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    Retrieves all unread messages for the current logged-in user.
    """
    unread = message_service.get_unread_messages(db, receiver_id=current_user.id)
    return unread

@router.get("/threads", response_model=List[MessageResponse])
def get_conversation_threads(
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    로그인한 사용자가 참여하는 모든 대화 스레드를 조회합니다.
    각 스레드는 해당 대화 상대(친구)와의 최신 메시지를 포함합니다.
    """
    threads = message_service.get_conversation_threads(db, current_user.id)
    if not threads:
        raise HTTPException(status_code=404, detail="No conversations found.")
    return threads

@router.get("/conversation/{friend_id}", response_model=List[MessageResponse])
def get_conversation_with_user(
    friend_id: int,
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    Retrieves the full conversation history between the current user and the specified friend.
    """
    messages = message_service.get_messages_between_users(db, current_user.id, friend_id)
    if not messages:
        raise HTTPException(status_code=404, detail="No conversation found")
    return messages

@router.post("/read", response_model=List[MessageResponse])
def mark_messages_as_read_endpoint(
    sender_id: int,
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    POST /api/v1/messages/read

    현재 로그인한 사용자의, 특정 발신자(sender_id)로부터 온 메시지를 읽음 처리합니다.
    """
    updated_messages = message_service.mark_messages_as_read(db, receiver_id=current_user.id, sender_id=sender_id)
    return updated_messages

@router.post("/upload_image", response_model=MessageResponse)
async def upload_chat_image(
    receiver_id: int = Form(...),
    image: UploadFile = File(...),
    background_tasks: BackgroundTasks = BackgroundTasks(),
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    Upload an image and send it as a message to the specified receiver.
    The image is stored on the media server and the path is saved in the message content.
    """
    # Firebase 초기화 확인
    initialize_firebase()
    
    try:
        # Create a unique filename using UUID
        filename = f"{uuid.uuid4()}_{image.filename}"
        file_path = f"{CHAT_IMAGES_PATH}/{filename}"
        
        # Upload the image using MediaService
        image_url = media_service.upload_file(image, file_path)
        logger.info(f"Uploaded chat image to: {image_url}")
            
        # Create a formatted content string that indicates this is an image
        image_content = f"[IMAGE]:{image_url}"
        
        # Save the message with the image path
        message = await message_service.create_message(
            db=db,
            sender_id=current_user.id,
            receiver_id=receiver_id,
            content=image_content
        )
        
        return message
        
    except Exception as e:
        logger.error(f"Error uploading image: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to upload image: {str(e)}")

@router.post("/send", response_model=MessageResponse)
async def send_message_async(
    payload: MessageCreate,
    background_tasks: BackgroundTasks,
    db: Session = Depends(deps.get_db),
    current_user = Depends(deps.get_current_user)
):
    """
    비동기 메시지 전송 및 알림 처리용 엔드포인트
    Text messages only - for images, use /upload_image endpoint
    """
    try:
        # Firebase 초기화 확인 (푸시 알림을 위해)
        initialize_firebase()
        
        # 메시지 전송 및 알림 전송 처리는 create_message에서 함께 처리
        message = await message_service.create_message(
            db=db,
            sender_id=current_user.id,
            receiver_id=payload.receiver_id,
            content=payload.content
        )
        
        return message
    except Exception as e:
        logger.error(f"Error sending message: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to send message: {str(e)}")