import { useInfiniteQuery } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
    ChevronDown,
    ChevronUp,
    Copy,
    ListChecks,
    RefreshCw,
    Search,
    Terminal,
} from "lucide-react";
import * as React from "react";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from "../../components/ui/card";
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from "../../components/ui/table";
import type { AuditLog } from "../../lib/adminApi";
import { fetchAuditLogs } from "../../lib/adminApi";

const defaultAuditFilters = [
    "method:POST path:/api/v1/*",
    "status:failure",
    "latency_ms:>1000",
];

type AuditDetails = {
    request_id?: string;
    method?: string;
    path?: string;
    status?: number;
    latency_ms?: number;
    error?: string;
    tenant_id?: string;
    actor_id?: string;
    action?: string;
    target?: string;
    before?: unknown;
    after?: unknown;
};

function parseDetails(details?: string): AuditDetails {
    if (!details) {
        return {};
    }
    try {
        const parsed = JSON.parse(details);
        if (parsed && typeof parsed === "object") {
            return parsed as AuditDetails;
        }
    } catch {}
    return {};
}

function formatCellValue(value: unknown) {
    if (value === null || value === undefined || value === "") {
        return "-";
    }
    if (typeof value === "string") {
        return value;
    }
    try {
        return JSON.stringify(value);
    } catch {
        return String(value);
    }
}

function formatIsoDateTime(value: string) {
    if (!value) {
        return { date: "-", time: "-" };
    }
    const parsed = new Date(value);
    if (Number.isNaN(parsed.getTime())) {
        return { date: value, time: "-" };
    }
    const date = parsed.toISOString().slice(0, 10);
    const time = parsed.toLocaleTimeString("ko-KR", { hour12: false });
    return { date, time };
}

function AuditLogsPage() {
    const [filters, setFilters] = React.useState(defaultAuditFilters);
    const [filterDraft, setFilterDraft] = React.useState("");
    const [expandedRows, setExpandedRows] = React.useState<
        Record<string, boolean>
    >({});

    const handleCopy = (value: string) => {
        if (!value) {
            return;
        }
        navigator.clipboard.writeText(value);
    };
    const {
        data,
        isLoading,
        error,
        fetchNextPage,
        hasNextPage,
        isFetchingNextPage,
        isFetching,
        refetch,
    } = useInfiniteQuery({
        queryKey: ["audit-logs"],
        queryFn: ({ pageParam }) => fetchAuditLogs(50, pageParam),
        initialPageParam: undefined as string | undefined,
        getNextPageParam: (lastPage) => lastPage.next_cursor || undefined,
    });

    const logs =
        data?.pages?.flatMap(
            (page) =>
                page?.items?.filter((item): item is AuditLog =>
                    Boolean(item),
                ) ?? [],
        ) ?? [];

    const handleAddFilter = () => {
        const trimmed = filterDraft.trim();
        if (!trimmed) {
            return;
        }
        setFilters((prev) =>
            prev.includes(trimmed) ? prev : [...prev, trimmed],
        );
        setFilterDraft("");
    };

    if (isLoading) {
        return <div className="p-8 text-center">Loading audit logs...</div>;
    }

    if (error) {
        const errMsg =
            (error as AxiosError<{ error?: string }>).response?.data?.error ??
            (error as Error).message;
        return (
            <div className="p-8 text-center text-red-500">
                Error loading logs: {errMsg}
            </div>
        );
    }

    return (
        <div className="space-y-8">
            <header className="flex flex-wrap items-start justify-between gap-4">
                <div>
                    <div className="flex items-center gap-2 text-sm text-[var(--color-muted)]">
                        <span>Audit</span>
                        <span>/</span>
                        <span className="text-foreground">Logs</span>
                    </div>
                    <h2 className="text-3xl font-semibold">감사 로그</h2>
                    <p className="text-sm text-[var(--color-muted)]">
                        Command 요청 기반 ClickHouse 로그를 조회합니다.
                        사용자/테넌트는 추후 세션 연동 시 자동 채워집니다.
                    </p>
                </div>
                <div className="flex items-center gap-2">
                    <Button
                        variant="outline"
                        onClick={() => refetch()}
                        disabled={isFetching}
                    >
                        <RefreshCw size={16} />
                        새로고침
                    </Button>
                    <Button>
                        <ListChecks size={16} />
                        Export CSV
                    </Button>
                </div>
            </header>

            <div className="space-y-4">
                <Card className="glass-panel">
                    <CardHeader className="flex flex-row items-center justify-between">
                        <div>
                            <CardTitle>Audit registry</CardTitle>
                            <CardDescription>
                                로드된 로그 {logs.length}건
                            </CardDescription>
                        </div>
                        <Badge variant="muted">Command only</Badge>
                    </CardHeader>
                    <CardContent>
                        <div className="mb-4 flex flex-wrap items-center gap-2">
                            <div className="flex flex-1 items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.02)] px-4 py-2 text-[var(--color-muted)]">
                                <Search size={14} />
                                <input
                                    value={filterDraft}
                                    onChange={(event) =>
                                        setFilterDraft(event.target.value)
                                    }
                                    onKeyDown={(event) => {
                                        if (event.key === "Enter") {
                                            handleAddFilter();
                                        }
                                    }}
                                    placeholder="필터 추가 (예: status:failure)"
                                    className="w-full bg-transparent text-sm text-foreground outline-none"
                                />
                                <Button
                                    size="sm"
                                    variant="outline"
                                    onClick={handleAddFilter}
                                >
                                    추가
                                </Button>
                            </div>
                            {filters.length === 0 ? (
                                <span className="text-xs text-[var(--color-muted)]">
                                    필터 없음
                                </span>
                            ) : (
                                filters.map((filter) => (
                                    <span
                                        key={filter}
                                        className="inline-flex items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.04)] px-3 py-1 text-xs text-[var(--color-muted)]"
                                    >
                                        <Terminal size={12} />
                                        {filter}
                                        <button
                                            type="button"
                                            onClick={() =>
                                                setFilters((prev) =>
                                                    prev.filter(
                                                        (item) =>
                                                            item !== filter,
                                                    ),
                                                )
                                            }
                                            className="inline-flex h-5 w-5 items-center justify-center rounded-full border border-[var(--color-border)] text-[10px] text-[var(--color-muted)]"
                                            aria-label={`${filter} 필터 제거`}
                                        >
                                            ×
                                        </button>
                                    </span>
                                ))
                            )}
                        </div>
                        <Table className="table-fixed">
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-[140px]">
                                        TIME
                                    </TableHead>
                                    <TableHead className="w-[160px]">
                                        ACTOR (ID)
                                    </TableHead>
                                    <TableHead>REQUEST</TableHead>
                                    <TableHead>PATH</TableHead>
                                    <TableHead className="w-[120px]">
                                        STATUS
                                    </TableHead>
                                    <TableHead>Action / Target</TableHead>
                                    <TableHead className="w-[80px]"></TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {isLoading && (
                                    <TableRow>
                                        <TableCell colSpan={7}>
                                            로딩 중...
                                        </TableCell>
                                    </TableRow>
                                )}
                                {!isLoading && logs.length === 0 && (
                                    <TableRow>
                                        <TableCell colSpan={7}>
                                            아직 수집된 감사 로그가 없습니다.
                                        </TableCell>
                                    </TableRow>
                                )}
                                {logs.map((row, index) => {
                                    const details = parseDetails(row.details);
                                    const actionLabel =
                                        details.action ||
                                        (details.method && details.path
                                            ? `${details.method} ${details.path}`
                                            : row.event_type);
                                    const rowKey = `${row.event_id}-${row.timestamp}-${index}`;
                                    const isExpanded = Boolean(
                                        expandedRows[rowKey],
                                    );
                                    return (
                                        <React.Fragment key={rowKey}>
                                            <TableRow className="bg-card/40">
                                                <TableCell className="text-xs text-[var(--color-muted)]">
                                                    {(() => {
                                                        const { date, time } =
                                                            formatIsoDateTime(
                                                                row.timestamp,
                                                            );
                                                        return (
                                                            <div className="space-y-1">
                                                                <div>
                                                                    {date}
                                                                </div>
                                                                <div>
                                                                    {time}
                                                                </div>
                                                            </div>
                                                        );
                                                    })()}
                                                </TableCell>
                                                <TableCell>
                                                    <div className="flex items-center gap-2">
                                                        <code className="rounded-md bg-secondary/60 px-2 py-1 text-xs text-muted-foreground">
                                                            {row.user_id ||
                                                                details.actor_id ||
                                                                "-"}
                                                        </code>
                                                        {(row.user_id ||
                                                            details.actor_id) && (
                                                            <Button
                                                                variant="ghost"
                                                                size="icon"
                                                                className="h-7 w-7 text-muted-foreground hover:text-primary"
                                                                aria-label="Copy actor id"
                                                                onClick={() =>
                                                                    handleCopy(
                                                                        row.user_id ||
                                                                            details.actor_id ||
                                                                            "",
                                                                    )
                                                                }
                                                            >
                                                                <Copy className="h-3 w-3" />
                                                            </Button>
                                                        )}
                                                    </div>
                                                </TableCell>
                                                <TableCell className="text-xs text-[var(--color-muted)]">
                                                    <div className="flex items-start gap-2">
                                                        <span className="break-all">
                                                            {formatCellValue(
                                                                details.request_id,
                                                            )}
                                                        </span>
                                                        {details.request_id && (
                                                            <Button
                                                                variant="ghost"
                                                                size="icon"
                                                                className="h-7 w-7 text-muted-foreground hover:text-primary"
                                                                aria-label="Copy request id"
                                                                onClick={() =>
                                                                    handleCopy(
                                                                        details.request_id ||
                                                                            "",
                                                                    )
                                                                }
                                                            >
                                                                <Copy className="h-3 w-3" />
                                                            </Button>
                                                        )}
                                                    </div>
                                                </TableCell>
                                                <TableCell className="text-xs text-[var(--color-muted)]">
                                                    <div className="font-semibold text-foreground">
                                                        {formatCellValue(
                                                            details.method,
                                                        )}
                                                    </div>
                                                    <div className="break-all">
                                                        {formatCellValue(
                                                            details.path,
                                                        )}
                                                    </div>
                                                </TableCell>
                                                <TableCell>
                                                    <Badge
                                                        variant={
                                                            row.status ===
                                                                "success" ||
                                                            row.status === "ok"
                                                                ? "success"
                                                                : "warning"
                                                        }
                                                    >
                                                        {row.status}
                                                    </Badge>
                                                </TableCell>
                                                <TableCell className="text-xs text-[var(--color-muted)]">
                                                    <div className="font-semibold text-foreground">
                                                        {actionLabel}
                                                    </div>
                                                    {details.target && (
                                                        <div className="flex items-center gap-2">
                                                            <span className="break-all">
                                                                Target ·{" "}
                                                                {details.target}
                                                            </span>
                                                            <Button
                                                                variant="ghost"
                                                                size="icon"
                                                                className="h-7 w-7 text-muted-foreground hover:text-primary"
                                                                aria-label="Copy target"
                                                                onClick={() =>
                                                                    handleCopy(
                                                                        details.target ||
                                                                            "",
                                                                    )
                                                                }
                                                            >
                                                                <Copy className="h-3 w-3" />
                                                            </Button>
                                                        </div>
                                                    )}
                                                </TableCell>
                                                <TableCell className="text-right">
                                                    <Button
                                                        variant="ghost"
                                                        size="sm"
                                                        onClick={() =>
                                                            setExpandedRows(
                                                                (prev) => ({
                                                                    ...prev,
                                                                    [rowKey]:
                                                                        !isExpanded,
                                                                }),
                                                            )
                                                        }
                                                    >
                                                        {isExpanded ? (
                                                            <ChevronUp className="h-4 w-4" />
                                                        ) : (
                                                            <ChevronDown className="h-4 w-4" />
                                                        )}
                                                    </Button>
                                                </TableCell>
                                            </TableRow>
                                            {isExpanded && (
                                                <TableRow className="bg-card/20">
                                                    <TableCell
                                                        colSpan={7}
                                                        className="text-xs"
                                                    >
                                                        <div className="grid gap-4 text-[var(--color-muted)] md:grid-cols-3">
                                                            <div className="space-y-1">
                                                                <div className="uppercase tracking-[0.16em]">
                                                                    Request
                                                                </div>
                                                                <div className="break-all">
                                                                    Request ID ·{" "}
                                                                    {formatCellValue(
                                                                        details.request_id,
                                                                    )}
                                                                </div>
                                                                <div className="break-all">
                                                                    Event ID ·{" "}
                                                                    {formatCellValue(
                                                                        row.event_id,
                                                                    )}
                                                                </div>
                                                                <div>
                                                                    IP ·{" "}
                                                                    {formatCellValue(
                                                                        row.ip_address,
                                                                    )}
                                                                </div>
                                                                <div>
                                                                    Latency ·{" "}
                                                                    {details.latency_ms !==
                                                                    undefined
                                                                        ? `${details.latency_ms}ms`
                                                                        : "-"}
                                                                </div>
                                                            </div>
                                                            <div className="space-y-1">
                                                                <div className="uppercase tracking-[0.16em]">
                                                                    Actor
                                                                </div>
                                                                <div>
                                                                    Actor ID ·{" "}
                                                                    {row.user_id ||
                                                                        details.actor_id ||
                                                                        "-"}
                                                                </div>
                                                                <div>
                                                                    Tenant ·{" "}
                                                                    {formatCellValue(
                                                                        details.tenant_id,
                                                                    )}
                                                                </div>
                                                                <div>
                                                                    Device ·{" "}
                                                                    {formatCellValue(
                                                                        row.device_id,
                                                                    )}
                                                                </div>
                                                            </div>
                                                            <div className="space-y-1">
                                                                <div className="uppercase tracking-[0.16em]">
                                                                    Result
                                                                </div>
                                                                <div className="break-all">
                                                                    Error ·{" "}
                                                                    {formatCellValue(
                                                                        details.error,
                                                                    )}
                                                                </div>
                                                                <div className="break-all">
                                                                    Before ·{" "}
                                                                    {formatCellValue(
                                                                        details.before,
                                                                    )}
                                                                </div>
                                                                <div className="break-all">
                                                                    After ·{" "}
                                                                    {formatCellValue(
                                                                        details.after,
                                                                    )}
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </TableCell>
                                                </TableRow>
                                            )}
                                        </React.Fragment>
                                    );
                                })}
                            </TableBody>
                        </Table>
                        <div className="pt-4 text-center">
                            {hasNextPage ? (
                                <Button
                                    variant="outline"
                                    onClick={() => fetchNextPage()}
                                    disabled={isFetchingNextPage}
                                >
                                    {isFetchingNextPage
                                        ? "Loading..."
                                        : "Load more"}
                                </Button>
                            ) : (
                                <span className="text-xs text-[var(--color-muted)]">
                                    End of audit feed
                                </span>
                            )}
                        </div>
                    </CardContent>
                </Card>
            </div>
        </div>
    );
}

export default AuditLogsPage;
