import { useState, useCallback } from "@wordpress/element";
import { Button, Icon, Notice, ToggleControl } from "@wordpress/components";
import { __ } from "@wordpress/i18n";
import { seen, trash, update } from "@wordpress/icons";
import apiFetch from "@wordpress/api-fetch";

import {
    REST_NAMESPACE,
    REST_ROOT,
    SETTINGS_BOOT,
} from "../config";

const ROUTE_BASE = `/${REST_NAMESPACE}/support-debug`;

/**
 * Self-contained support debug panel.
 *
 * Manages its own state and REST calls — does not participate
 * in the main settings save/reset/isDirty lifecycle.
 */
export default function SupportDebugPanel() {
    const initial = SETTINGS_BOOT.supportDebug || {};

    const [enabled, setEnabled] = useState(initial.enabled || false);
    const [hasLog, setHasLog] = useState(initial.has_log || false);
    const [fileSize, setFileSize] = useState(initial.file_size || 0);
    const [fileSizeHuman, setFileSizeHuman] = useState(
        initial.file_size_human || "",
    );
    const [filename, setFilename] = useState(initial.filename || "");
    const [isBusy, setIsBusy] = useState(false);
    const [error, setError] = useState("");

    const syncStatus = useCallback((status) => {
        setEnabled(status.enabled || false);
        setHasLog(status.has_log || false);
        setFileSize(status.file_size || 0);
        setFileSizeHuman(status.file_size_human || "");
        setFilename(status.filename || "");
    }, []);

    const handleToggle = useCallback(
        async (next) => {
            setIsBusy(true);
            setError("");
            try {
                const status = await apiFetch({
                    path: ROUTE_BASE,
                    method: "POST",
                    data: { enabled: next },
                });
                syncStatus(status);
            } catch (err) {
                setError(
                    err.message || __("Failed to toggle support debug.", "cache-autopilot"),
                );
            } finally {
                setIsBusy(false);
            }
        },
        [syncStatus],
    );

    const handleDownload = useCallback(async () => {
        setIsBusy(true);
        setError("");
        try {
            const response = await apiFetch({
                path: `${ROUTE_BASE}/download`,
                parse: false,
            });
            const blob = await response.blob();
            const downloadName = filename || "cache-autopilot-support.txt";
            const url = URL.createObjectURL(blob);
            const anchor = document.createElement("a");
            anchor.href = url;
            anchor.download = downloadName;
            document.body.appendChild(anchor);
            anchor.click();
            document.body.removeChild(anchor);
            URL.revokeObjectURL(url);
        } catch (err) {
            setError(
                err.message || __("Failed to download log file.", "cache-autopilot"),
            );
        } finally {
            setIsBusy(false);
        }
    }, [filename]);

    const handleDelete = useCallback(async () => {
        setIsBusy(true);
        setError("");
        try {
            const status = await apiFetch({
                path: `${ROUTE_BASE}/log`,
                method: "DELETE",
            });
            syncStatus(status);
        } catch (err) {
            setError(
                err.message || __("Failed to delete log file.", "cache-autopilot"),
            );
        } finally {
            setIsBusy(false);
        }
    }, [syncStatus]);

    const handleView = useCallback(async () => {
        setIsBusy(true);
        setError("");

        // Pre-open tab synchronously from user gesture (popup-safe).
        const newTab = window.open("", "_blank");
        if (!newTab) {
            setError(
                __("Popup blocked. Please allow popups and try again.", "cache-autopilot"),
            );
            setIsBusy(false);
            return;
        }

        // Security hardening.
        newTab.opener = null;

        // Immediate placeholder to keep popup heuristics satisfied.
        newTab.document.write("Loading debug log...");
        newTab.document.close();

        try {
            const res = await apiFetch({
                path: `${ROUTE_BASE}/view-token`,
                method: "POST",
            });

            const token =
                res && typeof res.token === "string" ? res.token : "";
            if (token === "") {
                throw new Error("Token missing");
            }

            const restRoot = REST_ROOT || `${window.location.origin}/wp-json/`;
            const viewUrl = `${restRoot.replace(/\/+$/, "")}${ROUTE_BASE}/view?token=${encodeURIComponent(token)}&t=${Date.now()}`;
            newTab.location.href = viewUrl;
        } catch (err) {
            // Keep a console breadcrumb for support triage.
            // eslint-disable-next-line no-console
            console.error("[SupportDebug] View failed", err);
            // Graceful fallback in the already opened tab.
            if (newTab && newTab.document && newTab.document.body) {
                newTab.document.body.innerText = "Failed to load debug log.";
            }
            setError(
                __(
                    "Failed to open debug log.",
                    "cache-autopilot",
                ),
            );
        } finally {
            setIsBusy(false);
        }
    }, []);

    const handleCheckStatus = useCallback(async () => {
        setIsBusy(true);
        setError("");
        try {
            const status = await apiFetch({ path: ROUTE_BASE });
            syncStatus(status);
        } catch (err) {
            setError(
                err.message || __("Failed to refresh status.", "cache-autopilot"),
            );
        } finally {
            setIsBusy(false);
        }
    }, [syncStatus]);

    const sizeLabel = hasLog && fileSizeHuman ? fileSizeHuman : "0 KB";

    return (
        <div className='ekesto-support-debug'>
            <ToggleControl
                __nextHasNoMarginBottom
                label={__("Support debug mode", "cache-autopilot")}
                help={__(
                    "Write diagnostic events to a downloadable log file.",
                    "cache-autopilot",
                )}
                checked={enabled}
                onChange={handleToggle}
                disabled={isBusy}
            />

            <div className='ekesto-support-debug__log-container'>
                {error && (
                    <Notice
                        status='error'
                        isDismissible
                        onDismiss={() => setError("")}
                    >
                        {error}
                    </Notice>
                )}

                {!enabled && (
                    <p className='ekesto-support-debug__status'>
                        {__(
                            "Enable support debug mode to start collecting diagnostic logs.",
                            "cache-autopilot",
                        )}
                    </p>
                )}

                {enabled && (
                    <div className='ekesto-support-debug__actions'>
                        <Button
                            variant='secondary'
                            onClick={handleDownload}
                            disabled={isBusy || !hasLog}
                            size='compact'
                        >
                            {__("Download Log", "cache-autopilot")}
                        </Button>
                        <span className='ekesto-support-debug__size'>
                            {sizeLabel}
                        </span>
                        <Button
                            variant='tertiary'
                            onClick={handleCheckStatus}
                            disabled={isBusy}
                            size='compact'
                            icon={<Icon icon={update} />}
                            label={__("Refresh", "cache-autopilot")}
                        />
                        <Button
                            variant='tertiary'
                            onClick={handleView}
                            disabled={isBusy || !hasLog}
                            size='compact'
                            icon={<Icon icon={seen} />}
                            label={__("View log", "cache-autopilot")}
                        />
                        <Button
                            variant='tertiary'
                            isDestructive
                            onClick={handleDelete}
                            disabled={isBusy || !hasLog}
                            size='compact'
                            icon={<Icon icon={trash} />}
                            label={__("Delete log", "cache-autopilot")}
                        />
                    </div>
                )}
            </div>
        </div>
    );
}
