import React, { Fragment } from "react";
import OneUptimeDate from "../../../../Types/Date";
import CopyTextButton from "../../CopyTextButton/CopyTextButton";
import ComponentLoader from "../../ComponentLoader/ComponentLoader";
import SeverityBadge from "./SeverityBadge";
import { getSeverityTheme } from "./severityTheme";
import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
import Icon from "../../Icon/Icon";
import IconProp from "../../../../Types/Icon/IconProp";
import { getLogsAttributeKeyFromColumnId, isLogsAttributeColumnId, normalizeLogsTableColumns, } from "../types";
export const resolveLogIdentifier = (log, index) => {
    const possibleIds = [
        log.id,
        log._id,
        log._objectId,
        log.traceId,
        log.timeUnixNano,
    ];
    for (const candidate of possibleIds) {
        if (!candidate) {
            continue;
        }
        try {
            return candidate.toString();
        }
        catch (_a) {
            continue;
        }
    }
    return `log-row-${index}`;
};
const stringifyLogValue = (value) => {
    if (value === undefined || value === null) {
        return "-";
    }
    if (typeof value === "string") {
        return value || "-";
    }
    if (typeof value === "number" || typeof value === "boolean") {
        return value.toString();
    }
    try {
        return JSON.stringify(value);
    }
    catch (_a) {
        return String(value);
    }
};
const LogsTable = (props) => {
    const showEmptyState = !props.isLoading && props.logs.length === 0;
    const activeSortField = props.sortField;
    const activeSortOrder = props.sortOrder || SortOrder.Descending;
    const selectedColumns = normalizeLogsTableColumns(props.selectedColumns);
    const showTraceColumn = selectedColumns.includes("traceId");
    const showSpanColumn = selectedColumns.includes("spanId");
    const resolveSortIcon = (field) => {
        if (activeSortField !== field) {
            return IconProp.ArrowUpDown;
        }
        return activeSortOrder === SortOrder.Descending
            ? IconProp.ChevronDown
            : IconProp.ChevronUp;
    };
    const resolveSortIconClass = (field) => {
        const base = "h-3.5 w-3.5 flex-none transition-colors";
        if (activeSortField === field) {
            return `${base} text-indigo-500`;
        }
        return `${base} text-gray-300`;
    };
    const getHeaderCell = (columnId) => {
        if (columnId === "time") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId },
                React.createElement("button", { type: "button", className: `flex items-center gap-2 text-left font-semibold tracking-wider text-gray-500 transition-colors hover:text-gray-700 focus:outline-none ${activeSortField === "time" ? "text-gray-700" : ""}`, onClick: () => {
                        var _a;
                        (_a = props.onSortChange) === null || _a === void 0 ? void 0 : _a.call(props, "time");
                    }, "aria-sort": activeSortField === "time"
                        ? activeSortOrder === SortOrder.Descending
                            ? "descending"
                            : "ascending"
                        : "none" },
                    React.createElement("span", null, "Time"),
                    React.createElement(Icon, { icon: resolveSortIcon("time"), className: resolveSortIconClass("time"), "aria-hidden": "true" }))));
        }
        if (columnId === "severity") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId },
                React.createElement("button", { type: "button", className: `flex items-center gap-2 text-left font-semibold tracking-wider text-gray-500 transition-colors hover:text-gray-700 focus:outline-none ${activeSortField === "severityText" ? "text-gray-700" : ""}`, onClick: () => {
                        var _a;
                        (_a = props.onSortChange) === null || _a === void 0 ? void 0 : _a.call(props, "severityText");
                    }, "aria-sort": activeSortField === "severityText"
                        ? activeSortOrder === SortOrder.Descending
                            ? "descending"
                            : "ascending"
                        : "none" },
                    React.createElement("span", null, "Severity"),
                    React.createElement(Icon, { icon: resolveSortIcon("severityText"), className: resolveSortIconClass("severityText"), "aria-hidden": "true" }))));
        }
        if (columnId === "service") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId }, "Service"));
        }
        if (columnId === "message") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId }, "Message"));
        }
        if (columnId === "traceId") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId }, "Trace ID"));
        }
        if (columnId === "spanId") {
            return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId }, "Span ID"));
        }
        return (React.createElement("th", { scope: "col", className: "px-4 py-2.5", key: columnId }, getLogsAttributeKeyFromColumnId(columnId) || columnId));
    };
    return (React.createElement("div", { className: "relative" },
        React.createElement("div", { className: "overflow-x-auto bg-white" },
            React.createElement("table", { className: "min-w-full" },
                React.createElement("thead", { className: "bg-gray-50/80" },
                    React.createElement("tr", { className: "text-left text-[11px] font-semibold uppercase tracking-wider text-gray-500" }, selectedColumns.map((columnId) => {
                        return getHeaderCell(columnId);
                    }))),
                React.createElement("tbody", { className: "divide-y divide-gray-100" }, props.logs.map((log, index) => {
                    var _a, _b, _c, _d;
                    const rowId = resolveLogIdentifier(log, index);
                    const primaryEntityId = ((_a = log.primaryEntityId) === null || _a === void 0 ? void 0 : _a.toString()) || "";
                    const service = props.serviceMap[primaryEntityId];
                    const serviceName = (service === null || service === void 0 ? void 0 : service.name) || primaryEntityId || "Unknown";
                    const serviceColor = ((service === null || service === void 0 ? void 0 : service.serviceColor) && (service === null || service === void 0 ? void 0 : service.serviceColor.toString())) ||
                        "#94a3b8";
                    const message = ((_b = log.body) === null || _b === void 0 ? void 0 : _b.toString()) || "";
                    const traceId = ((_c = log.traceId) === null || _c === void 0 ? void 0 : _c.toString()) || "";
                    const spanId = ((_d = log.spanId) === null || _d === void 0 ? void 0 : _d.toString()) || "";
                    const isSelected = props.selectedLogId === rowId;
                    const isFocused = props.focusedRowIndex === index;
                    const severityTheme = getSeverityTheme(log.severityText);
                    return (React.createElement(Fragment, { key: rowId },
                        React.createElement("tr", { onClick: () => {
                                props.onRowClick(log, rowId);
                            }, className: `group cursor-pointer align-top transition-colors hover:bg-gray-50/70 border-l-[3px] ${severityTheme.borderClass} ${isSelected
                                ? "bg-indigo-50/50 ring-1 ring-inset ring-indigo-200"
                                : isFocused
                                    ? "bg-gray-100/70 ring-1 ring-inset ring-gray-300"
                                    : ""}`, "data-focused": isFocused || undefined, "aria-selected": isSelected, "aria-expanded": isSelected }, selectedColumns.map((columnId) => {
                            if (columnId === "time") {
                                return (React.createElement("td", { className: "whitespace-nowrap px-4 py-2 text-[13px] font-mono text-gray-600", key: columnId }, log.time
                                    ? OneUptimeDate.getDateAsUserFriendlyFormattedString(log.time)
                                    : "-"));
                            }
                            if (columnId === "service") {
                                return (React.createElement("td", { className: "px-4 py-2", key: columnId },
                                    React.createElement("div", { className: "flex items-center gap-3 text-sm text-gray-700" },
                                        React.createElement("span", { className: "h-2.5 w-2.5 flex-none rounded-full shadow-sm", style: { backgroundColor: serviceColor }, "aria-hidden": "true" }),
                                        React.createElement("span", { className: "truncate", title: serviceName }, serviceName))));
                            }
                            if (columnId === "severity") {
                                return (React.createElement("td", { className: "px-4 py-2", key: columnId },
                                    React.createElement(SeverityBadge, { severity: log.severityText })));
                            }
                            if (columnId === "message") {
                                return (React.createElement("td", { className: "px-4 py-2", key: columnId },
                                    React.createElement("div", { className: "flex items-start justify-between gap-3" },
                                        React.createElement("div", { className: "flex min-w-0 flex-1 flex-col gap-1" },
                                            React.createElement("p", { className: "whitespace-pre-wrap break-words text-sm text-gray-800", title: message }, message || "-"),
                                            ((traceId && !showTraceColumn) ||
                                                (spanId && !showSpanColumn)) && (React.createElement("div", { className: "flex flex-wrap gap-3 text-[11px] tracking-wide text-gray-400" },
                                                traceId && !showTraceColumn && (React.createElement("span", null,
                                                    "Trace: ",
                                                    traceId)),
                                                spanId && !showSpanColumn && (React.createElement("span", null,
                                                    "Span: ",
                                                    spanId))))),
                                        React.createElement(CopyTextButton, { textToBeCopied: message, size: "xs", variant: "ghost", iconOnly: true, title: "Copy log message", className: "opacity-0 transition-opacity group-hover:opacity-100" }))));
                            }
                            if (columnId === "traceId") {
                                return (React.createElement("td", { className: "max-w-xs px-4 py-2 text-sm text-gray-600", key: columnId },
                                    React.createElement("span", { className: "block truncate font-mono", title: traceId }, traceId || "-")));
                            }
                            if (columnId === "spanId") {
                                return (React.createElement("td", { className: "max-w-xs px-4 py-2 text-sm text-gray-600", key: columnId },
                                    React.createElement("span", { className: "block truncate font-mono", title: spanId }, spanId || "-")));
                            }
                            if (isLogsAttributeColumnId(columnId)) {
                                const attributeKey = getLogsAttributeKeyFromColumnId(columnId);
                                const attributeValue = attributeKey &&
                                    typeof log.attributes === "object" &&
                                    log.attributes
                                    ? log.attributes[attributeKey]
                                    : undefined;
                                const displayValue = stringifyLogValue(attributeValue);
                                return (React.createElement("td", { className: "max-w-xs px-4 py-2 text-sm text-gray-600", key: columnId },
                                    React.createElement("span", { className: "block truncate", title: displayValue }, displayValue)));
                            }
                            return (React.createElement("td", { className: "px-4 py-2 text-sm text-gray-600", key: columnId }, "-"));
                        })),
                        isSelected && props.renderExpandedContent && (React.createElement("tr", { className: "bg-white" },
                            React.createElement("td", { colSpan: selectedColumns.length, className: "px-6 pb-6 pt-3" }, props.renderExpandedContent(log))))));
                })))),
        props.isLoading && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center bg-white/80 backdrop-blur-sm" },
            React.createElement(ComponentLoader, null))),
        showEmptyState && (React.createElement("div", { className: "flex h-full items-center justify-center px-6 py-12 text-center bg-white" },
            React.createElement("div", { className: "w-full max-w-xl rounded-md border border-gray-200 bg-white p-6 text-left shadow-sm" },
                React.createElement("p", { className: "font-mono text-sm uppercase text-gray-500" }, "No logs found"),
                React.createElement("p", { className: "mt-3 font-mono text-xs text-gray-400" }, props.emptyMessage || "Adjust filters or check again later."))))));
};
export default LogsTable;
//# sourceMappingURL=LogsTable.js.map