import os
import logging
from fastapi import FastAPI, Request, BackgroundTasks
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

from src.utils.bitbucket_client import BitbucketClient
from src.utils.ai_reviewer import AIReviewer
from src.utils.email_notifier import EmailNotifier

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI(title="AI Code Review Service")

class ReviewRequest(BaseModel):
    url: str

@app.get("/")
async def root():
    return {"message": "AI Code Review Service is running"}

@app.post("/webhook/bitbucket")
async def bitbucket_webhook(request: Request, background_tasks: BackgroundTasks):
    """
    Handle Bitbucket Webhooks for Pull Requests.
    """
    try:
        payload = await request.json()
        event_key = request.headers.get("X-Event-Key")
        
        logger.info(f"Received Bitbucket event: {event_key}")
        
        # We only care about PR created or updated
        if event_key in ["pullrequest:created", "pullrequest:updated"]:
            background_tasks.add_task(process_pull_request, payload)
            return JSONResponse({"message": "Review task scheduled"}, status_code=202)
        
        return JSONResponse({"message": "Event ignored"}, status_code=200)
    
    except Exception as e:
        logger.error(f"Error processing webhook: {str(e)}")
        return JSONResponse({"error": "Internal Server Error"}, status_code=500)

@app.post("/api/v0/review")
async def manual_review_api(request: ReviewRequest):
    """
    Directly review a Bitbucket PR diff from a given URL.
    Returns the AI summary in the response.
    """
    try:
        pr_url = request.url
        
        logger.info(f"Received manual review request for URL: {pr_url}")

        bb_client = BitbucketClient()
        ai_reviewer = AIReviewer()

        # 1. Parse URL
        params = bb_client.parse_url(pr_url)
        workspace = params['workspace']
        repo_slug = params['repo_slug']
        pr_id = params['pr_id']

        # 2. Fetch Diff
        diff_content = bb_client.get_diff(workspace, repo_slug, pr_id)
        
        # 3. AI Review
        review_summary = ai_reviewer.review_diff(diff_content)
        
        return JSONResponse({
            "status": "success",
            "workspace": workspace,
            "repository": repo_slug,
            "pr_id": pr_id,
            "review_summary": review_summary
        })

    except Exception as e:
        logger.error(f"Error in manual review API: {str(e)}")
        return JSONResponse({"error": str(e)}, status_code=500)

async def process_pull_request(payload: dict):
    """
    Core logic to fetch diff, review it, and notify.
    """
    try:
        repo_full_name = payload['repository']['full_name']
        workspace, repo_slug = repo_full_name.split('/', 1)
        pr_id = payload['pullrequest']['id']
        pr_title = payload['pullrequest']['title']
        
        logger.info(f"Processing review for PR #{pr_id} in {workspace}/{repo_slug}")

        bb_client = BitbucketClient()
        ai_reviewer = AIReviewer()
        notifier = EmailNotifier()

        # 1. Fetch Diff
        diff_content = bb_client.get_diff(workspace, repo_slug, pr_id)
        
        # 2. Fetch PR Details (to get author email)
        pr_details = bb_client.get_pr_details(workspace, repo_slug, pr_id)
        # Author email is often not available directly in the 2.0 API unless they have public email.
        # We might need to use a fallback or specific logic if provided by user.
        # For now, let's try to find it or use a placeholder.
        author_email = pr_details.get('author', {}).get('email') or os.getenv("FALLBACK_RECIPIENT")
        
        if not author_email:
            logger.warning(f"Could not find author email for PR #{pr_id}. Using fallback.")
        
        # 3. AI Review
        review_summary = ai_reviewer.review_diff(diff_content)
        
        # 4. Notify
        notifier.notify_review(author_email, review_summary, pr_title)
        
        logger.info(f"Completed review for PR #{pr_id}")

    except Exception as e:
        logger.error(f"Failed to process PR review: {str(e)}")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("app:app", host="127.0.0.1", port=5008, reload=True)
