"""
TMS Permission Management Routes
Handles submission creation, listing, deletion, retry, and queue display.
"""

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel
from typing import List
import logging

from ..services import supabase_service

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


# ==================== REQUEST MODELS ====================

class SubmissionCreate(BaseModel):
    submission_id: str
    usernames: List[str]
    ge_input: str


# ==================== SUBMISSION ENDPOINTS ====================

@router.post("/submissions")
def create_submission(payload: SubmissionCreate):
    try:
        created = supabase_service.create_submission_supabase(
            payload.submission_id, 
            payload.usernames, 
            payload.ge_input
        )
        return created
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/submissions")
def list_submissions(limit: int = 50):
    submissions = supabase_service.get_submissions_supabase(limit=limit)
    return {"success": True, "submissions": submissions}


@router.get("/submissions/{submission_id}")
def get_submission(submission_id: str):
    sub_list = supabase_service.get_submissions_supabase(limit=100)
    sub = next((item for item in sub_list if item.get("submission_id") == submission_id), None)
    if not sub:
        raise HTTPException(status_code=404, detail="Submission not found")
    return {"success": True, "submission": sub}


@router.delete("/submissions/{submission_id}")
def delete_submission(submission_id: str):
    ok = supabase_service.delete_submission_supabase(submission_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Submission not found or could not be deleted")
    return {"success": True}


@router.post("/submissions/{submission_id}/retry")
def retry_submission(submission_id: str, payload: dict = None):  # type: ignore
    """Retry a submission with only the error GE IDs and error usernames.
    
    If payload.errorGeIds and payload.errorUsernames are provided, create a new submission 
    with only those GE IDs and usernames that had errors.
    Otherwise, reset the original submission to pending (legacy behavior).
    """
    if payload and payload.get('errorGeIds') and payload.get('errorUsernames'):
        error_ge_ids = payload['errorGeIds']
        error_usernames = payload['errorUsernames']
        
        # Create new submission with only error GE IDs and error usernames
        new_ge_id_and_lang = '\n'.join(error_ge_ids)
        username_str = ','.join(error_usernames)
        
        created = supabase_service.create_retry_submission(username_str, new_ge_id_and_lang)
        if not created:
            raise HTTPException(status_code=500, detail="Failed to create retry submission")
        return {"success": True, "newSubmissionId": created.get("id")}
    else:
        # Legacy behavior: reset status to pending
        ok = supabase_service.update_submission_supabase(submission_id, status="pending")
        if not ok:
            raise HTTPException(status_code=404, detail="Submission not found or could not be updated")
        return {"success": True}


# ==================== DRIVER MANAGEMENT ====================

@router.post('/driver/close')
def close_driver(request: Request):
    """Close the global Selenium WebDriver if it's running.

    Security policy:
    - If environment variable DRIVER_ADMIN_TOKEN is set, require header X-Admin-Token matching it.
    - If DRIVER_ADMIN_TOKEN is not set, only allow requests from localhost (127.0.0.1 or ::1).
    """
    import os
    try:
        admin_token = os.environ.get('DRIVER_ADMIN_TOKEN')
        header_token = request.headers.get('x-admin-token')
        client_host = request.client.host if request.client else ''

        if admin_token:
            if not header_token or header_token != admin_token:
                raise HTTPException(status_code=401, detail='Invalid or missing admin token')
        else:
            # allow only requests originating from localhost when no token configured
            if client_host not in ('127.0.0.1', '::1', 'localhost'):
                raise HTTPException(status_code=403, detail='Driver close is restricted to localhost')

        # TMS permission automation is handled by TypeScript backend now
        # This endpoint is kept for backward compatibility but does nothing
        return {'success': True, 'message': 'Driver management moved to TypeScript backend'}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ==================== USERNAME MANAGEMENT ====================

@router.get('/usernames')
def get_usernames():
    usernames = supabase_service.get_userslist()
    return {"success": True, "usernames": usernames}


@router.get('/usernames/search')
def search_usernames(q: str = ""):
    """Search usernames by query string (case-insensitive, contains match)."""
    all_usernames = supabase_service.get_userslist()
    if not q:
        return {"success": True, "suggestions": all_usernames[:20]}
    
    q_lower = q.lower()
    suggestions = [u for u in all_usernames if q_lower in u.lower()]
    return {"success": True, "suggestions": suggestions[:20]}


@router.post('/usernames')
def add_username(payload: dict):
    new_username = payload.get('username') if isinstance(payload, dict) else None
    if not new_username:
        raise HTTPException(status_code=400, detail='username is required')
    return supabase_service.add_username(new_username)


@router.delete('/usernames')
def delete_username(payload: dict):
    username = payload.get('username') if isinstance(payload, dict) else None
    if not username:
        raise HTTPException(status_code=400, detail='username is required')
    return supabase_service.delete_username(username)


# ==================== QUEUE DISPLAY ====================

@router.get('/queue')
def get_queue(limit: int = 100, all: bool = False):
    """Return a flattened list of GE items built from pending submissions in Supabase.
    Each pending submission's `input.ge_input` (newline separated) is split into GE ID and lang
    and turned into an item consumable by the frontend `QueueStatus` component.
    """
    try:
        # By default include only pending and processing submissions so UI can show the single processing submission
        # If caller passes all=true, include completed and failed as well (useful when a single endpoint should provide history)
        all_subs = supabase_service.get_submissions_supabase(limit=1000) or []
        allowed = ('pending', 'processing') if not all else ('pending', 'processing', 'completed', 'failed')
        subs = [d for d in all_subs if str(d.get('status', '')).lower() in allowed]
        items = []
        for doc in subs:
            submission_id = doc.get('submission_id')
            usernames = doc.get('input', {}).get('usernames', []) if isinstance(doc.get('input'), dict) else []
            usernames_str = '\n'.join(usernames) if isinstance(usernames, list) else (usernames or '')
            ge_input = doc.get('input', {}).get('ge_input', '') if isinstance(doc.get('input'), dict) else ''
            # split lines and create items
            lines = [l.strip() for l in str(ge_input).splitlines() if l and l.strip()]
            for idx, line in enumerate(lines):
                parts = line.split()  # expect e.g. "1000 de" or "696 us"
                ge_id = parts[0] if len(parts) > 0 else line
                lang = parts[1] if len(parts) > 1 else ''
                key = f"{submission_id}:{idx}"
                raw_status = str(doc.get('status', 'pending')).lower()
                # map backend status to frontend status labels
                if raw_status == 'pending':
                    mapped_status = 'waiting'
                elif raw_status == 'processing':
                    mapped_status = 'processing'
                elif raw_status == 'completed':
                    # when requesting all, represent completed as done
                    mapped_status = 'done'
                elif raw_status == 'failed':
                    mapped_status = 'error'
                else:
                    mapped_status = raw_status
                items.append({
                    'key': key,
                    'id': str(ge_id),
                    'lang': str(lang),
                    'status': mapped_status,
                    'usernames': usernames_str,
                    'submission_id': submission_id
                })
        # respect limit on resulting GE items
        return {'success': True, 'queue': items[:limit]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
