import { Link } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import type { IconType } from 'react-icons';
import {
  FaArrowRight,
  FaBoxOpen,
  FaCheck,
  FaExclamationCircle,
  FaExclamationTriangle,
  FaLifeRing,
  FaRegEyeSlash,
  FaRegQuestionCircle,
  FaShieldAlt,
  FaSpinner,
} from 'react-icons/fa';

import { getDateRangeFromPreset } from '../agent-analytics/helpers';
import JourneyDetailModal from '../agent-analytics/JourneyDetailModal';
import type {
  AgentGapCategory,
  AgentGapMutation,
  IAgentGap,
} from '../../service/agent-analytics/agent-analytics.interface';
import {
  fetchAgentGaps,
  updateAgentGapState,
} from '../../service/agent-analytics/agent-analytics.service';

const GAPS_TO = '/agent-analytics?tab=gaps';
const MAX_VISIBLE = 5;

interface CategoryMeta {
  label: string;
  icon: IconType;
  iconBg: string;
  iconColor: string;
}

const CATEGORY_META: Record<AgentGapCategory, CategoryMeta> = {
  info_missing: {
    label: 'Info missing',
    icon: FaRegQuestionCircle,
    iconBg: 'bg-amber-50',
    iconColor: 'text-amber-600',
  },
  feature_missing: {
    label: 'Feature / product missing',
    icon: FaBoxOpen,
    iconBg: 'bg-rose-50',
    iconColor: 'text-rose-600',
  },
  cannot_guide: {
    label: 'Cannot guide',
    icon: FaExclamationTriangle,
    iconBg: 'bg-orange-50',
    iconColor: 'text-orange-600',
  },
  out_of_scope: {
    label: 'Out of scope',
    icon: FaLifeRing,
    iconBg: 'bg-sky-50',
    iconColor: 'text-sky-600',
  },
};

const categoryMetaFor = (category: AgentGapCategory): CategoryMeta =>
  CATEGORY_META[category] ?? CATEGORY_META.info_missing;

/**
 * Dashboard "Conversation gaps" widget — the most frequent active gaps from
 * the last 30 days with quick mark-fixed / dismiss actions and a conversation
 * drill-down. The full fix flow lives on the Agent Analytics Gaps tab.
 *
 * @param {object} props - Recomaze auth.
 * @return {React.ReactElement} The gaps section.
 */
export function LatestGaps({ token }: { token: string }) {
  const [gaps, setGaps] = useState<IAgentGap[]>([]);
  const [hasMore, setHasMore] = useState(false);
  const [loading, setLoading] = useState(true);
  const [pendingKey, setPendingKey] = useState<string | null>(null);
  const [openFingerprint, setOpenFingerprint] = useState<string | null>(null);

  useEffect(() => {
    if (!token) return;
    let cancelled = false;
    const range = getDateRangeFromPreset('30d');
    setLoading(true);
    void (async () => {
      try {
        const result = await fetchAgentGaps(
          range.start,
          range.end,
          MAX_VISIBLE,
          null,
          null,
          'active'
        );
        if (cancelled) return;
        setGaps(result.gaps);
        setHasMore(
          Boolean(result.next_cursor) ||
            result.total_all_categories > result.gaps.length
        );
      } catch {
        // Benign: the store may have no agent gaps yet.
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [token]);

  const handleMutate = async (gap: IAgentGap, status: AgentGapMutation) => {
    const key = `${gap.category}::${gap.target}`;
    setPendingKey(key);
    setGaps(previous =>
      previous.filter(entry => `${entry.category}::${entry.target}` !== key)
    );
    try {
      await updateAgentGapState({
        target: gap.target,
        category: gap.category,
        status,
      });
    } catch {
      console.warn('[Dashboard] gap mutate failed');
    } finally {
      setPendingKey(null);
    }
  };

  return (
    <section className="rounded-2xl border border-gray-200 bg-white p-6">
      <div className="mb-4 flex flex-wrap items-end justify-between gap-3">
        <div className="flex items-center gap-2.5">
          <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-rose-50 ring-1 ring-rose-100">
            <FaExclamationCircle className="h-4 w-4 text-rose-500" />
          </span>
          <div>
            <h2 className="text-base font-semibold text-gray-900">
              Conversation gaps
            </h2>
            <p className="mt-0.5 text-xs text-gray-500">
              Where your agent came up short · last 30 days
            </p>
          </div>
        </div>
        <Link
          to={GAPS_TO}
          className="group inline-flex items-center gap-1 rounded-full border border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-gray-600 transition-colors hover:border-[#B7007C]/30 hover:text-[#B7007C]"
        >
          View all
          <FaArrowRight className="h-3 w-3 transition-transform group-hover:translate-x-0.5" />
        </Link>
      </div>

      {loading ? (
        <SkeletonRows />
      ) : gaps.length === 0 ? (
        <EmptyState />
      ) : (
        <div className="space-y-3">
          {gaps.map((gap, index) => {
            const meta = categoryMetaFor(gap.category);
            const Icon = meta.icon;
            const key = `${gap.category}::${gap.target}`;
            const isPending = pendingKey === key;
            const firstSample = gap.samples?.[0];

            return (
              <div
                key={`${key}-${index}`}
                className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-gray-200 bg-white p-4 transition-all hover:border-[#B7007C]/30 hover:shadow-sm"
              >
                <div className="flex min-w-0 items-start gap-3">
                  <span
                    className={`mt-0.5 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg ${meta.iconBg}`}
                  >
                    <Icon className={`h-4 w-4 ${meta.iconColor}`} />
                  </span>
                  <div className="min-w-0">
                    <p className="truncate text-sm font-semibold text-gray-900">
                      {gap.target}
                    </p>
                    <p className="text-xs text-gray-500">{meta.label}</p>
                  </div>
                </div>
                <div className="flex items-center gap-2">
                  {firstSample ? (
                    <button
                      type="button"
                      onClick={() =>
                        setOpenFingerprint(firstSample.fingerprint)
                      }
                      title="Open a sample conversation"
                      className="inline-flex items-center rounded-full border border-gray-200 bg-white px-3 py-1 text-xs font-medium tabular-nums text-gray-700 transition-colors hover:border-[#B7007C]/30 hover:text-[#B7007C]"
                    >
                      {gap.count} conversation{gap.count === 1 ? '' : 's'}
                    </button>
                  ) : (
                    <span className="inline-flex items-center rounded-full border border-gray-200 bg-white px-3 py-1 text-xs tabular-nums text-gray-600">
                      {gap.count} conversation{gap.count === 1 ? '' : 's'}
                    </span>
                  )}
                  <button
                    type="button"
                    onClick={() => handleMutate(gap, 'completed')}
                    disabled={isPending}
                    title="Mark this gap as fixed"
                    className="inline-flex items-center gap-1.5 rounded-full border border-emerald-200 bg-white px-3 py-1 text-xs font-medium text-emerald-700 transition-colors hover:bg-emerald-50 disabled:cursor-not-allowed disabled:opacity-60"
                  >
                    {isPending ? (
                      <FaSpinner className="h-3.5 w-3.5 animate-spin" />
                    ) : (
                      <FaCheck className="h-3.5 w-3.5" />
                    )}
                    Mark fixed
                  </button>
                  <button
                    type="button"
                    onClick={() => handleMutate(gap, 'dismissed')}
                    disabled={isPending}
                    title="Dismiss this gap"
                    className="inline-flex h-7 w-7 items-center justify-center rounded-full border border-gray-200 bg-white text-gray-500 transition-colors hover:border-gray-300 hover:bg-gray-50 hover:text-gray-700 disabled:cursor-not-allowed disabled:opacity-60"
                  >
                    <FaRegEyeSlash className="h-3.5 w-3.5" />
                  </button>
                </div>
              </div>
            );
          })}
          {hasMore && (
            <Link
              to={GAPS_TO}
              className="group flex items-center justify-center gap-1 rounded-xl border border-dashed border-gray-200 px-4 py-2.5 text-xs font-medium text-gray-500 transition-colors hover:border-[#B7007C]/30 hover:text-[#B7007C]"
            >
              More gaps to review
              <FaArrowRight className="h-3 w-3 transition-transform group-hover:translate-x-0.5" />
            </Link>
          )}
        </div>
      )}

      {openFingerprint && (
        <JourneyDetailModal
          fingerprint={openFingerprint}
          onClose={() => setOpenFingerprint(null)}
        />
      )}
    </section>
  );
}

function SkeletonRows() {
  return (
    <div className="space-y-3">
      {Array.from({ length: 3 }).map((_, index) => (
        <div
          key={index}
          className="h-16 animate-pulse rounded-xl border border-gray-100 bg-gray-50"
        />
      ))}
    </div>
  );
}

function EmptyState() {
  return (
    <div className="flex flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-gray-200 px-6 py-10 text-center">
      <span className="flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50">
        <FaShieldAlt className="h-5 w-5 text-emerald-500" />
      </span>
      <p className="text-sm font-medium text-gray-900">No gaps detected</p>
      <p className="max-w-xs text-xs text-gray-500">
        Your agent is handling questions without falling short. New gaps surface
        here as they happen.
      </p>
    </div>
  );
}
