from app.core.auth import get_current_user
from app.utils.db import fetch_all, paginate
from fastapi import APIRouter, Depends, Request
from sqlalchemy.orm import Session
from sqlalchemy import select, asc, desc
from app.core.response import send_response, send_error
from app.core.database import get_db
from app.models.role import Role
from app.models.permission_role import PermissionRole
from uuid import uuid4

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


@router.post("")
async def store(
    request: Request,
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    data = await request.json()  # sync (tanpa await)

    if not data.get("slug") or not data.get("name"):
        return send_error("Validation error")

    if data.get("id"):
        return update_role(data["id"], data, db)

    role = Role(
        id=str(uuid4()),
        slug=data["slug"],
        name=data["name"],
    )
    role.permissions = [
        PermissionRole(
            permission_id=item["permission_id"], actions=item["actions"], role=role
        )
        for item in data.get("permissions", [])
    ]

    db.add(role)
    db.commit()
    db.refresh(role)

    return send_response(role.to_dict(), "Berhasil membuat jabatan")


def update_role(role_id: str, data: dict, db: Session):
    role = db.get(Role, role_id)
    if not role:
        return send_error("Jabatan tidak ditemukan")

    try:
        role.slug = data["slug"]
        role.name = data["name"]
        role.permissions.clear()
        db.flush()
        role.permissions = [
            PermissionRole(
                permission_id=item["permission_id"], actions=item["actions"], role=role
            )
            for item in data.get("permissions", [])
        ]
        db.commit()
    except Exception as e:
        db.rollback()
        raise e

    return send_response(role.to_dict(), "Berhasil mengupdate jabatan")


@router.get("")
def index(
    request: Request,
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    params = request.query_params

    per_page = int(params.get("itemsPerPage", 0))
    page = int(params.get("page", 1))
    sort_by = params.get("sortBy", "updated_at")
    sort_order = params.get("sortOrder", "desc")
    keyword = params.get("q")

    query = select(Role.id, Role.name, Role.slug, Role.created_at, Role.updated_at)

    if keyword:
        query = query.filter(Role.name.like(f"%{keyword}%"))

    if per_page:
        rows = paginate(db, query, page, per_page, sort_by, sort_order)
    else:
        rows = fetch_all(db, query)
    return send_response(rows, "Daftar status")


@router.get("/{id}")
def show(
    id: str,
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    role = db.execute(select(Role).where(Role.id == id)).scalar_one_or_none()

    if not role:
        return send_error("Jabatan tidak ditemukan")

    rows = db.execute(
        select(PermissionRole.permission_id, PermissionRole.actions).where(
            PermissionRole.role_id == id
        )
    ).all()

    result = role.to_dict()
    permissions = {row.permission_id: row.actions for row in rows}
    result["permissions"] = permissions
    return send_response(result, "Detail jabatan")


@router.delete("/{id}")
def destroy(
    id: str,
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    role = db.get(Role, id)
    if not role:
        return send_error("Jabatan tidak ditemukan")

    db.delete(role)
    db.commit()

    return send_response(role.to_dict(), "Berhasil menghapus jabatan")
