from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from utils.get_db import get_db
from models import Project
from schema.project_schema import ProjectCreateRequestSchema, ProjectUpdateRequestSchema
from utils.logging import logger 
from uuid import UUID
from utils.pagination import get_paginated_response
from typing import Optional
from models.project_model import ProjectStatus

def all_projects_of_org(request:Request,db: Session, page: int = 1, page_size: int = 10, search: str = None, sort_by: str = "created_at", sort_order: str = "desc", status:ProjectStatus = 'ACTIVE'):
    user = request.state.user

    if user.platform_role == 'SUPER_ADMIN':
        projects = db.query(Project)
        paginated_response=get_paginated_response(query=projects,request=request, page=page, limit=page_size)
        return paginated_response
    
    if not user.org_id or user.org_role not in ['ORG_ADMIN', 'MANAGER', 'MEMBER']:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User does not belong to any organization")
    
    projects = db.query(Project).filter(Project.org_id == user.org_id)
    if status:
        projects = projects.filter(Project.status == status)
    if search:
        projects = projects.filter(Project.name.ilike(f"%{search}%"))
    if sort_by in ['name', 'created_at']:
        sort_column = getattr(Project, sort_by)
        if sort_order == 'desc':
            sort_column = sort_column.desc()
        projects = projects.order_by(sort_column)
    paginated_response=get_paginated_response(query=projects,request=request, page=page, limit=page_size)
    return paginated_response

def create_project_for_org(request:Request,payload:ProjectCreateRequestSchema,db: Session):
    try:
        user = request.state.user
        logger.info(f"Creating project with name: {payload.name} for organization ID: {user.org_id} by user ID: {user.id}")

        if not user.org_id or user.org_role not in ['ORG_ADMIN', 'MANAGER']:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only organization admins and managers can create projects")
        
        new_project = Project(
            name=payload.name,
            description=payload.description,
            org_id=user.org_id,
            created_by=user.id,
            project_key=f"{payload.name[:3].upper()}-{user.org_id.hex[:6].upper()}"
        )

        db.add(new_project)
        db.commit()
        db.refresh(new_project)

        return {
            "id": new_project.id,
            "name": new_project.name,
            "description": new_project.description,
            "org_id": new_project.org_id,
            "created_by": new_project.created_by,
            "project_key": new_project.project_key,
            "message": "Project created successfully"
        }
    except HTTPException as e:
        raise e
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
    
def update_project_for_org(project_id:UUID,request:Request,payload:ProjectUpdateRequestSchema,db: Session):
    try:
        user = request.state.user
        logger.info(f"Updating project with ID: {project_id} for organization ID: {user.org_id} by user ID: {user.id}")

        if not user.org_id or user.org_role not in ['ORG_ADMIN', 'MANAGER']:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only organization admins and managers can update projects")
        
        project = db.query(Project).filter(Project.id == project_id, Project.org_id == user.org_id).first()
        if not project:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")

        project.name = payload.name
        project.description = payload.description
        project.status = payload.status
        db.commit()
        db.refresh(project)

        return {
            "id": project.id,
            "name": project.name,
            "description": project.description,
            "org_id": project.org_id,
            "created_by": project.created_by,
            "project_key": project.project_key,
            "message": "Project updated successfully"
        }
    except HTTPException as e:
        raise e
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
    
def delete_project_for_org(project_id:UUID,request:Request,db: Session):
    try:
        user = request.state.user
        logger.info(f"Deleting project with ID: {project_id} for organization ID: {user.org_id} by user ID: {user.id}")

        if not user.org_id or user.org_role not in ['ORG_ADMIN', 'MANAGER']:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only organization admins and managers can delete projects")
        
        project = db.query(Project).filter(Project.id == project_id, Project.org_id == user.org_id).first()
        if not project:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")

        project_details = {
            "id": project.id,
            "name": project.name,
            "description": project.description,
            "org_id": project.org_id,
            "created_by": project.created_by,
            "project_key": project.project_key,
            "message": "Project deleted successfully"
        }

        db.delete(project)
        db.commit()

        return project_details
    except HTTPException as e:
        raise e
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))


def get_project_by_id(project_id: UUID, request: Request, db: Session):
    try:
        user = request.state.user
        logger.info(f"Fetching project with ID: {project_id} for organization ID: {user.org_id}")

        if not user.org_id or user.org_role not in ['ORG_ADMIN', 'MANAGER', 'MEMBER']:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User does not belong to any organization")

        project = db.query(Project).filter(Project.id == project_id, Project.org_id == user.org_id).first()
        if not project:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found")

        return project
    except HTTPException as e:
        raise e
    except Exception as e:
        logger.error(f"Error fetching project {project_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))