import React, { useCallback, useEffect, useState } from "react";
import { __, sprintf } from "@wordpress/i18n";
import DefaultPageLayout from "@/components/DefaultPageLayout";
import ProOnlyMessage from "@/components/ProOnlyMessage";
import { getRouteVisiblity } from "@libs/menu-visibility";
import { ToastContainer, useToast } from "@libs/toast";
import { useConfirm } from "@libs/confirm-dialog";
import SpinnerButton from "@libs/confirm-dialog/SpinnerButton";
import { buildRestUrl } from "@libs/url";
import { formatDateTimeForSite } from "@/libs/dateTime";
import {
  AlertTriangle,
  CheckCircle,
  ChevronLeft,
  ChevronRight,
  RefreshCw,
} from "lucide-react";

const FailureBadge = ({ label }) => (
  <span className="arraysubs-job-status arraysubs-job-status--failed">
    <AlertTriangle size={14} />
    <span>{label || __("Unknown", "arraysubs")}</span>
  </span>
);

const formatTimestamp = (value) => {
  if (!value) {
    return "-";
  }

  return formatDateTimeForSite(value, "-");
};

const normalizeResponse = async (response, fallbackMessage) => {
  const payload = await response.json().catch(() => ({}));

  if (!response.ok) {
    throw new Error(payload.message || fallbackMessage);
  }

  return payload;
};

const RenewalFailuresContent = () => {
  const { env } = window.arraySubs;
  const { toasts, showToast, removeToast } = useToast();
  const { confirm, confirmDialog } = useConfirm();
  const [loading, setLoading] = useState(true);
  const [failures, setFailures] = useState([]);
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(0);
  const [processingKey, setProcessingKey] = useState("");
  const perPage = 30;

  const fetchFailures = useCallback(
    async (currentPage = 1) => {
      setLoading(true);

      try {
        const response = await fetch(
          buildRestUrl(env?.apiBaseUrl, "arraysubs/v1/audits/renewal-failures", {
            page: currentPage,
            per_page: perPage,
          }),
          {
            headers: { "X-WP-Nonce": env?.nonce },
          },
        );
        const result = await normalizeResponse(
          response,
          __("Failed to load renewal failures.", "arraysubs"),
        );
        const content = result.content || {};

        setFailures(content.failures || []);
        setTotal(content.total || 0);
        setTotalPages(content.total_pages || 0);
        setPage(content.page || currentPage);
      } catch (error) {
        showToast(error.message, "error");
      } finally {
        setLoading(false);
      }
    },
    [env?.apiBaseUrl, env?.nonce],
  );

  useEffect(() => {
    fetchFailures(1);
  }, []);

  const handleRetry = async (failure) => {
    try {
      await confirm({
        title: __("Retry Renewal", "arraysubs"),
        message: sprintf(
          /* translators: %d: subscription ID. */
          __(
            "Retry the failed renewal payment for subscription #%d now? The gateway verification runs before charging.",
            "arraysubs",
          ),
          failure.subscription_id,
        ),
        confirmText: __("Retry", "arraysubs"),
        cancelText: __("Cancel", "arraysubs"),
        loadingText: __("Retrying...", "arraysubs"),
        variant: "warning",
        onConfirm: async () => {
          const key = `retry-${failure.subscription_id}`;
          setProcessingKey(key);

          try {
            const response = await fetch(
              buildRestUrl(
                env?.apiBaseUrl,
                `arraysubs/v1/audits/renewal-failures/${failure.subscription_id}/retry`,
              ),
              {
                method: "POST",
                headers: { "X-WP-Nonce": env?.nonce },
              },
            );
            const result = await normalizeResponse(
              response,
              __("Renewal retry failed.", "arraysubs"),
            );
            const succeeded = Boolean(result.content?.result?.success);

            showToast(
              result.message || __("Renewal retry completed.", "arraysubs"),
              succeeded ? "success" : "error",
            );
            fetchFailures(page);
          } finally {
            setProcessingKey("");
          }
        },
      });
    } catch (error) {
      showToast(error.message, "error");
      setProcessingKey("");
    }
  };

  const handleResolve = async (failure) => {
    try {
      await confirm({
        title: __("Mark Failure Resolved", "arraysubs"),
        message: __(
          "This only dismisses the troubleshooting row and records an audit entry. It does not pay the renewal order.",
          "arraysubs",
        ),
        confirmText: __("Mark Resolved", "arraysubs"),
        cancelText: __("Cancel", "arraysubs"),
        loadingText: __("Resolving...", "arraysubs"),
        variant: "warning",
        onConfirm: async () => {
          const key = `resolve-${failure.subscription_id}`;
          setProcessingKey(key);

          try {
            const response = await fetch(
              buildRestUrl(
                env?.apiBaseUrl,
                `arraysubs/v1/audits/renewal-failures/${failure.subscription_id}/resolve`,
              ),
              {
                method: "POST",
                headers: { "X-WP-Nonce": env?.nonce },
              },
            );
            const result = await normalizeResponse(
              response,
              __("Failed to mark the failure as resolved.", "arraysubs"),
            );

            showToast(
              result.message || __("Renewal failure marked resolved.", "arraysubs"),
              "success",
            );
            fetchFailures(page);
          } finally {
            setProcessingKey("");
          }
        },
      });
    } catch (error) {
      showToast(error.message, "error");
      setProcessingKey("");
    }
  };

  const handlePageChange = (nextPage) => {
    if (nextPage < 1 || nextPage > totalPages) {
      return;
    }

    fetchFailures(nextPage);
  };

  return (
    <>
      <div className="arraysubs-audit-filters">
        <div className="arraysubs-audit-filters__row">
          <button
            type="button"
            className="button button-small"
            onClick={() => fetchFailures(page)}
            disabled={loading}
          >
            <RefreshCw size={14} className={loading ? "arraysubs-spin" : ""} />
            {__("Refresh", "arraysubs")}
          </button>
        </div>
      </div>

      <div className="arraysubs-audit-table-wrap">
        {loading && failures.length === 0 ? (
          <p className="arraysubs-loading">
            {__("Loading renewal failures...", "arraysubs")}
          </p>
        ) : failures.length === 0 ? (
          <p className="arraysubs-audit-empty">
            {__(
              "No unresolved renewal failures found. Failed renewal payments appear here until they are retried successfully or marked resolved.",
              "arraysubs",
            )}
          </p>
        ) : (
          <table className="wp-list-table widefat fixed striped arraysubs-audit-table arraysubs-renewal-failures-table">
            <thead>
              <tr>
                <th>{__("Subscription", "arraysubs")}</th>
                <th>{__("Customer", "arraysubs")}</th>
                <th>{__("Failure", "arraysubs")}</th>
                <th>{__("Failed", "arraysubs")}</th>
                <th>{__("Last Attempted", "arraysubs")}</th>
                <th>{__("Order", "arraysubs")}</th>
                <th>{__("Actions", "arraysubs")}</th>
              </tr>
            </thead>
            <tbody>
              {failures.map((failure) => (
                <tr key={failure.subscription_id}>
                  <td>
                    <a
                      href={failure.subscription_url}
                      className="arraysubs-audit-sub-link"
                    >
                      #{failure.subscription_number}
                    </a>
                    <span className="arraysubs-renewal-failures-table__meta">
                      {failure.subscription_label}
                    </span>
                    {failure.gateway && (
                      <span className="arraysubs-renewal-failures-table__meta">
                        {failure.gateway}
                      </span>
                    )}
                  </td>
                  <td>
                    <strong>{failure.customer_name}</strong>
                    <span className="arraysubs-renewal-failures-table__meta">
                      {failure.customer_email || "-"}
                    </span>
                  </td>
                  <td>
                    <FailureBadge label={failure.failure_label} />
                    <span className="arraysubs-renewal-failures-table__reason">
                      {failure.failure_reason ||
                        __("No gateway reason recorded.", "arraysubs")}
                    </span>
                  </td>
                  <td>{formatTimestamp(failure.failed_at_timestamp)}</td>
                  <td>
                    {formatTimestamp(failure.last_attempted_timestamp)}
                    {failure.retry_attempts > 0 && (
                      <span className="arraysubs-renewal-failures-table__meta">
                        {sprintf(
                          /* translators: %d: retry attempt count. */
                          __("Retries: %d", "arraysubs"),
                          failure.retry_attempts,
                        )}
                      </span>
                    )}
                    {failure.next_retry_timestamp && (
                      <span className="arraysubs-renewal-failures-table__meta">
                        {sprintf(
                          /* translators: %s: next retry timestamp. */
                          __("Next: %s", "arraysubs"),
                          formatTimestamp(failure.next_retry_timestamp),
                        )}
                      </span>
                    )}
                  </td>
                  <td>
                    {failure.order_id > 0 ? (
                      <>
                        <a
                          href={failure.order_url}
                          target="_blank"
                          rel="noreferrer"
                        >
                          #{failure.order_id}
                        </a>
                        <span className="arraysubs-renewal-failures-table__meta">
                          {failure.order_status_label || failure.order_status}
                        </span>
                        {failure.order_total && (
                          <span
                            className="arraysubs-renewal-failures-table__meta"
                            dangerouslySetInnerHTML={{
                              __html: failure.order_total,
                            }}
                          />
                        )}
                      </>
                    ) : (
                      "-"
                    )}
                  </td>
                  <td>
                    <div className="arraysubs-renewal-failures-table__actions">
                      <SpinnerButton
                        type="button"
                        className="button button-small"
                        loading={processingKey === `retry-${failure.subscription_id}`}
                        loadingText={__("Retrying...", "arraysubs")}
                        onClick={() => handleRetry(failure)}
                        disabled={!failure.can_retry}
                      >
                        <RefreshCw size={14} />
                        {__("Retry", "arraysubs")}
                      </SpinnerButton>
                      <SpinnerButton
                        type="button"
                        className="button button-small"
                        loading={
                          processingKey === `resolve-${failure.subscription_id}`
                        }
                        loadingText={__("Resolving...", "arraysubs")}
                        onClick={() => handleResolve(failure)}
                      >
                        <CheckCircle size={14} />
                        {__("Mark Resolved", "arraysubs")}
                      </SpinnerButton>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {totalPages > 1 && (
        <div className="arraysubs-audit-pagination">
          <button
            type="button"
            className="button button-small"
            disabled={page <= 1}
            onClick={() => handlePageChange(page - 1)}
          >
            <ChevronLeft size={16} />
            {__("Previous", "arraysubs")}
          </button>
          <span className="arraysubs-audit-pagination__info">
            {__("Page", "arraysubs")} {page} {__("of", "arraysubs")}{" "}
            {totalPages}
            <span className="arraysubs-audit-pagination__total">
              ({total} {__("total", "arraysubs")})
            </span>
          </span>
          <button
            type="button"
            className="button button-small"
            disabled={page >= totalPages}
            onClick={() => handlePageChange(page + 1)}
          >
            {__("Next", "arraysubs")}
            <ChevronRight size={16} />
          </button>
        </div>
      )}

      {confirmDialog}
      <ToastContainer toasts={toasts} removeToast={removeToast} />
    </>
  );
};

const RenewalFailures = () => {
  const menuItems = window.arraySubs?.menu?.items || [];
  const visibility = getRouteVisiblity("/audits/renewal-failures", menuItems);
  const isProActive = visibility === 1;

  return (
    <DefaultPageLayout
      title={__("Renewal Failures", "arraysubs")}
      subtitle={
        isProActive
          ? __(
              "Troubleshooting queue for failed renewal payments that still need action.",
              "arraysubs",
            )
          : ""
      }
    >
      {isProActive ? <RenewalFailuresContent /> : <ProOnlyMessage />}
    </DefaultPageLayout>
  );
};

export default RenewalFailures;
