"""
Storage provider routes for L1 server.

Manages user storage backends (Pinata, web3.storage, local, etc.)
"""

from typing import Optional, Dict, Any

from fastapi import APIRouter, Request, Depends, HTTPException, Form
from fastapi.responses import HTMLResponse, RedirectResponse
from pydantic import BaseModel

from artdag_common import render
from artdag_common.middleware import wants_html, wants_json
from artdag_common.middleware.auth import UserContext

from ..dependencies import get_database, get_current_user, require_auth, get_templates
from ..services.storage_service import StorageService, STORAGE_PROVIDERS_INFO, VALID_PROVIDER_TYPES

router = APIRouter()


# Import storage_providers module
import storage_providers as sp_module


def get_storage_service():
    """Get storage service instance."""
    import database
    return StorageService(database, sp_module)


class AddStorageRequest(BaseModel):
    provider_type: str
    config: Dict[str, Any]
    capacity_gb: int = 5
    provider_name: Optional[str] = None


class UpdateStorageRequest(BaseModel):
    config: Optional[Dict[str, Any]] = None
    capacity_gb: Optional[int] = None
    is_active: Optional[bool] = None


@router.get("")
async def list_storage(
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
    ctx: UserContext = Depends(require_auth),
):
    """List user's storage providers. HTML for browsers, JSON for API."""
    storages = await storage_service.list_storages(ctx.actor_id)

    if wants_json(request):
        return {"storages": storages}

    # Render HTML template
    from ..dependencies import get_nav_counts
    nav_counts = await get_nav_counts(ctx.actor_id)

    templates = get_templates(request)
    return render(templates, "storage/list.html", request,
        storages=storages,
        user=ctx,
        nav_counts=nav_counts,
        providers_info=STORAGE_PROVIDERS_INFO,
        active_tab="storage",
    )


@router.post("")
async def add_storage(
    req: AddStorageRequest,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
):
    """Add a storage provider via API."""
    ctx = await require_auth(request)

    storage_id, error = await storage_service.add_storage(
        actor_id=ctx.actor_id,
        provider_type=req.provider_type,
        config=req.config,
        capacity_gb=req.capacity_gb,
        provider_name=req.provider_name,
    )

    if error:
        raise HTTPException(400, error)

    return {"id": storage_id, "message": "Storage provider added"}


@router.post("/add")
async def add_storage_form(
    request: Request,
    provider_type: str = Form(...),
    provider_name: Optional[str] = Form(None),
    description: Optional[str] = Form(None),
    capacity_gb: int = Form(5),
    api_key: Optional[str] = Form(None),
    secret_key: Optional[str] = Form(None),
    api_token: Optional[str] = Form(None),
    project_id: Optional[str] = Form(None),
    project_secret: Optional[str] = Form(None),
    access_key: Optional[str] = Form(None),
    bucket: Optional[str] = Form(None),
    path: Optional[str] = Form(None),
    storage_service: StorageService = Depends(get_storage_service),
):
    """Add a storage provider via HTML form."""
    ctx = await get_current_user(request)
    if not ctx:
        return HTMLResponse('<div class="text-red-400">Not authenticated</div>', status_code=401)

    # Build config from form
    form_data = {
        "api_key": api_key,
        "secret_key": secret_key,
        "api_token": api_token,
        "project_id": project_id,
        "project_secret": project_secret,
        "access_key": access_key,
        "bucket": bucket,
        "path": path,
    }
    config, error = storage_service.build_config_from_form(provider_type, form_data)

    if error:
        return HTMLResponse(f'<div class="text-red-400">{error}</div>')

    storage_id, error = await storage_service.add_storage(
        actor_id=ctx.actor_id,
        provider_type=provider_type,
        config=config,
        capacity_gb=capacity_gb,
        provider_name=provider_name,
        description=description,
    )

    if error:
        return HTMLResponse(f'<div class="text-red-400">{error}</div>')

    return HTMLResponse(f'''
        <div class="text-green-400 mb-2">Storage provider added successfully!</div>
        <script>setTimeout(() => window.location.href = '/storage/type/{provider_type}', 1500);</script>
    ''')


@router.get("/{storage_id}")
async def get_storage(
    storage_id: int,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
):
    """Get a specific storage provider."""
    ctx = await require_auth(request)

    storage = await storage_service.get_storage(storage_id, ctx.actor_id)
    if not storage:
        raise HTTPException(404, "Storage provider not found")

    return storage


@router.patch("/{storage_id}")
async def update_storage(
    storage_id: int,
    req: UpdateStorageRequest,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
):
    """Update a storage provider."""
    ctx = await require_auth(request)

    success, error = await storage_service.update_storage(
        storage_id=storage_id,
        actor_id=ctx.actor_id,
        config=req.config,
        capacity_gb=req.capacity_gb,
        is_active=req.is_active,
    )

    if error:
        raise HTTPException(400, error)

    return {"message": "Storage provider updated"}


@router.delete("/{storage_id}")
async def delete_storage(
    storage_id: int,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
    ctx: UserContext = Depends(require_auth),
):
    """Remove a storage provider."""
    success, error = await storage_service.delete_storage(storage_id, ctx.actor_id)

    if error:
        raise HTTPException(400, error)

    if wants_html(request):
        return HTMLResponse("")

    return {"message": "Storage provider removed"}


@router.post("/{storage_id}/test")
async def test_storage(
    storage_id: int,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
):
    """Test storage provider connectivity."""
    ctx = await get_current_user(request)
    if not ctx:
        if wants_html(request):
            return HTMLResponse('<span class="text-red-400">Not authenticated</span>', status_code=401)
        raise HTTPException(401, "Not authenticated")

    success, message = await storage_service.test_storage(storage_id, ctx.actor_id)

    if wants_html(request):
        color = "green" if success else "red"
        return HTMLResponse(f'<span class="text-{color}-400">{message}</span>')

    return {"success": success, "message": message}


@router.get("/type/{provider_type}")
async def storage_type_page(
    provider_type: str,
    request: Request,
    storage_service: StorageService = Depends(get_storage_service),
    ctx: UserContext = Depends(require_auth),
):
    """Page for managing storage configs of a specific type."""
    if provider_type not in STORAGE_PROVIDERS_INFO:
        raise HTTPException(404, "Invalid provider type")

    storages = await storage_service.list_by_type(ctx.actor_id, provider_type)
    provider_info = STORAGE_PROVIDERS_INFO[provider_type]

    if wants_json(request):
        return {
            "provider_type": provider_type,
            "provider_info": provider_info,
            "storages": storages,
        }

    from ..dependencies import get_nav_counts
    nav_counts = await get_nav_counts(ctx.actor_id)

    templates = get_templates(request)
    return render(templates, "storage/type.html", request,
        provider_type=provider_type,
        provider_info=provider_info,
        storages=storages,
        user=ctx,
        nav_counts=nav_counts,
        active_tab="storage",
    )
