
"""API endpoints for managing workflow sources."""

from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
import httpx

from ...core.database.session import get_session
from ...core.workflows.source import WorkflowSource
from ...core.schemas.source import (
    WorkflowSourceCreate,
    WorkflowSourceUpdate,
    WorkflowSourceResponse
)

router = APIRouter(prefix="/sources", tags=["sources"])

async def _validate_source(url: str, api_key: str) -> dict:
    """Validate a source by fetching its version info."""
    try:
        async with httpx.AsyncClient(verify=False) as client:
            headers = {"accept": "application/json"}
            if api_key:
                headers["x-api-key"] = api_key
            response = await client.get(f"{url}/api/v1/version", headers=headers)
            response.raise_for_status()
            return response.json()
    except Exception as e:
        raise HTTPException(
            status_code=400,
            detail=f"Failed to validate source: {str(e)}"
        )

@router.post("/", response_model=WorkflowSourceResponse)
async def create_source(
    source: WorkflowSourceCreate,
    session: AsyncSession = Depends(get_session)
) -> WorkflowSourceResponse:
    """Create a new workflow source."""
    # Check if source with URL already exists
    result = await session.execute(
        select(WorkflowSource).where(WorkflowSource.url == source.url)
    )
    if result.scalar_one_or_none():
        raise HTTPException(
            status_code=400,
            detail=f"Source with URL {source.url} already exists"
        )
    
    # Validate source and get version info
    version_info = await _validate_source(source.url, source.api_key)
    
    # Create source
    db_source = WorkflowSource(
        source_type=source.source_type,
        url=source.url,
        encrypted_api_key=WorkflowSource.encrypt_api_key(source.api_key),
        version_info=version_info,
        status=source.status or "active"
    )
    session.add(db_source)
    await session.commit()
    await session.refresh(db_source)
    
    return WorkflowSourceResponse.from_orm(db_source)

@router.get("/", response_model=List[WorkflowSourceResponse])
async def list_sources(
    status: Optional[str] = None,
    session: AsyncSession = Depends(get_session)
) -> List[WorkflowSourceResponse]:
    """List all workflow sources."""
    query = select(WorkflowSource)
    if status:
        query = query.where(WorkflowSource.status == status)
    
    result = await session.execute(query)
    sources = result.scalars().all()
    return [WorkflowSourceResponse.from_orm(source) for source in sources]

@router.get("/{source_id}", response_model=WorkflowSourceResponse)
async def get_source(
    source_id: UUID,
    session: AsyncSession = Depends(get_session)
) -> WorkflowSourceResponse:
    """Get a specific workflow source."""
    source = await session.get(WorkflowSource, source_id)
    if not source:
        raise HTTPException(status_code=404, detail="Source not found")
    return WorkflowSourceResponse.from_orm(source)

@router.patch("/{source_id}", response_model=WorkflowSourceResponse)
async def update_source(
    source_id: UUID,
    update_data: WorkflowSourceUpdate,
    session: AsyncSession = Depends(get_session)
) -> WorkflowSourceResponse:
    """Update a workflow source."""
    source = await session.get(WorkflowSource, source_id)
    if not source:
        raise HTTPException(status_code=404, detail="Source not found")
    
    # Update fields
    if update_data.source_type is not None:
        source.source_type = update_data.source_type
    if update_data.url is not None:
        # Check if new URL conflicts with existing source
        if update_data.url != source.url:
            result = await session.execute(
                select(WorkflowSource).where(WorkflowSource.url == update_data.url)
            )
            if result.scalar_one_or_none():
                raise HTTPException(
                    status_code=400,
                    detail=f"Source with URL {update_data.url} already exists"
                )
        source.url = update_data.url
    if update_data.api_key is not None:
        source.encrypted_api_key = WorkflowSource.encrypt_api_key(update_data.api_key)
        # Validate new API key and update version info
        version_info = await _validate_source(source.url, update_data.api_key)
        source.version_info = version_info
    if update_data.status is not None:
        source.status = update_data.status
    
    await session.commit()
    await session.refresh(source)
    return WorkflowSourceResponse.from_orm(source)

@router.delete("/{source_id}")
async def delete_source(
    source_id: UUID,
    session: AsyncSession = Depends(get_session)
) -> dict:
    """Delete a workflow source."""
    source = await session.get(WorkflowSource, source_id)
    if not source:
        raise HTTPException(status_code=404, detail="Source not found")
    
    await session.delete(source)
    await session.commit()
    return {"message": "Source deleted successfully"}


