import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { Link } from 'react-router-dom';
import {
  AlertTriangle,
  AlertCircle,
  Target,
  TrendingUp,
  Shield,
  Lightbulb,
  Filter,
  X,
  ArrowUpRight,
  ArrowRight,
  RefreshCw,
  CheckCircle2,
  Minus,
  ChevronUp,
  ChevronDown,
} from 'lucide-react';
import { AppLayout } from '../../components/layout/AppLayout';
import { coachingApi } from '../../api/coachingApi';
import type { CoachingInsight, CoachingInsightsResponse, CoachingSeverity } from '../../types';

// ---------------------------------------------------------------------------
// Constants / styling maps
// ---------------------------------------------------------------------------

const REFRESH_INTERVAL_MS = 5 * 60 * 1000; // match backend 5-min cache TTL

const SEVERITY_ORDER: Record<CoachingSeverity, number> = { high: 0, medium: 1, low: 2 };

const severityCardStyles: Record<CoachingSeverity, string> = {
  high: 'border-red-200 bg-red-50/60',
  medium: 'border-amber-200 bg-amber-50/60',
  low: 'border-emerald-200 bg-emerald-50/60',
};

const severityBadgeStyles: Record<CoachingSeverity, string> = {
  high: 'bg-red-100 text-red-700',
  medium: 'bg-amber-100 text-amber-700',
  low: 'bg-emerald-100 text-emerald-700',
};

const severityIconStyles: Record<CoachingSeverity, string> = {
  high: 'bg-red-100 text-red-600',
  medium: 'bg-amber-100 text-amber-600',
  low: 'bg-emerald-100 text-emerald-600',
};

const CATEGORY_META: Record<string, { label: string; icon: React.ElementType }> = {
  market: { label: 'Market', icon: AlertTriangle },
  forecast: { label: 'Forecast', icon: TrendingUp },
  goal: { label: 'Goals', icon: Target },
  scale: { label: 'Scale', icon: ArrowUpRight },
  intelligence: { label: 'Intelligence', icon: Shield },
};

const ALL_CATEGORIES = ['market', 'forecast', 'goal', 'scale', 'intelligence'] as const;

function categoryMeta(category: string) {
  return CATEGORY_META[category] ?? { label: category.charAt(0).toUpperCase() + category.slice(1), icon: Lightbulb };
}

function scoreTone(score: number): { text: string; stroke: string; label: string } {
  if (score >= 80) return { text: 'text-emerald-600', stroke: 'stroke-emerald-500', label: 'Healthy' };
  if (score >= 50) return { text: 'text-amber-600', stroke: 'stroke-amber-500', label: 'Needs attention' };
  return { text: 'text-red-600', stroke: 'stroke-red-500', label: 'At risk' };
}

// Per-category score: 100 - (high*20) - (medium*10), floor 30 — mirrors backend formula.
function categoryScore(insights: CoachingInsight[]): number {
  if (insights.length === 0) return 100;
  const high = insights.filter((i) => i.severity === 'high').length;
  const medium = insights.filter((i) => i.severity === 'medium').length;
  return Math.max(30, 100 - high * 20 - medium * 10);
}

// ---------------------------------------------------------------------------
// Score gauge
// ---------------------------------------------------------------------------

function ScoreGauge({ score }: { score: number }) {
  const tone = scoreTone(score);
  return (
    <div className="relative h-28 w-28 shrink-0">
      <svg viewBox="0 0 36 36" className="h-full w-full -rotate-90">
        <circle cx="18" cy="18" r="15.915" fill="none" stroke="#e5e7eb" strokeWidth="3.2" />
        <circle
          cx="18"
          cy="18"
          r="15.915"
          fill="none"
          strokeWidth="3.2"
          strokeDasharray={`${score} 100`}
          strokeLinecap="round"
          className={`transition-all duration-700 ${tone.stroke}`}
        />
      </svg>
      <div className="absolute inset-0 flex flex-col items-center justify-center">
        <span className={`text-3xl font-bold ${tone.text}`}>{score}</span>
        <span className="text-[10px] font-medium uppercase tracking-wide text-surface-400">/ 100</span>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Insight card
// ---------------------------------------------------------------------------

function InsightCard({
  insight,
  onDismiss,
  dismissing,
}: {
  insight: CoachingInsight;
  onDismiss: (id: string) => void;
  dismissing: boolean;
}) {
  const meta = categoryMeta(insight.category);
  const Icon = meta.icon;
  return (
    <div className={`rounded-xl border p-5 transition-colors ${severityCardStyles[insight.severity]}`}>
      <div className="flex items-start gap-4">
        <div className={`mt-0.5 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg ${severityIconStyles[insight.severity]}`}>
          <Icon className="h-5 w-5" />
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-2">
            <h3 className="font-semibold text-surface-900">{insight.title}</h3>
            <span className={`rounded-full px-2 py-0.5 text-xs font-semibold uppercase tracking-wide ${severityBadgeStyles[insight.severity]}`}>
              {insight.severity}
            </span>
            <span className="rounded-full bg-white/80 px-2 py-0.5 text-xs font-medium text-surface-600 ring-1 ring-surface-200">
              {meta.label}
            </span>
          </div>
          <p className="mt-2 text-sm leading-relaxed text-surface-700">{insight.narrative}</p>
          {insight.action_url && (
            <Link
              to={insight.action_url}
              className="mt-3 inline-flex items-center gap-1 text-sm font-semibold text-brand-600 hover:text-brand-700"
            >
              Take action <ArrowUpRight className="h-3.5 w-3.5" />
            </Link>
          )}
        </div>
        <button
          onClick={() => onDismiss(insight.id)}
          disabled={dismissing}
          className="rounded-lg p-1.5 text-surface-400 transition-colors hover:bg-white/60 hover:text-surface-600 disabled:opacity-40"
          title="Dismiss for 24 hours"
          aria-label={`Dismiss ${insight.title}`}
        >
          <X className="h-4 w-4" />
        </button>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Page
// ---------------------------------------------------------------------------

export default function CoachingPage() {
  const [data, setData] = useState<CoachingInsightsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [categoryFilter, setCategoryFilter] = useState<'all' | string>('all');
  const [severityFilter, setSeverityFilter] = useState<'all' | CoachingSeverity>('all');
  const [dismissingIds, setDismissingIds] = useState<Set<string>>(new Set());
  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
  const [prevScore, setPrevScore] = useState<number | null>(null);

  const loadInsights = useCallback(async (silent = false) => {
    try {
      if (silent) setRefreshing(true);
      else setLoading(true);
      const result = await coachingApi.getInsights();
      setData((prev) => {
        if (prev) setPrevScore(prev.overall_score);
        return result;
      });
      setLastUpdated(new Date());
      setError(null);
    } catch (e) {
      if (!silent) setError(e instanceof Error ? e.message : 'Failed to load coaching insights');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

  // Initial load + auto-refresh every 5 minutes (matches backend cache TTL)
  useEffect(() => {
    loadInsights();
    const interval = setInterval(() => loadInsights(true), REFRESH_INTERVAL_MS);
    return () => clearInterval(interval);
  }, [loadInsights]);

  // Auto-dismiss toast
  useEffect(() => {
    if (!toast) return;
    const t = setTimeout(() => setToast(null), 4000);
    return () => clearTimeout(t);
  }, [toast]);

  const handleDismiss = async (id: string) => {
    setDismissingIds((prev) => new Set(prev).add(id));
    try {
      await coachingApi.dismissInsight(id);
      setData((prev) =>
        prev
          ? { ...prev, insights: prev.insights.map((i) => (i.id === id ? { ...i, dismissed: true } : i)) }
          : prev
      );
      setToast({ message: 'Insight dismissed for 24 hours', type: 'success' });
    } catch {
      setToast({ message: 'Failed to dismiss insight — please try again', type: 'error' });
    } finally {
      setDismissingIds((prev) => {
        const next = new Set(prev);
        next.delete(id);
        return next;
      });
    }
  };

  const activeInsights = useMemo(
    () =>
      (data?.insights ?? [])
        .filter((i) => !i.dismissed)
        .sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]),
    [data]
  );

  const nextMove = activeInsights[0] ?? null;

  const filteredInsights = useMemo(
    () =>
      activeInsights.filter(
        (i) =>
          (categoryFilter === 'all' || i.category === categoryFilter) &&
          (severityFilter === 'all' || i.severity === severityFilter)
      ),
    [activeInsights, categoryFilter, severityFilter]
  );

  const presentCategories = useMemo(() => {
    const set = new Set(activeInsights.map((i) => i.category));
    // Keep canonical order, then any extras the backend introduces
    const ordered = ALL_CATEGORIES.filter((c) => set.has(c)) as string[];
    for (const c of set) if (!ordered.includes(c)) ordered.push(c);
    return ordered;
  }, [activeInsights]);

  const score = data?.overall_score ?? 100;
  const tone = scoreTone(score);
  const highCount = activeInsights.filter((i) => i.severity === 'high').length;
  const mediumCount = activeInsights.filter((i) => i.severity === 'medium').length;
  const lowCount = activeInsights.filter((i) => i.severity === 'low').length;
  const dismissedCount = (data?.insights ?? []).filter((i) => i.dismissed).length;

  const scoreDelta = prevScore !== null ? score - prevScore : 0;

  if (loading && !data) {
    return (
      <AppLayout title="Smart Coaching">
        <div className="flex items-center justify-center py-24">
          <div className="h-6 w-6 animate-spin rounded-full border-2 border-brand-600 border-t-transparent" />
          <span className="ml-3 text-sm text-surface-500">Loading coaching insights…</span>
        </div>
      </AppLayout>
    );
  }

  return (
    <AppLayout title="Smart Coaching">
      {/* Toast */}
      {toast && (
        <div
          className={`fixed bottom-6 right-6 z-50 flex items-center gap-2 rounded-lg px-4 py-3 text-sm font-medium shadow-lg ${
            toast.type === 'success' ? 'bg-surface-900 text-white' : 'bg-red-600 text-white'
          }`}
        >
          {toast.type === 'success' ? <CheckCircle2 className="h-4 w-4" /> : <AlertCircle className="h-4 w-4" />}
          {toast.message}
        </div>
      )}

      {/* Header row */}
      <div className="mb-6 flex flex-wrap items-center justify-between gap-3">
        <div>
          <h1 className="text-xl font-bold text-surface-900 sm:text-2xl">Smart Coaching</h1>
          <p className="mt-1 text-sm text-surface-500">
            Data-driven recommendations across your markets, forecasts, and goals
          </p>
        </div>
        <div className="flex items-center gap-3">
          {lastUpdated && (
            <span className="text-xs text-surface-400">
              Updated {lastUpdated.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })}
            </span>
          )}
          <button
            onClick={() => loadInsights(true)}
            disabled={refreshing}
            className="inline-flex items-center gap-1.5 rounded-lg border border-surface-200 bg-white px-3 py-1.5 text-sm font-medium text-surface-600 transition-colors hover:bg-surface-50 disabled:opacity-50"
          >
            <RefreshCw className={`h-3.5 w-3.5 ${refreshing ? 'animate-spin' : ''}`} />
            Refresh
          </button>
        </div>
      </div>

      {error ? (
        <div className="rounded-xl border border-red-200 bg-red-50 p-8 text-center">
          <AlertCircle className="mx-auto h-8 w-8 text-red-400" />
          <p className="mt-3 text-sm font-medium text-red-800">{error}</p>
          <button
            onClick={() => loadInsights()}
            className="mt-3 rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700"
          >
            Try again
          </button>
        </div>
      ) : (
        <>
          {/* Score + summary */}
          <div className="mb-6 grid grid-cols-1 gap-4 lg:grid-cols-3">
            {/* Health score */}
            <div className="rounded-xl border border-surface-200 bg-white p-6">
              <div className="flex items-center gap-5">
                <ScoreGauge score={score} />
                <div>
                  <p className="text-sm font-medium text-surface-500">Business Health Score</p>
                  <p className={`mt-1 text-lg font-semibold ${tone.text}`}>{tone.label}</p>
                  {prevScore !== null && scoreDelta !== 0 && (
                    <p
                      className={`mt-1 inline-flex items-center gap-0.5 text-xs font-medium ${
                        scoreDelta > 0 ? 'text-emerald-600' : 'text-red-600'
                      }`}
                    >
                      {scoreDelta > 0 ? <ChevronUp className="h-3.5 w-3.5" /> : <ChevronDown className="h-3.5 w-3.5" />}
                      {Math.abs(scoreDelta)} pts since last refresh
                    </p>
                  )}
                  <p className="mt-1 text-xs text-surface-400">Recalculated every 5 minutes</p>
                </div>
              </div>
            </div>

            {/* Active alerts */}
            <div className="rounded-xl border border-surface-200 bg-white p-6">
              <p className="text-sm font-medium text-surface-500">Active Recommendations</p>
              <p className="mt-2 text-4xl font-bold text-surface-900">{activeInsights.length}</p>
              <div className="mt-3 flex items-center gap-3 text-xs font-medium">
                <span className="inline-flex items-center gap-1 text-red-600">
                  <span className="h-2 w-2 rounded-full bg-red-500" /> {highCount} high
                </span>
                <span className="inline-flex items-center gap-1 text-amber-600">
                  <span className="h-2 w-2 rounded-full bg-amber-500" /> {mediumCount} medium
                </span>
                <span className="inline-flex items-center gap-1 text-emerald-600">
                  <span className="h-2 w-2 rounded-full bg-emerald-500" /> {lowCount} low
                </span>
              </div>
            </div>

            {/* Dismissed */}
            <div className="rounded-xl border border-surface-200 bg-white p-6">
              <p className="text-sm font-medium text-surface-500">Dismissed</p>
              <p className="mt-2 text-4xl font-bold text-surface-900">{dismissedCount}</p>
              <p className="mt-3 text-xs text-surface-400">Hidden for 24 hours</p>
            </div>
          </div>

          {/* Next Move hero */}
          {nextMove && (
            <div className="mb-6 overflow-hidden rounded-xl border border-brand-200 bg-gradient-to-r from-brand-50 to-white">
              <div className="flex flex-col gap-4 p-6 sm:flex-row sm:items-center">
                <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-brand-100 text-brand-600">
                  <Lightbulb className="h-6 w-6" />
                </div>
                <div className="min-w-0 flex-1">
                  <div className="flex flex-wrap items-center gap-2">
                    <p className="text-xs font-bold uppercase tracking-wider text-brand-600">Your Next Move</p>
                    <span className={`rounded-full px-2 py-0.5 text-xs font-semibold uppercase ${severityBadgeStyles[nextMove.severity]}`}>
                      {nextMove.severity}
                    </span>
                  </div>
                  <h2 className="mt-1 text-lg font-bold text-surface-900">{nextMove.title}</h2>
                  <p className="mt-1 text-sm text-surface-600">{nextMove.narrative}</p>
                </div>
                {nextMove.action_url && (
                  <Link
                    to={nextMove.action_url}
                    className="inline-flex shrink-0 items-center gap-2 rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-brand-700"
                  >
                    Take action <ArrowRight className="h-4 w-4" />
                  </Link>
                )}
              </div>
            </div>
          )}

          {/* Category scorecards */}
          {activeInsights.length > 0 && (
            <div className="mb-6">
              <h3 className="mb-3 text-sm font-semibold text-surface-700">Category Scorecards</h3>
              <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
                {ALL_CATEGORIES.map((cat) => {
                  const catInsights = activeInsights.filter((i) => i.category === cat);
                  const catScore = categoryScore(catInsights);
                  const catTone = scoreTone(catScore);
                  const meta = categoryMeta(cat);
                  const Icon = meta.icon;
                  const passing = catScore >= 80;
                  return (
                    <button
                      key={cat}
                      onClick={() => setCategoryFilter(categoryFilter === cat ? 'all' : cat)}
                      className={`rounded-xl border bg-white p-4 text-left transition-all hover:shadow-sm ${
                        categoryFilter === cat ? 'border-brand-400 ring-1 ring-brand-200' : 'border-surface-200'
                      }`}
                    >
                      <div className="flex items-center justify-between">
                        <Icon className="h-4 w-4 text-surface-400" />
                        {passing ? (
                          <CheckCircle2 className="h-4 w-4 text-emerald-500" />
                        ) : catInsights.some((i) => i.severity === 'high') ? (
                          <AlertTriangle className="h-4 w-4 text-red-500" />
                        ) : (
                          <Minus className="h-4 w-4 text-amber-500" />
                        )}
                      </div>
                      <p className="mt-2 text-xs font-medium text-surface-500">{meta.label}</p>
                      <p className={`text-xl font-bold ${catTone.text}`}>{catScore}</p>
                      <p className="text-[11px] text-surface-400">
                        {catInsights.length === 0 ? 'No issues' : `${catInsights.length} alert${catInsights.length !== 1 ? 's' : ''}`}
                      </p>
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {/* Filter bar */}
          <div className="mb-4 flex flex-wrap items-center gap-2">
            <Filter className="h-4 w-4 text-surface-400" />
            <button
              onClick={() => setCategoryFilter('all')}
              className={`rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${
                categoryFilter === 'all' ? 'bg-brand-100 text-brand-700' : 'text-surface-500 hover:bg-surface-100'
              }`}
            >
              All categories
            </button>
            {presentCategories.map((cat) => {
              const meta = categoryMeta(cat);
              return (
                <button
                  key={cat}
                  onClick={() => setCategoryFilter(categoryFilter === cat ? 'all' : cat)}
                  className={`rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${
                    categoryFilter === cat ? 'bg-brand-100 text-brand-700' : 'text-surface-500 hover:bg-surface-100'
                  }`}
                >
                  {meta.label}
                </button>
              );
            })}
            <span className="mx-2 h-4 w-px bg-surface-200" />
            {(['all', 'high', 'medium', 'low'] as const).map((sev) => (
              <button
                key={sev}
                onClick={() => setSeverityFilter(sev)}
                className={`rounded-full px-3 py-1.5 text-sm font-medium capitalize transition-colors ${
                  severityFilter === sev ? 'bg-surface-900 text-white' : 'text-surface-500 hover:bg-surface-100'
                }`}
              >
                {sev === 'all' ? 'Any severity' : sev}
              </button>
            ))}
            <span className="ml-auto text-xs text-surface-400">
              {filteredInsights.length} insight{filteredInsights.length !== 1 ? 's' : ''}
            </span>
          </div>

          {/* Insights feed */}
          {filteredInsights.length === 0 ? (
            <div className="rounded-xl border border-surface-200 bg-white p-12 text-center">
              <CheckCircle2 className="mx-auto h-12 w-12 text-emerald-300" />
              <h3 className="mt-4 text-lg font-semibold text-surface-900">
                {activeInsights.length === 0 ? 'All clear!' : 'No matching insights'}
              </h3>
              <p className="mx-auto mt-2 max-w-md text-sm text-surface-500">
                {activeInsights.length === 0
                  ? 'No coaching recommendations right now — your metrics are looking good. We re-check every 5 minutes.'
                  : 'Try adjusting your category or severity filters to see other insights.'}
              </p>
            </div>
          ) : (
            <div className="space-y-4">
              {filteredInsights.map((insight) => (
                <InsightCard
                  key={insight.id}
                  insight={insight}
                  onDismiss={handleDismiss}
                  dismissing={dismissingIds.has(insight.id)}
                />
              ))}
            </div>
          )}
        </>
      )}
    </AppLayout>
  );
}