import React, { useCallback, useEffect, useMemo, useState } from 'react';

import { CardSkeleton } from '../agent-analytics/CardSkeleton';
import EmptyState from '../agent-analytics/EmptyState';
import InfoTooltip from '../agent-analytics/InfoTooltip';
import ConfirmDialog from '../ui/ConfirmDialog';
import type { ChatPromptVolumeEntry } from '../../service/visibility/visibility.interface';
import {
  adoptFromChat,
  getChatPromptVolumes,
  stopTrackingFromChat,
} from '../../service/visibility/visibility.service';
import { stopTrackingChatThemeTexts } from '../../utils/confirmTexts';

import { toneToBadgeClass } from './helpers';

interface TrendingInYourChatProps {
  clientId: string;
  token: string;
  brandId: string;
  onAdopted?: () => void;
}

const DEFAULT_VISIBLE = 8;

/**
 * Surfaces trending themes mined from the merchant's own chatbot, with
 * "Track in AI search" to promote a theme into the tracked prompt set.
 */
const TrendingInYourChat = ({
  clientId,
  token,
  brandId,
  onAdopted,
}: TrendingInYourChatProps): JSX.Element => {
  const [themes, setThemes] = useState<ChatPromptVolumeEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [busyByTheme, setBusyByTheme] = useState<Record<string, boolean>>({});
  const [adoptedByTheme, setAdoptedByTheme] = useState<Record<string, boolean>>(
    {}
  );
  const [expanded, setExpanded] = useState(false);
  const [pendingStopTheme, setPendingStopTheme] =
    useState<ChatPromptVolumeEntry | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await getChatPromptVolumes(clientId, token, brandId);
      setThemes(response.themes || []);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : 'Failed to load chat themes.'
      );
    } finally {
      setLoading(false);
    }
  }, [clientId, token, brandId]);

  useEffect(() => {
    load();
  }, [load]);

  const sortedThemes = useMemo(() => {
    return [...themes].sort((a, b) => {
      if (b.trending_score !== a.trending_score) {
        return (b.trending_score || 0) - (a.trending_score || 0);
      }

      return (b.volume_30d || 0) - (a.volume_30d || 0);
    });
  }, [themes]);

  const visibleThemes = expanded
    ? sortedThemes
    : sortedThemes.slice(0, DEFAULT_VISIBLE);
  const hiddenCount = sortedThemes.length - visibleThemes.length;

  const handleAdopt = async (theme: ChatPromptVolumeEntry) => {
    setBusyByTheme(prev => ({ ...prev, [theme.prompt_theme_id]: true }));
    try {
      await adoptFromChat(clientId, token, brandId, {
        theme_ids: [theme.prompt_theme_id],
      });
      setAdoptedByTheme(prev => ({
        ...prev,
        [theme.prompt_theme_id]: true,
      }));
      onAdopted?.();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to adopt theme.');
    } finally {
      setBusyByTheme(prev => ({ ...prev, [theme.prompt_theme_id]: false }));
    }
  };

  /**
   * Backdrop/Esc/cancel handler for the stop-tracking confirm modal.
   *
   * @param next {boolean} Requested open state from the modal.
   * @returns {void}
   */
  const handleStopThemeOpenChange = (next: boolean): void => {
    if (!next) setPendingStopTheme(null);
  };

  /**
   * Confirm-side handler that forwards the staged theme to the actual
   * untrack runner. Kept separate so the JSX stays declarative.
   *
   * @returns {void}
   */
  const handleStopThemeConfirm = (): void => {
    if (pendingStopTheme) handleStopTracking(pendingStopTheme);
  };

  const handleStopTracking = async (theme: ChatPromptVolumeEntry) => {
    setPendingStopTheme(null);
    setBusyByTheme(prev => ({ ...prev, [theme.prompt_theme_id]: true }));
    try {
      await stopTrackingFromChat(clientId, token, brandId, {
        theme_ids: [theme.prompt_theme_id],
      });
      // Backend hard-deletes the theme row so it should disappear from the
      // trending list entirely (per product decision). The miner may
      // resurface it on the next scan if user questions keep clustering
      // around it, which is fine.
      setThemes(prev =>
        prev.filter(row => row.prompt_theme_id !== theme.prompt_theme_id)
      );
      setAdoptedByTheme(prev => {
        const next = { ...prev };
        delete next[theme.prompt_theme_id];
        return next;
      });
      onAdopted?.();
    } catch (err) {
      setError(
        err instanceof Error ? err.message : 'Failed to stop tracking theme.'
      );
    } finally {
      setBusyByTheme(prev => {
        const next = { ...prev };
        delete next[theme.prompt_theme_id];
        return next;
      });
    }
  };

  return (
    <div className="flex flex-col gap-3">
      <div className="flex items-center gap-2">
        <h2 className="text-xl font-semibold text-gray-900">
          Trending in your chat
        </h2>
        <InfoTooltip text="Clusters of questions your own chatbot users are asking this quarter. Adopting a theme adds it to the prompts we monitor in AI search." />
      </div>

      {error && (
        <div className="bg-white rounded-xl border border-gray-200 p-4">
          <div className="flex flex-col gap-2">
            <p className="text-xs text-red-700">{error}</p>
            <button
              type="button"
              onClick={load}
              className="text-sm font-medium text-red-700 hover:underline self-start"
            >
              Retry
            </button>
          </div>
        </div>
      )}

      {loading && themes.length === 0 ? (
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))',
            gap: 16,
          }}
        >
          <CardSkeleton />
          <CardSkeleton />
          <CardSkeleton />
        </div>
      ) : sortedThemes.length === 0 ? (
        <EmptyState message="No chat themes yet. Once your chatbot has enough conversations, trending clusters will appear here." />
      ) : (
        <>
          <div className="flex flex-col gap-2">
            {visibleThemes.map(theme => {
              const alreadyTracked =
                adoptedByTheme[theme.prompt_theme_id] ||
                Boolean(theme.mapped_visibility_prompt_id);
              const trendingStrong = theme.trending_score > 50;
              const samples = (theme.sample_questions || [])
                .map(q => (q || '').trim())
                .filter(q => q !== '')
                .slice(0, 2);

              return (
                <div
                  key={theme.prompt_theme_id}
                  className="bg-white rounded-xl border border-gray-200 p-4"
                >
                  <div className="flex items-start justify-between gap-4 flex-wrap">
                    <div style={{ flex: '1 1 320px', minWidth: 0 }}>
                      <div className="flex flex-col gap-1">
                        <p className="text-sm font-semibold text-gray-900">
                          {theme.theme_label}
                        </p>
                        {samples.length > 0 && (
                          <p className="text-xs italic text-gray-500">
                            {samples.map((q, idx) => (
                              <span key={idx}>
                                {idx > 0 ? ' · ' : ''}e.g. &quot;{q}&quot;
                              </span>
                            ))}
                          </p>
                        )}
                      </div>
                    </div>

                    <div
                      style={{
                        flex: '0 0 auto',
                        alignSelf: 'flex-start',
                        paddingTop: 2,
                      }}
                    >
                      <div className="flex items-center gap-2 flex-wrap">
                        <span
                          className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${toneToBadgeClass(trendingStrong ? 'success' : undefined)}`}
                        >
                          {`Trending ${theme.trending_score}`}
                        </span>
                        <span className="text-xs text-gray-500">
                          {`7d ${theme.volume_7d} · 30d ${theme.volume_30d}`}
                        </span>
                        {alreadyTracked ? (
                          <>
                            <span
                              className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${toneToBadgeClass('success')}`}
                            >
                              Tracked
                            </span>
                            <button
                              type="button"
                              onClick={() => setPendingStopTheme(theme)}
                              disabled={busyByTheme[theme.prompt_theme_id]}
                              className="inline-flex items-center rounded-md border border-red-200 bg-white px-2.5 py-1 text-xs font-medium text-red-700 hover:bg-red-50 disabled:opacity-60"
                            >
                              {busyByTheme[theme.prompt_theme_id]
                                ? 'Stopping...'
                                : 'Stop tracking'}
                            </button>
                          </>
                        ) : (
                          <button
                            type="button"
                            onClick={() => handleAdopt(theme)}
                            disabled={busyByTheme[theme.prompt_theme_id]}
                            className="inline-flex items-center rounded-md bg-black px-2.5 py-1 text-xs font-medium text-white hover:bg-gray-800 disabled:opacity-60"
                          >
                            {busyByTheme[theme.prompt_theme_id]
                              ? 'Adopting...'
                              : 'Track in AI search'}
                          </button>
                        )}
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>

          {hiddenCount > 0 && !expanded && (
            <div className="text-center">
              <button
                type="button"
                onClick={() => setExpanded(true)}
                className="text-sm font-medium text-pink-700 hover:underline"
              >
                {`Show all (${sortedThemes.length})`}
              </button>
            </div>
          )}
          {expanded && sortedThemes.length > DEFAULT_VISIBLE && (
            <div className="text-center">
              <button
                type="button"
                onClick={() => setExpanded(false)}
                className="text-sm font-medium text-pink-700 hover:underline"
              >
                {`Collapse to top ${DEFAULT_VISIBLE}`}
              </button>
            </div>
          )}
        </>
      )}

      <ConfirmDialog
        open={pendingStopTheme !== null}
        onOpenChange={handleStopThemeOpenChange}
        busy={
          pendingStopTheme
            ? Boolean(busyByTheme[pendingStopTheme.prompt_theme_id])
            : false
        }
        onConfirm={handleStopThemeConfirm}
        {...stopTrackingChatThemeTexts(pendingStopTheme?.theme_label ?? '')}
      />
    </div>
  );
};

export default TrendingInYourChat;
