import { Link } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import {
  FaArrowRight,
  FaBullseye,
  FaCheck,
  FaChevronDown,
  FaChevronUp,
  FaRegLightbulb,
  FaSpinner,
  FaTimes,
} from 'react-icons/fa';
import { HiSparkles } from 'react-icons/hi';

import type {
  IInsight,
  IInsightReport,
} from '../../service/agent-analytics/agent-analytics.interface';
import {
  dismissAiInsight,
  fetchAiInsights,
} from '../../service/agent-analytics/agent-analytics.service';
import { createCampaign } from '../../service/campaigns/campaigns.service';

const INSIGHTS_TO = '/agent-analytics?tab=insights';
const MAX_VISIBLE = 5;

const PRIORITY_STYLES: Record<string, { dot: string; badge: string }> = {
  high: { dot: 'bg-red-500', badge: 'bg-red-50 text-red-600' },
  medium: { dot: 'bg-yellow-500', badge: 'bg-amber-50 text-amber-600' },
  low: { dot: 'bg-green-500', badge: 'bg-emerald-50 text-emerald-600' },
};

/**
 * Dashboard "Latest insights" widget — most recent active AI recommendations
 * with the same dismiss / create-campaign actions as the Agent Analytics tab.
 *
 * @param {object} props - Recomaze auth.
 * @return {React.ReactElement} The insights section.
 */
export function LatestInsights({ token }: { token: string }) {
  const [report, setReport] = useState<IInsightReport | null>(null);
  const [loading, setLoading] = useState(true);
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [dismissingId, setDismissingId] = useState<string | null>(null);
  const [creatingId, setCreatingId] = useState<string | null>(null);
  const [campaignDone, setCampaignDone] = useState<Set<string>>(new Set());
  const [campaignError, setCampaignError] = useState<string | null>(null);

  useEffect(() => {
    if (!token) return;
    let cancelled = false;
    setLoading(true);
    void (async () => {
      try {
        const res = await fetchAiInsights();
        if (!cancelled) setReport(res?.report ?? null);
      } catch {
        // Benign: the store may have no insights report yet.
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();

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

  const activeInsights = (report?.insights ?? []).filter(
    insight => !insight.dismissed
  );
  const visibleInsights = activeInsights.slice(0, MAX_VISIBLE);
  const moreCount = Math.max(0, activeInsights.length - visibleInsights.length);

  const handleDismiss = async (insight: IInsight) => {
    if (!report) return;
    setDismissingId(insight.id);
    try {
      await dismissAiInsight(report.report_id, insight.id);
      setReport(prev =>
        prev
          ? {
              ...prev,
              insights: prev.insights.map(entry =>
                entry.id === insight.id ? { ...entry, dismissed: true } : entry
              ),
            }
          : prev
      );
    } catch {
      console.warn('[Dashboard] dismiss insight failed');
    } finally {
      setDismissingId(null);
    }
  };

  const handleCreateCampaign = async (insight: IInsight) => {
    const campaign = insight.suggested_campaign;
    if (!campaign) return;
    setCreatingId(insight.id);
    setCampaignError(null);
    try {
      await createCampaign({
        name: campaign.name,
        goal: campaign.goal,
        target_categories: campaign.target_categories,
        tone_of_voice: campaign.tone_of_voice,
        priority: campaign.priority,
        description: campaign.description,
      });
      setCampaignDone(prev => new Set(prev).add(insight.id));
    } catch (campaignErr) {
      setCampaignError(
        campaignErr instanceof Error
          ? campaignErr.message
          : 'Failed to create campaign'
      );
    } finally {
      setCreatingId(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-amber-50 ring-1 ring-amber-100">
            <FaRegLightbulb className="h-4 w-4 text-amber-500" />
          </span>
          <div>
            <h2 className="text-base font-semibold text-gray-900">
              Latest insights
            </h2>
            <p className="mt-0.5 text-xs text-gray-500">
              {activeInsights.length > 0
                ? `${activeInsights.length} active recommendation${
                    activeInsights.length === 1 ? '' : 's'
                  }`
                : 'AI-generated recommendations from your conversations'}
            </p>
          </div>
        </div>
        <Link
          to={INSIGHTS_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>

      {campaignError && (
        <div className="mb-3 flex items-center justify-between gap-3 rounded-lg border border-red-100 bg-red-50 px-3 py-2 text-xs text-red-600">
          <span>{campaignError}</span>
          <button
            type="button"
            onClick={() => setCampaignError(null)}
            aria-label="Dismiss error"
            className="shrink-0 text-red-400 transition-colors hover:text-red-600"
          >
            <FaTimes className="h-3 w-3" />
          </button>
        </div>
      )}

      {loading ? (
        <SkeletonRows />
      ) : visibleInsights.length === 0 ? (
        <EmptyState />
      ) : (
        <div className="space-y-2.5">
          {visibleInsights.map(insight => (
            <InsightCard
              key={insight.id}
              insight={insight}
              expanded={expandedId === insight.id}
              campaignDone={campaignDone.has(insight.id)}
              isDismissing={dismissingId === insight.id}
              isCreating={creatingId === insight.id}
              onToggle={() =>
                setExpandedId(current =>
                  current === insight.id ? null : insight.id
                )
              }
              onDismiss={handleDismiss}
              onCreateCampaign={handleCreateCampaign}
            />
          ))}
          {moreCount > 0 && (
            <Link
              to={INSIGHTS_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]"
            >
              +{moreCount} more insight{moreCount === 1 ? '' : 's'}
              <FaArrowRight className="h-3 w-3 transition-transform group-hover:translate-x-0.5" />
            </Link>
          )}
        </div>
      )}
    </section>
  );
}

function InsightCard({
  insight,
  expanded,
  campaignDone,
  isDismissing,
  isCreating,
  onToggle,
  onDismiss,
  onCreateCampaign,
}: {
  insight: IInsight;
  expanded: boolean;
  campaignDone: boolean;
  isDismissing: boolean;
  isCreating: boolean;
  onToggle: () => void;
  onDismiss: (insight: IInsight) => void;
  onCreateCampaign: (insight: IInsight) => void;
}) {
  const style = PRIORITY_STYLES[insight.priority] ?? PRIORITY_STYLES.low;

  return (
    <div className="overflow-hidden rounded-xl border border-gray-200 bg-white transition-colors hover:border-gray-300">
      <button
        type="button"
        onClick={onToggle}
        aria-expanded={expanded}
        className="flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-gray-50"
      >
        <span className={`h-2.5 w-2.5 shrink-0 rounded-full ${style.dot}`} />
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2">
            <p className="truncate text-sm font-semibold text-gray-900">
              {insight.title}
            </p>
            {campaignDone && (
              <span className="inline-flex shrink-0 items-center gap-1 rounded-full bg-emerald-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-emerald-600">
                <FaCheck className="h-2.5 w-2.5" />
                Campaign
              </span>
            )}
          </div>
          {insight.subtitle && (
            <p className="mt-0.5 line-clamp-2 text-xs leading-relaxed text-gray-500">
              {insight.subtitle}
            </p>
          )}
        </div>
        <span
          className={`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${style.badge}`}
        >
          {insight.priority}
        </span>
        {expanded ? (
          <FaChevronUp className="h-3 w-3 shrink-0 text-gray-400" />
        ) : (
          <FaChevronDown className="h-3 w-3 shrink-0 text-gray-400" />
        )}
      </button>

      {expanded && (
        <div className="border-t border-gray-100 px-4 pb-4">
          {insight.metrics?.length > 0 && (
            <div className="mt-3 flex flex-wrap gap-2">
              {insight.metrics.map((metric, index) => (
                <div
                  key={index}
                  className="rounded-lg border border-gray-100 bg-gray-50 px-3 py-2"
                >
                  <p className="text-xs text-gray-500">{metric.label}</p>
                  <p className="text-sm font-semibold text-gray-900">
                    {metric.value}
                  </p>
                </div>
              ))}
            </div>
          )}

          {insight.suggested_campaign && (
            <div className="mt-4 rounded-xl border border-purple-100 bg-purple-50 p-4">
              <div className="flex items-center gap-2">
                <FaBullseye className="h-4 w-4 shrink-0 text-purple-600" />
                <p className="text-sm font-semibold text-gray-900">
                  Suggested action: Create a targeted campaign
                </p>
              </div>

              <div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
                <CampaignField
                  label="Campaign name"
                  value={insight.suggested_campaign.name}
                />
                <CampaignField
                  label="Goal"
                  value={insight.suggested_campaign.goal}
                  capitalize
                />
                <CampaignField
                  label="Target categories"
                  value={
                    insight.suggested_campaign.target_categories?.join(', ') ||
                    '—'
                  }
                />
                <CampaignField
                  label="Tone"
                  value={insight.suggested_campaign.tone_of_voice}
                />
              </div>

              <div className="mt-3 flex gap-2">
                {campaignDone ? (
                  <div className="flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-3 py-1.5 text-sm text-green-700">
                    <FaCheck className="h-3.5 w-3.5" />
                    Campaign created
                  </div>
                ) : (
                  <button
                    type="button"
                    disabled={isCreating}
                    onClick={() => onCreateCampaign(insight)}
                    className="inline-flex h-8 items-center gap-1.5 rounded-md bg-[#B7007C] px-3 text-xs font-semibold text-white shadow-sm transition-colors hover:bg-[#900063] disabled:cursor-not-allowed disabled:opacity-60"
                  >
                    {isCreating && (
                      <FaSpinner className="h-3.5 w-3.5 animate-spin" />
                    )}
                    Create campaign with these settings
                  </button>
                )}
              </div>
            </div>
          )}

          <div className="mt-3 flex items-center justify-end gap-2">
            <Link
              to={INSIGHTS_TO}
              className="inline-flex h-8 items-center rounded-md px-3 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-50 hover:text-gray-900"
            >
              Open in analytics
            </Link>
            <button
              type="button"
              className="inline-flex h-8 items-center gap-1.5 rounded-md px-3 text-xs font-medium text-red-600 transition-colors hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-60"
              disabled={isDismissing}
              onClick={() => onDismiss(insight)}
            >
              {isDismissing && (
                <FaSpinner className="h-3.5 w-3.5 animate-spin" />
              )}
              Dismiss
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function CampaignField({
  label,
  value,
  capitalize,
}: {
  label: string;
  value: string;
  capitalize?: boolean;
}) {
  return (
    <div>
      <p className="text-xs text-gray-500">{label}</p>
      <div
        className={`mt-1 rounded-lg border border-purple-100 bg-white px-3 py-1.5 text-sm text-gray-900 ${
          capitalize ? 'capitalize' : ''
        }`}
      >
        {value}
      </div>
    </div>
  );
}

function SkeletonRows() {
  return (
    <div className="space-y-2.5">
      {Array.from({ length: 3 }).map((_, index) => (
        <div
          key={index}
          className="h-14 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-gray-100">
        <HiSparkles className="h-5 w-5 text-gray-400" />
      </span>
      <p className="text-sm font-medium text-gray-900">No insights yet</p>
      <p className="max-w-xs text-xs text-gray-500">
        Recommendations appear here as visitors chat with your agent.
      </p>
    </div>
  );
}
