import { AlertTriangle, RotateCw } from 'lucide-react';

import { useForm } from '@inertiajs/react';

import { Button } from '@/Components/ui/button';

import { classifyGscError, formatErrorForSupport, SUPPORT_EMAIL } from '../helpers';

interface GscFailureCardProps {
  siteId: string;
  /**
   * Numeric DB id of the GSC connection. Used to construct a stable
   * `Ref:` token so support can correlate the user's complaint with the
   * actual row in the database. Optional because the connection might
   * have been deleted between fetch and render.
   */
  connectionId?: number;
  /**
   * Raw `sync_error` text from the GSC connection row. Free-form (Google's
   * exception messages). Pattern-matched by `classifyGscError` to choose
   * an action. Truncated to 500 chars before embedding in the mailto body.
   */
  errorMessage?: string | null;
  /**
   * Force the Reconnect CTA regardless of error classification. Used for the
   * `expired` connection status: the OAuth token is gone, so a retry-sync
   * would just fail again — the only fix is to re-auth. Without this, an
   * expired connection with an empty `sync_error` classifies as `retry` (the
   * empty-string default) and surfaces a useless "Retry sync" button.
   */
  forceReconnect?: boolean;
}

/**
 * Failure card shown when GSC sync has failed. Three slots:
 *   1. What we tried (in plain English).
 *   2. Why it likely failed (best-guess from the error string via
 *      `classifyGscError`).
 *   3. What to do next — a typed primary CTA based on the classification,
 *      plus a support hook with a stable reference id.
 *
 * Replaces the previous bare "GSC sync failed. Please retry the connection."
 * which gave the user nothing to mention to support.
 */
export function GscFailureCard({
  siteId,
  connectionId,
  errorMessage,
  forceReconnect = false,
}: GscFailureCardProps) {
  const classified = classifyGscError(errorMessage);
  // Expired tokens (forceReconnect) override the classification: re-auth is
  // the only path back, so override the cause copy too rather than showing a
  // generic "no specific reason" when sync_error is empty.
  const likelyCause = forceReconnect
    ? 'Your Google connection expired. Reconnect to resume syncing.'
    : classified.likelyCause;
  const whatToDo = forceReconnect ? 'reconnect' : classified.whatToDo;
  const refId = connectionId ? `gsc-${siteId}-${connectionId}` : `gsc-${siteId}`;
  const supportSubject = encodeURIComponent(`GSC sync failed (ref ${refId})`);
  const supportBody = encodeURIComponent(
    `Reference: ${refId}\nError: ${formatErrorForSupport(errorMessage)}\n\n` +
      'I tried to sync Google Search Console and it failed. Can you help?',
  );
  const supportHref = `mailto:${SUPPORT_EMAIL}?subject=${supportSubject}&body=${supportBody}`;

  // POST-based retry. Hits gsc.retry-sync (GscConnectionController::retrySync),
  // which clears the failed sync_status and re-dispatches SyncGscDataJob.
  // Inertia router POST so the controller's flash response surfaces via
  // useFlashToasts. Fire-and-forget — do NOT await.
  const retryForm = useForm({});
  const submitRetry = () => {
    retryForm.post(route('gsc.retry-sync', { site: siteId }), {
      preserveScroll: true,
    });
  };

  return (
    <div
      role="status"
      className="rounded-md border border-destructive/40 bg-destructive/5 p-3 space-y-2"
    >
      <div className="flex items-start gap-2">
        <AlertTriangle className="size-4 text-destructive shrink-0 mt-0.5" aria-hidden="true" />
        <div className="space-y-1.5 min-w-0 flex-1">
          <p className="text-sm font-medium text-foreground">
            We couldn't sync your Search Console data.
          </p>
          <p className="text-xs text-muted-foreground">
            <span className="font-medium text-foreground">Likely cause:</span> {likelyCause}
          </p>
        </div>
      </div>
      <div className="flex flex-wrap items-center gap-2 pt-1">
        {whatToDo === 'reconnect' ? (
          // UI-010: Button asChild for consistent focus ring + accessible semantics
          <Button asChild size="sm">
            <a href={route('gsc.connect', { site: siteId })}>Reconnect Google</a>
          </Button>
        ) : (
          /*
           * Always-on retry button. Covers:
           *   - whatToDo === 'retry' (transient/rate-limit/network errors)
           *   - whatToDo === 'contact_support' (unclassified errors — the
           *     catch-all fallback that previously left the user stuck
           *     with only a mailto link). Server-side retrySync() will
           *     clear sync_status and re-dispatch SyncGscDataJob, plus
           *     enforce max_sync_per_day so this can't be abused.
           */
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={submitRetry}
            disabled={retryForm.processing}
          >
            <RotateCw
              className={`h-3.5 w-3.5${retryForm.processing ? ' animate-spin' : ''}`}
              aria-hidden="true"
            />
            {retryForm.processing ? 'Retrying…' : 'Retry sync'}
          </Button>
        )}
        <a
          href={supportHref}
          className="inline-flex items-center gap-1.5 text-xs text-muted-foreground underline underline-offset-2 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm"
        >
          Contact support
        </a>
        <span className="text-xs text-muted-foreground font-data">Ref: {refId}</span>
      </div>
    </div>
  );
}
