"""Reusable audit-tab renderer with data loaders supplied by the application."""

from __future__ import annotations

from typing import Any, Callable


AuditInventoryLoader = Callable[[], list[dict[str, Any]]]
AuditEventsLoader = Callable[[int, int, str, str], list[dict[str, Any]]]


def render_hmm_audit_tab(
    st: Any,
    inventory_loader: AuditInventoryLoader,
    events_loader: AuditEventsLoader,
    error_type: type[Exception],
) -> None:
    """Render HMM access audit data without owning DB connection details."""

    st.markdown(
        '<div class="kb-section-title input" role="heading" aria-level="3">'
        '감사로그 ( <strong>HMM 접근 관리</strong> )'
        '</div>',
        unsafe_allow_html=True,
    )
    st.markdown(
        '<div class="kb-audit-lead">'
        'HMM 백오피스의 사용자·그룹·역할·토큰·접근 정책 변경 이력을 시간순으로 확인합니다. '
        '이벤트 유형과 처리 상태로 필터링해 운영 변경의 성공·실패를 추적할 수 있습니다.'
        '</div>',
        unsafe_allow_html=True,
    )
    try:
        inventory = inventory_loader()
    except error_type as exc:
        st.error(str(exc))
        return

    event_types = tuple(
        str(item.get("event_type") or "").strip()
        for item in inventory
        if str(item.get("event_type") or "").strip()
    )
    st.markdown('<div class="kb-audit-heading">조회 조건</div>', unsafe_allow_html=True)
    with st.container(key="poc4_hmm_audit_filters"):
        event_column, status_column = st.columns(2)
        with event_column:
            selected_event_type = st.selectbox(
                "이벤트 유형",
                options=("", *event_types),
                format_func=lambda value: "전체 이벤트" if not value else value,
                key="poc4_hmm_audit_event_filter",
            )
        with status_column:
            selected_status = st.selectbox(
                "처리 상태",
                options=("", "SUCCESS", "FAILURE", "DENIED"),
                format_func=lambda value: "전체 상태" if not value else value,
                key="poc4_hmm_audit_status_filter",
            )
        days_column, limit_column, refresh_column = st.columns([1.5, 1, 0.8])
        with days_column:
            days = st.slider(
                "조회 기간",
                min_value=1,
                max_value=90,
                value=7,
                format="%d일",
                key="poc4_hmm_audit_days",
            )
        with limit_column:
            row_limit = st.number_input(
                "최대 건수",
                min_value=10,
                max_value=500,
                value=100,
                step=10,
                key="poc4_hmm_audit_row_limit",
            )
        with refresh_column:
            st.markdown('<div style="height: 28px"></div>', unsafe_allow_html=True)
            if st.button(
                "새로고침",
                icon=":material/refresh:",
                width="stretch",
                key="poc4_hmm_audit_refresh",
            ):
                inventory_loader.clear()
                events_loader.clear()
                st.rerun()

    try:
        events = events_loader(
            int(days), int(row_limit), selected_event_type, selected_status
        )
    except error_type as exc:
        st.error(str(exc))
        return

    success_count = sum(
        1 for item in events if str(item.get("status") or "").upper() == "SUCCESS"
    )
    with st.container(key="poc4_hmm_audit_metrics"):
        type_metric, event_metric, success_metric, failure_metric = st.columns(4)
        type_metric.metric("이벤트 유형", len(inventory))
        event_metric.metric("조회 이벤트", len(events))
        success_metric.metric("성공", success_count)
        failure_metric.metric("실패·거부", len(events) - success_count)

    st.markdown(
        '<div class="kb-audit-heading">이벤트 유형 현황</div>'
        f'<div class="kb-audit-caption">현재 기록된 이벤트 유형 {len(inventory)}개 · '
        '유형별 누적 건수와 최근 발생 시각을 확인합니다.</div>',
        unsafe_allow_html=True,
    )
    with st.container(key="poc4_hmm_audit_inventory_panel"):
        with st.expander("감사 이벤트 유형", expanded=True):
            if inventory:
                st.dataframe(
                    [
                        {
                            "이벤트 유형": str(item.get("event_type") or ""),
                            "누적 건수": int(item.get("event_count") or 0),
                            "최근 발생(KST)": str(item.get("latest_event_time") or ""),
                        }
                        for item in inventory
                    ],
                    column_config={
                        "이벤트 유형": st.column_config.TextColumn(width="large"),
                        "누적 건수": st.column_config.NumberColumn(width="small"),
                        "최근 발생(KST)": st.column_config.TextColumn(width="medium"),
                    },
                    hide_index=True,
                    width="stretch",
                    height=min(360, 72 + 36 * len(inventory)),
                )
            else:
                st.caption("아직 기록된 HMM 접근 관리 이벤트가 없습니다.")

    st.markdown(
        '<div class="kb-audit-heading">감사 이벤트</div>'
        '<div class="kb-audit-caption">최신 이벤트부터 표시합니다. '
        '처리 상태와 대상 식별자, 오류 메시지를 먼저 확인하세요.</div>',
        unsafe_allow_html=True,
    )
    show_details = st.toggle(
        "상세 메시지 표시",
        value=True,
        key="poc4_hmm_audit_show_details",
    )
    if not events:
        st.info("선택한 조건에 해당하는 HMM 접근 관리 이벤트가 없습니다.")
        return

    display_rows: list[dict[str, Any]] = []
    for event in events:
        row: dict[str, Any] = {
            "감사 ID": int(event.get("audit_id") or 0),
            "발생시각(KST)": str(event.get("event_time") or ""),
            "이벤트 유형": str(event.get("event_type") or ""),
            "상태": str(event.get("status") or ""),
            "토큰 Key ID": event.get("key_id"),
            "대상 Object ID": event.get("object_id"),
            "처리 행": event.get("row_count"),
            "오류 코드": str(event.get("error_code") or ""),
        }
        if show_details:
            row["메시지"] = str(event.get("message") or "")
        display_rows.append(row)

    column_config: dict[str, Any] = {
        "감사 ID": st.column_config.NumberColumn(width="small"),
        "발생시각(KST)": st.column_config.TextColumn(width="medium"),
        "이벤트 유형": st.column_config.TextColumn(width="large"),
        "상태": st.column_config.TextColumn(width="small"),
        "토큰 Key ID": st.column_config.NumberColumn(width="small"),
        "대상 Object ID": st.column_config.NumberColumn(width="small"),
        "처리 행": st.column_config.NumberColumn(width="small"),
        "오류 코드": st.column_config.TextColumn(width="medium"),
    }
    if show_details:
        column_config["메시지"] = st.column_config.TextColumn(width="large")
    with st.container(key="poc4_hmm_audit_event_panel"):
        st.dataframe(
            display_rows,
            column_config=column_config,
            hide_index=True,
            width="stretch",
            height=min(640, 104 + 38 * len(display_rows)),
        )
