'use client';

import { useEffect, useState } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';

// Maps the post-action query state to banner copy. Keep the slug interpolation
// generic — `name` is whatever the server action echoes back via ?slug=.
function describe(state, name) {
  const label = name ? `"${name}"` : 'item';
  if (state === 'installed') {
    return {
      tone: 'success',
      eyebrow: 'Installed',
      text: `${label} is now installed and available to your agents.`,
    };
  }
  if (state === 'uninstalled') {
    return {
      tone: 'success',
      eyebrow: 'Uninstalled',
      text: `${label} has been removed from your installed catalog.`,
    };
  }
  if (state === 'deferred') {
    return {
      tone: 'info',
      eyebrow: 'Pending',
      text: `Bundle install for ${label} lands in Phase 2 — the catalog now reflects the request.`,
    };
  }
  if (state === 'setup_required') {
    return {
      tone: 'info',
      eyebrow: 'Setup required',
      text: `Open the setup assistant for ${label} to finish connecting it.`,
    };
  }
  if (state === 'already_present') {
    return {
      tone: 'info',
      eyebrow: 'Already installed',
      text: `A workflow with the same slug as ${label} already exists. Edit it on /workflows.`,
    };
  }
  if (state === 'in_flight_cases') {
    return {
      tone: 'info',
      eyebrow: 'Uninstall blocked',
      text: `${label} has cases still running. Finish or cancel them before uninstalling.`,
    };
  }
  if (state === 'error') {
    return {
      tone: 'error',
      eyebrow: 'Action failed',
      text: `Could not update ${label}. Check the runtime panel for details.`,
    };
  }
  return null;
}

// Scrubs the post-action query params after the toast is dismissed or auto-expires,
// so a page refresh does not re-show the same banner.
const TOAST_PARAMS = ['toast', 'slug', 'toast_kind'];

function scrubUrl(pathname, params, router) {
  const next = params instanceof URLSearchParams ? new URLSearchParams(params) : new URLSearchParams(params.toString());
  let changed = false;
  for (const key of TOAST_PARAMS) {
    if (next.has(key)) {
      next.delete(key);
      changed = true;
    }
  }
  if (!changed) return;
  const qs = next.toString();
  router.replace(qs ? `${pathname}?${qs}` : pathname, { scroll: false });
}

export default function InstallToast() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const state = searchParams.get('toast');
  const slug = searchParams.get('slug') || '';

  // Snapshot the toast for the lifetime of this banner so a URL scrub does
  // not race the fade-out. Re-snapshot when a new toast arrives.
  const [snapshot, setSnapshot] = useState(() => (state ? { state, slug, key: `${state}:${slug}:${Date.now()}` } : null));
  const [visible, setVisible] = useState(Boolean(state));

  // Capture pathname + the full query-string snapshot for the scrub callback
  // without putting unstable identities (`searchParams`, `router`) in the
  // effect dependency array — they re-bind every render in Next 15 and would
  // re-arm the timers on every keystroke / re-render. Re-arm only when a new
  // toast actually arrives.
  const queryString = searchParams.toString();
  useEffect(() => {
    if (!state) return;
    setSnapshot({ state, slug, key: `${state}:${slug}:${Date.now()}` });
    setVisible(true);
    const dismissTimer = setTimeout(() => setVisible(false), 3800);
    const scrubTimer = setTimeout(
      () => scrubUrl(pathname, new URLSearchParams(queryString), router),
      4000,
    );
    return () => {
      clearTimeout(dismissTimer);
      clearTimeout(scrubTimer);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- pathname/router intentionally excluded; see comment above
  }, [state, slug, queryString]);

  if (!visible || !snapshot) return null;
  const copy = describe(snapshot.state, snapshot.slug);
  if (!copy) return null;

  return (
    <div className={`mkt-toast ${copy.tone}`} role="status" aria-live="polite" key={snapshot.key}>
      <span>{copy.eyebrow}</span>
      <p>{copy.text}</p>
      <button
        type="button"
        onClick={() => {
          setVisible(false);
          scrubUrl(pathname, searchParams, router);
        }}
        aria-label="Dismiss notification"
      >
        ×
      </button>
    </div>
  );
}
