"""
Access Grants Management Endpoints for Mitai Jinkendo

Admin-only access grants history and manual grant creation.
"""
from datetime import datetime, timedelta
from fastapi import APIRouter, HTTPException, Depends

from db import get_db, get_cursor, r2d
from auth import require_admin

router = APIRouter(prefix="/api/access-grants", tags=["access-grants"])


@router.get("")
def list_access_grants(
    profile_id: str = None,
    active_only: bool = False,
    session: dict = Depends(require_admin)
):
    """
    Admin: List access grants.

    Query params:
    - profile_id: Filter by user
    - active_only: Only show currently active grants
    """
    with get_db() as conn:
        cur = get_cursor(conn)

        query = """
            SELECT
                ag.*,
                t.name as tier_name,
                p.name as profile_name,
                p.email as profile_email
            FROM access_grants ag
            JOIN tiers t ON t.id = ag.tier_id
            JOIN profiles p ON p.id = ag.profile_id
        """

        conditions = []
        params = []

        if profile_id:
            conditions.append("ag.profile_id = %s")
            params.append(profile_id)

        if active_only:
            conditions.append("ag.is_active = true")
            conditions.append("ag.valid_until > CURRENT_TIMESTAMP")

        if conditions:
            query += " WHERE " + " AND ".join(conditions)

        query += " ORDER BY ag.valid_until DESC"

        cur.execute(query, params)
        return [r2d(r) for r in cur.fetchall()]


@router.post("")
def create_access_grant(data: dict, session: dict = Depends(require_admin)):
    """
    Admin: Manually create access grant.

    Body:
        {
            "profile_id": "uuid",
            "tier_id": "premium",
            "duration_days": 30,
            "reason": "Compensation for bug"
        }
    """
    profile_id = data.get('profile_id')
    tier_id = data.get('tier_id')
    duration_days = data.get('duration_days')
    reason = data.get('reason', '')

    if not profile_id or not tier_id or not duration_days:
        raise HTTPException(400, "profile_id, tier_id und duration_days fehlen")

    valid_from = datetime.now()
    valid_until = valid_from + timedelta(days=duration_days)

    with get_db() as conn:
        cur = get_cursor(conn)

        # Create grant
        cur.execute("""
            INSERT INTO access_grants (
                profile_id, tier_id, granted_by, valid_from, valid_until
            )
            VALUES (%s, %s, 'admin', %s, %s)
            RETURNING id
        """, (profile_id, tier_id, valid_from, valid_until))

        grant_id = cur.fetchone()['id']

        # Log activity
        cur.execute("""
            INSERT INTO user_activity_log (profile_id, action, details)
            VALUES (%s, 'access_grant_created', %s)
        """, (
            profile_id,
            f'{{"tier": "{tier_id}", "duration_days": {duration_days}, "reason": "{reason}"}}'
        ))

        conn.commit()

        return {
            "ok": True,
            "id": grant_id,
            "valid_until": valid_until.isoformat()
        }


@router.put("/{grant_id}")
def update_access_grant(grant_id: str, data: dict, session: dict = Depends(require_admin)):
    """
    Admin: Update access grant (e.g., extend duration, pause/resume).

    Body:
        {
            "is_active": false,  // Pause grant
            "valid_until": "2026-12-31T23:59:59"  // Extend
        }
    """
    with get_db() as conn:
        cur = get_cursor(conn)

        updates = []
        values = []

        if 'is_active' in data:
            updates.append('is_active = %s')
            values.append(data['is_active'])

            if not data['is_active']:
                # Pausing - calculate remaining days
                cur.execute("SELECT valid_until FROM access_grants WHERE id = %s", (grant_id,))
                grant = cur.fetchone()
                if grant:
                    remaining = (grant['valid_until'] - datetime.now()).days
                    updates.append('remaining_days = %s')
                    values.append(remaining)
                    updates.append('paused_at = CURRENT_TIMESTAMP')

        if 'valid_until' in data:
            updates.append('valid_until = %s')
            values.append(data['valid_until'])

        if not updates:
            return {"ok": True}

        updates.append('updated = CURRENT_TIMESTAMP')
        values.append(grant_id)

        cur.execute(
            f"UPDATE access_grants SET {', '.join(updates)} WHERE id = %s",
            values
        )
        conn.commit()

        return {"ok": True}


@router.delete("/{grant_id}")
def revoke_access_grant(grant_id: str, session: dict = Depends(require_admin)):
    """Admin: Revoke access grant (hard delete)."""
    with get_db() as conn:
        cur = get_cursor(conn)

        # Get grant info for logging
        cur.execute("SELECT profile_id, tier_id FROM access_grants WHERE id = %s", (grant_id,))
        grant = cur.fetchone()

        if grant:
            # Log revocation
            cur.execute("""
                INSERT INTO user_activity_log (profile_id, action, details)
                VALUES (%s, 'access_grant_revoked', %s)
            """, (
                grant['profile_id'],
                f'{{"grant_id": "{grant_id}", "tier": "{grant["tier_id"]}"}}'
            ))

        # Delete grant
        cur.execute("DELETE FROM access_grants WHERE id = %s", (grant_id,))
        conn.commit()

        return {"ok": True}
