from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
import os
import uuid
from pathlib import Path
from PIL import Image
from config.database import get_db
from config.settings import settings
from models.ticket import Ticket, TicketType, TicketStatus, TicketPriority
from models.user import User
from schemas.ticket import TicketCreate, TicketUpdate, TicketResponse, TicketAdminUpdate
from utils.security import get_current_active_user, get_admin_user

router = APIRouter()

@router.get("/", response_model=List[TicketResponse])
async def get_user_tickets(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Get current user's tickets."""
    tickets = db.query(Ticket).filter(Ticket.user_id == current_user.id).order_by(Ticket.created_at.desc()).all()
    return [format_ticket_response(ticket, db) for ticket in tickets]

@router.get("/admin", response_model=List[TicketResponse])
async def get_all_tickets_admin(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user),
    status_filter: Optional[TicketStatus] = None,
    type_filter: Optional[TicketType] = None,
    priority_filter: Optional[TicketPriority] = None
):
    """Get all tickets (admin only)."""
    query = db.query(Ticket)
    
    if status_filter:
        query = query.filter(Ticket.status == status_filter)
    if type_filter:
        query = query.filter(Ticket.ticket_type == type_filter)
    if priority_filter:
        query = query.filter(Ticket.priority == priority_filter)
    
    tickets = query.order_by(Ticket.created_at.desc()).all()
    return [format_ticket_response(ticket, db) for ticket in tickets]

@router.get("/{ticket_id}", response_model=TicketResponse)
async def get_ticket(
    ticket_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Get a specific ticket."""
    ticket = db.query(Ticket).filter(Ticket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Ticket not found"
        )
    
    # Users can only see their own tickets, admins can see all
    if ticket.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to view this ticket"
        )
    
    return format_ticket_response(ticket, db)

@router.post("/", response_model=TicketResponse)
async def create_ticket(
    title: str = Form(...),
    description: str = Form(...),
    ticket_type: str = Form("other"),  # Changed from TicketType to str
    priority: str = Form("medium"),    # Changed from TicketPriority to str
    screenshot: Optional[UploadFile] = File(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Create a new ticket."""
    print(f"DEBUG - Received ticket data: title='{title}', description='{description}', ticket_type='{ticket_type}', priority='{priority}'")
    
    # Validate and convert ticket_type
    try:
        ticket_type_enum = TicketType(ticket_type)
        print(f"DEBUG - Ticket type converted successfully: {ticket_type_enum}")
    except ValueError as e:
        print(f"DEBUG - Error converting ticket_type '{ticket_type}': {e}")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Invalid ticket type: {ticket_type}. Valid types: {[t.value for t in TicketType]}"
        )
    
    # Validate and convert priority
    try:
        priority_enum = TicketPriority(priority)
        print(f"DEBUG - Priority converted successfully: {priority_enum}")
    except ValueError as e:
        print(f"DEBUG - Error converting priority '{priority}': {e}")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Invalid priority: {priority}. Valid priorities: {[p.value for p in TicketPriority]}"
        )
    
    print("DEBUG - Starting ticket creation...")
    
    # Create tickets directory
    tickets_dir = Path(settings.UPLOAD_PATH) / "tickets" / str(current_user.id)
    tickets_dir.mkdir(parents=True, exist_ok=True)
    print(f"DEBUG - Created tickets directory: {tickets_dir}")
    
    screenshot_path = None
    if screenshot:
        print(f"DEBUG - Processing screenshot: {screenshot.filename}, content_type: {screenshot.content_type}")
        # Validate file type
        if not screenshot.content_type.startswith('image/'):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Screenshot must be an image file"
            )
        
        # Generate unique filename
        file_extension = screenshot.filename.split(".")[-1]
        filename = f"ticket_{uuid.uuid4()}.{file_extension}"
        file_path = tickets_dir / filename
        
        # Save and optimize image
        contents = await screenshot.read()
        with open(file_path, "wb") as f:
            f.write(contents)
        
        # Optimize image
        try:
            img = Image.open(file_path)
            if img.size[0] > 1920 or img.size[1] > 1080:
                img.thumbnail((1920, 1080), Image.Resampling.LANCZOS)
                img.save(file_path, quality=85, optimize=True)
        except Exception as e:
            print(f"Error optimizing screenshot: {e}")
        
        screenshot_path = f"/tickets/{current_user.id}/{filename}"
        print(f"DEBUG - Screenshot saved: {screenshot_path}")
    
    print("DEBUG - Creating ticket object...")
    ticket = Ticket(
        title=title,
        description=description,
        ticket_type=ticket_type_enum,
        priority=priority_enum,
        user_id=current_user.id,
        screenshot_path=screenshot_path
    )
    
    print("DEBUG - Adding ticket to database...")
    db.add(ticket)
    db.commit()
    db.refresh(ticket)
    print(f"DEBUG - Ticket created successfully with ID: {ticket.id}")
    
    return format_ticket_response(ticket, db)

@router.put("/{ticket_id}", response_model=TicketResponse)
async def update_ticket(
    ticket_id: int,
    ticket_update: TicketUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Update a ticket."""
    ticket = db.query(Ticket).filter(Ticket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Ticket not found"
        )
    
    # Users can only update their own tickets, admins can update all
    if ticket.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to update this ticket"
        )
    
    # Regular users can only update title, description, and type
    if not current_user.is_admin:
        update_data = ticket_update.dict(exclude_unset=True)
        allowed_fields = ['title', 'description', 'ticket_type']
        update_data = {k: v for k, v in update_data.items() if k in allowed_fields}
    else:
        update_data = ticket_update.dict(exclude_unset=True)
        
        # Update resolved_at if status is resolved
        if 'status' in update_data and update_data['status'] == TicketStatus.RESOLVED:
            update_data['resolved_at'] = datetime.utcnow()
    
    for field, value in update_data.items():
        setattr(ticket, field, value)
    
    ticket.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(ticket)
    
    return format_ticket_response(ticket, db)

@router.put("/{ticket_id}/admin", response_model=TicketResponse)
async def update_ticket_admin(
    ticket_id: int,
    ticket_update: TicketAdminUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """Update a ticket as admin."""
    ticket = db.query(Ticket).filter(Ticket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Ticket not found"
        )
    
    update_data = ticket_update.dict(exclude_unset=True)
    
    # Update resolved_at if status is resolved
    if 'status' in update_data and update_data['status'] == TicketStatus.RESOLVED:
        update_data['resolved_at'] = datetime.utcnow()
    
    for field, value in update_data.items():
        setattr(ticket, field, value)
    
    ticket.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(ticket)
    
    return format_ticket_response(ticket, db)

@router.delete("/{ticket_id}")
async def delete_ticket(
    ticket_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """Delete a ticket."""
    ticket = db.query(Ticket).filter(Ticket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Ticket not found"
        )
    
    # Users can only delete their own tickets, admins can delete all
    if ticket.user_id != current_user.id and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to delete this ticket"
        )
    
    # Delete screenshot if exists
    if ticket.screenshot_path:
        try:
            screenshot_file = settings.UPLOAD_PATH + ticket.screenshot_path
            if os.path.exists(screenshot_file):
                os.remove(screenshot_file)
        except Exception as e:
            print(f"Error deleting screenshot: {e}")
    
    db.delete(ticket)
    db.commit()
    
    return {"message": "Ticket deleted successfully"}

def format_ticket_response(ticket: Ticket, db: Session) -> dict:
    """Format ticket response with user information."""
    user = db.query(User).filter(User.id == ticket.user_id).first()
    assigned_admin = None
    if ticket.assigned_to:
        assigned_admin = db.query(User).filter(User.id == ticket.assigned_to).first()
    
    return {
        "id": ticket.id,
        "title": ticket.title,
        "description": ticket.description,
        "ticket_type": ticket.ticket_type,
        "status": ticket.status,
        "priority": ticket.priority,
        "user_id": ticket.user_id,
        "assigned_to": ticket.assigned_to,
        "screenshot_path": ticket.screenshot_path,
        "admin_notes": ticket.admin_notes,
        "created_at": ticket.created_at,
        "updated_at": ticket.updated_at,
        "resolved_at": ticket.resolved_at,
        "user_name": user.full_name if user else "Unknown",
        "user_email": user.email if user else "Unknown",
        "assigned_admin_name": assigned_admin.full_name if assigned_admin else None
    }
