import { Fragment, useEffect, useState } from "@wordpress/element";
import { __, sprintf } from "@wordpress/i18n";
import { Button, Notice, Spinner } from "@wordpress/components";
import { seen, closeSmall, close } from "@wordpress/icons";
import RecentLogDetails from "./RecentLogDetails";
import ServerTimeClock from "./ServerTimeClock";

const CLOSE_ICON = closeSmall || close;
const LOGS_ALL_LOAD_CAP = 200;
const UTC_DATABASE_TIMESTAMP_PATTERN = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/;

const parseNonNegativeInt = (value, fallback = 0) => {
    const parsed = Number(value);
    if (!Number.isFinite(parsed) || parsed < 0) {
        return fallback;
    }

    return Math.trunc(parsed);
};

const formatStartedAt = (timestamp, tz) => {
    if (!timestamp) {
        return { date: "—", time: "" };
    }

    try {
        const formatter = new Intl.DateTimeFormat("sv-SE", {
            timeZone: tz,
            year: "numeric",
            month: "2-digit",
            day: "2-digit",
            hour: "2-digit",
            minute: "2-digit",
            second: "2-digit",
            hour12: false,
        });

        const date = new Date(timestamp + " UTC");
        const parts = formatter.formatToParts(date);

        const getPart = (type) => (
            parts.find((part) => part.type === type)?.value || ""
        );

        const datePart = [getPart("year"), getPart("month"), getPart("day")]
            .filter(Boolean)
            .join("-");
        const timePart = [getPart("hour"), getPart("minute"), getPart("second")]
            .filter(Boolean)
            .join(":");

        if (datePart !== "") {
            return { date: datePart, time: timePart };
        }
    } catch {
        // Fall through to best-effort split.
    }

    const value = String(timestamp);
    const [datePart, timePart = ""] = value.split(" ");

    return {
        date: datePart || value,
        time: timePart,
    };
};

export default function RecentLogs({
    logs = [],
    logsMeta = {},
    loading = false,
    tz = "UTC",
    error = null,
    onRefresh = null,
    onLoadRemaining = null,
    canLoadRemaining = true,
}) {
    const [refreshing, setRefreshing] = useState(false);
    const [loadingRemaining, setLoadingRemaining] = useState(false);
    const [loadRemainingError, setLoadRemainingError] = useState("");
    const [expandedLogId, setExpandedLogId] = useState(null);
    const logsTotal = parseNonNegativeInt(logsMeta?.logsTotal, logs.length);
    const logsShown = parseNonNegativeInt(logsMeta?.logsShown, logs.length);
    const logsOverflow = parseNonNegativeInt(
        logsMeta?.logsOverflow,
        Math.max(0, logsTotal - logsShown),
    );
    const logsTruncated = logsMeta?.logsTruncated === true;
    const logsLoadAmount = Math.min(logsOverflow, LOGS_ALL_LOAD_CAP);
    const loadRemainingLabel = logsOverflow > LOGS_ALL_LOAD_CAP
        ? sprintf(
            __("Load additional %d runs", "cache-autopilot"),
            logsLoadAmount,
        )
        : sprintf(
            __("Load remaining %d runs", "cache-autopilot"),
            logsOverflow,
        );

    useEffect(() => {
        setLoadRemainingError("");
    }, [logsTotal, logsShown, canLoadRemaining]);

    const handleRefresh = async () => {
        if (typeof onRefresh !== "function") {
            return;
        }

        setRefreshing(true);
        try {
            await onRefresh();
        } catch (err) {
            console.error(err);
        } finally {
            setRefreshing(false);
        }
    };

    const handleLoadRemaining = async () => {
        if (typeof onLoadRemaining !== "function" || !canLoadRemaining) {
            return;
        }

        setLoadingRemaining(true);
        setLoadRemainingError("");
        try {
            await onLoadRemaining();
        } catch (err) {
            setLoadRemainingError(
                err?.message || __("Failed to load additional runs.", "cache-autopilot"),
            );
        } finally {
            setLoadingRemaining(false);
        }
    };

    const formatDuration = (startedAt, finishedAt) => {
        if (!startedAt || !finishedAt) return "—";

        const parseUtcTimestamp = (timestamp) => {
            const match = String(timestamp).match(UTC_DATABASE_TIMESTAMP_PATTERN);
            if (!match) return Number.NaN;

            return new Date(`${match[1]}T${match[2]}Z`).getTime() / 1000;
        };

        const t0 = parseUtcTimestamp(startedAt);
        const t1 = parseUtcTimestamp(finishedAt);

        if (!Number.isFinite(t0) || !Number.isFinite(t1) || t0 <= 0 || t1 <= 0 || t1 < t0) {
            return "—";
        }

        const sec = Math.floor(t1 - t0);

        if (sec < 60) return sec + "s";

        const min = Math.floor(sec / 60);
        const rem = sec % 60;

        if (min < 60) return min + "m " + String(rem).padStart(2, "0") + "s";

        const hr = Math.floor(min / 60);
        const minRem = min % 60;
        return hr + "h " + String(minRem).padStart(2, "0") + "m";
    };

    const formatModeLabel = (modeKey) => {
        if (modeKey === "targeted") {
            return __("Targeted", "cache-autopilot");
        }
        if (modeKey === "full") {
            return __("Full", "cache-autopilot");
        }
        return modeKey || "";
    };

    const formatProgressValue = (status, value) => (
        status === "preparing" ? "—" : (value || 0)
    );

    const toggleExpanded = (logId) => {
        setExpandedLogId((current) => (current === logId ? null : logId));
    };

    return (
        <>
            {typeof onRefresh === "function" && (
                <div className='ecw-reload-log'>
                    <Button
                        variant='secondary'
                        className='ecw-reload-log__button'
                        onClick={handleRefresh}
                        isBusy={refreshing}
                        disabled={refreshing}
                    >
                        {__("Reload logs", "cache-autopilot")}
                    </Button>
                    <p className='ecw-reload-log__description ekesto-section-description'>
                        <strong>{__("Server time:", "cache-autopilot")}</strong>{" "}
                        <ServerTimeClock />
                    </p>
                </div>
            )}
            {error ? <p className='ecw-helper-text'>{error}</p> : null}
            {loading && logs.length === 0 ? (
                <Spinner />
            ) : logs.length === 0 ? (
                <p>{__("No recent runs found.", "cache-autopilot")}</p>
            ) : (
                <>
                    <div className='ekesto-responsive-table-container'>
                        <div className='ekesto-responsive-table-inner'>
                            <table className='widefat striped ecw-log-table'>
                                <thead>
                                    <tr>
                                        <th>{__("Started", "cache-autopilot")}</th>
                                        <th>{__("Duration", "cache-autopilot")}</th>
                                        <th>{__("Trigger", "cache-autopilot")}</th>
                                        <th>{__("Mode", "cache-autopilot")}</th>
                                        <th>{__("Status", "cache-autopilot")}</th>
                                        <th>{__("Total", "cache-autopilot")}</th>
                                        <th>{__("Warmed", "cache-autopilot")}</th>
                                        <th>{__("Failed", "cache-autopilot")}</th>
                                        <th className='ecw-log-table__actions-column'>
                                            <span className='screen-reader-text'>
                                                {__("Actions", "cache-autopilot")}
                                            </span>
                                        </th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {logs.map((log, index) => {
                                        const logId = log?.id ?? `log-${index}`;
                                        const started = formatStartedAt(
                                            log.started_at,
                                            tz,
                                        );
                                        const isExpanded =
                                            expandedLogId === logId;
                                        const detailsId = `ecw-log-details-${logId}`;
                                        const viewAriaLabel = isExpanded
                                            ? __("Hide URL details", "cache-autopilot")
                                            : __("View URL details", "cache-autopilot");

                                        return (
                                            <Fragment key={logId}>
                                                <tr
                                                    className={
                                                        isExpanded
                                                            ? "is-expanded"
                                                            : ""
                                                    }
                                                >
                                                    <td>
                                                        <div className='ecw-log-table__started'>
                                                            <span className='ecw-log-table__started-date'>
                                                                {started.date}
                                                            </span>
                                                            {started.time ? (
                                                                <span className='ecw-log-table__started-time'>
                                                                    {
                                                                        started.time
                                                                    }
                                                                </span>
                                                            ) : null}
                                                        </div>
                                                    </td>
                                                    <td>
                                                        {formatDuration(
                                                            log.started_at,
                                                            log.finished_at,
                                                        )}
                                                    </td>
                                                    <td>
                                                        <code>
                                                            {log.trigger_display ||
                                                                log.trigger_key ||
                                                                ""}
                                                        </code>
                                                    </td>
                                                    <td>
                                                        <code
                                                            className={
                                                                log.is_updated
                                                                    ? "ecw-log-table__mode is-updated"
                                                                    : "ecw-log-table__mode"
                                                            }
                                                            title={
                                                                log.is_updated
                                                                    ? __(
                                                                          "Later content changes were added to this warmup run.",
                                                                          "cache-autopilot",
                                                                      )
                                                                    : undefined
                                                            }
                                                        >
                                                            {formatModeLabel(
                                                                log.mode_display_key ||
                                                                    log.mode ||
                                                                    "",
                                                            )}
                                                            {log.is_updated ? (
                                                                <>
                                                                    <br />
                                                                    {__("Updated", "cache-autopilot")}
                                                                </>
                                                            ) : null}
                                                        </code>
                                                    </td>
                                                    <td>{log.status || ""}</td>
                                                    <td>
                                                        {formatProgressValue(
                                                            log.status,
                                                            log.total_urls,
                                                        )}
                                                    </td>
                                                    <td>
                                                        {formatProgressValue(
                                                            log.status,
                                                            log.warmed_urls,
                                                        )}
                                                    </td>
                                                    <td>
                                                        {formatProgressValue(
                                                            log.status,
                                                            log.failed_urls,
                                                        )}
                                                    </td>
                                                    <td className='ecw-log-table__actions-cell'>
                                                        <Button
                                                            variant='tertiary'
                                                            className='ecw-log-table__view-button'
                                                            icon={
                                                                isExpanded
                                                                    ? CLOSE_ICON
                                                                    : seen
                                                            }
                                                            onClick={() =>
                                                                toggleExpanded(
                                                                    logId,
                                                                )
                                                            }
                                                            aria-expanded={
                                                                isExpanded
                                                            }
                                                            aria-controls={
                                                                isExpanded
                                                                    ? detailsId
                                                                    : undefined
                                                            }
                                                            aria-label={
                                                                viewAriaLabel
                                                            }
                                                            label={
                                                                viewAriaLabel
                                                            }
                                                        ></Button>
                                                    </td>
                                                </tr>
                                                {isExpanded ? (
                                                    <tr className='ecw-log-table__details-row'>
                                                        <td colSpan={9}>
                                                            <RecentLogDetails
                                                                log={log}
                                                                detailsId={
                                                                    detailsId
                                                                }
                                                            />
                                                        </td>
                                                    </tr>
                                                ) : null}
                                            </Fragment>
                                        );
                                    })}
                                </tbody>
                            </table>
                        </div>
                    </div>
                    {(logsOverflow > 0 && canLoadRemaining) ||
                    loadRemainingError ? (
                        <div className='ecw-log-table__details-load-actions'>
                            {logsOverflow > 0 && canLoadRemaining ? (
                                <Button
                                    variant='secondary'
                                    onClick={handleLoadRemaining}
                                    isBusy={loadingRemaining}
                                    disabled={loadingRemaining || loading}
                                >
                                    {loadRemainingLabel}
                                </Button>
                            ) : null}
                            {loadRemainingError ? (
                                <Notice status='error' isDismissible={false}>
                                    {loadRemainingError}
                                </Notice>
                            ) : null}
                        </div>
                    ) : null}
                    {logsTruncated ? (
                        <p className='ecw-log-table__details-overflow ecw-log-table__details-overflow--truncated'>
                            {sprintf(
                                __(
                                    "Showing newest %1$d runs out of %2$d. Older runs are not loaded.",
                                    "cache-autopilot",
                                ),
                                logsShown,
                                logsTotal,
                            )}
                        </p>
                    ) : null}
                </>
            )}
        </>
    );
}
