import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  AlertTriangle,
  Building2,
  CheckCircle2,
  Landmark,
  Loader2,
  MapPin,
  RefreshCw,
  Rocket,
  Scale,
  Sparkles,
  Target,
} from 'lucide-react';
import toast from 'react-hot-toast';
import {
  getStrategyRecommend,
  postStrategyRecommend,
  type StrategyRecommendResult,
} from '../../api/client';
import {
  formatScore,
  formatTaxChecklistId,
  hasTaxChecklists,
  isBlockedPath,
  normalizeStrategyResult,
  pathsForCards,
  resolveAutoSelectedPath,
  type StrategyPathView,
  type StrategyResultView,
} from './strategyCascadeModel';

export type StrategyCascadePanelProps = {
  /** Company NIP — enables GET with profile spine cache */
  nip?: string;
  /** Initial project goal (B+R, inwestycja, …) */
  initialGoal?: string;
  /** Initial region / voivodeship */
  initialRegion?: string;
  /** Optional company_data for POST when no profile spine yet */
  companyData?: Record<string, unknown>;
  /** Prefer POST (wizard) vs GET (profile page with saved spine) */
  mode?: 'get' | 'post' | 'auto';
  /** Compact layout for wizard / sidebar */
  compact?: boolean;
  /** Auto-fetch when nip/goal/region settle */
  autoLoad?: boolean;
  /** Notify parent of selected path id (user click) */
  onPathSelect?: (pathId: string, path: StrategyPathView) => void;
  /** Currently selected path (controlled); defaults to primary */
  selectedPathId?: string | null;
};

const PATH_ICONS: Record<string, React.ReactNode> = {
  tax_psi_ulgi: <Scale size={20} color="#a78bfa" />,
  regional_fst: <MapPin size={20} color="#34d399" />,
  national_feng: <Sparkles size={20} color="#38bdf8" />,
  debt_loan_guarantee: <Landmark size={20} color="#fbbf24" />,
  direct_eu_prep: <Rocket size={20} color="#f472b6" />,
};

function pathIcon(id: string) {
  return PATH_ICONS[id] || <Target size={20} color="var(--accent-blue)" />;
}

/**
 * Strategy cascade 2026 — ≥4 path cards from GET|POST /api/company/strategy/recommend.
 * Marks primary; shows de_minimis_blocked paths; goal + region inputs.
 */
const StrategyCascadePanel: React.FC<StrategyCascadePanelProps> = ({
  nip = '',
  initialGoal = '',
  initialRegion = '',
  companyData,
  mode = 'auto',
  compact = false,
  autoLoad = true,
  onPathSelect,
  selectedPathId: controlledSelected,
}) => {
  const [goal, setGoal] = useState(initialGoal);
  const [region, setRegion] = useState(initialRegion);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [view, setView] = useState<StrategyResultView | null>(null);
  const [localSelected, setLocalSelected] = useState<string | null>(null);
  /** True after the user clicks a path card (not auto-primary). */
  const userPickedRef = useRef(false);
  const localSelectedRef = useRef<string | null>(null);
  const onPathSelectRef = useRef(onPathSelect);
  onPathSelectRef.current = onPathSelect;
  const controlledRef = useRef(controlledSelected);
  controlledRef.current = controlledSelected;

  // Sync when parent changes initial goal/region (wizard step transitions)
  useEffect(() => {
    setGoal(initialGoal);
  }, [initialGoal]);
  useEffect(() => {
    setRegion(initialRegion);
  }, [initialRegion]);

  const applyResult = useCallback(
    (strategy: StrategyRecommendResult | Record<string, unknown>) => {
      const next = normalizeStrategyResult(strategy as Record<string, unknown>);
      setView(next);

      const controlled = controlledRef.current;
      const current =
        controlled !== undefined ? controlled : localSelectedRef.current;
      const auto = resolveAutoSelectedPath(next, current, userPickedRef.current);

      if (auto) {
        localSelectedRef.current = auto.id;
        setLocalSelected(auto.id);
        // Notify parent of primary (or fallback) when nothing usable was selected yet.
        // Fixes create-project omitting strategy_path when user never clicked a card.
        onPathSelectRef.current?.(auto.id, auto);
      } else if (!current && next.primaryPathId) {
        localSelectedRef.current = next.primaryPathId;
        setLocalSelected(next.primaryPathId);
      }
    },
    [],
  );

  const load = useCallback(
    async (overrides?: { goal?: string; region?: string }) => {
      const goalEff = overrides?.goal ?? goal;
      const regionEff = overrides?.region ?? region;
      setLoading(true);
      setError(null);
      try {
        const cleanedNip = (nip || '').replace(/\D/g, '');
        const usePost =
          mode === 'post' ||
          (mode === 'auto' &&
            (!!companyData || (!cleanedNip && (!!goalEff || !!regionEff))));

        let strategy: StrategyRecommendResult;
        if (usePost) {
          const res = await postStrategyRecommend({
            nip: cleanedNip || undefined,
            goal: goalEff || '',
            region: regionEff || '',
            company_data: companyData,
          });
          strategy = res.strategy;
        } else {
          const res = await getStrategyRecommend({
            nip: cleanedNip || undefined,
            goal: goalEff || '',
            region: regionEff || '',
          });
          strategy = res.strategy;
        }
        applyResult(strategy);
      } catch (e: unknown) {
        console.error('strategy/recommend failed', e);
        const msg =
          (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail ||
          'Nie udało się pobrać kaskady strategii.';
        setError(String(msg));
        toast.error('Błąd kaskady strategii');
      } finally {
        setLoading(false);
      }
    },
    [nip, goal, region, companyData, mode, applyResult],
  );

  // Auto-load on mount / when nip or parent goal/region seed changes (not every keystroke).
  useEffect(() => {
    if (!autoLoad) return;
    setGoal(initialGoal);
    setRegion(initialRegion);
    const t = window.setTimeout(() => {
      void load({ goal: initialGoal, region: initialRegion });
    }, 250);
    return () => window.clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps -- goal/region edits use Odśwież or Enter
  }, [autoLoad, nip, initialGoal, initialRegion, mode]);

  const selectedId = controlledSelected !== undefined ? controlledSelected : localSelected;
  const cards = view ? pathsForCards(view) : [];

  const handleSelect = (path: StrategyPathView) => {
    if (isBlockedPath(path)) {
      toast.error('Ścieżka zablokowana (de minimis) — wybierz inną rekomendację.');
      return;
    }
    userPickedRef.current = true;
    localSelectedRef.current = path.id;
    setLocalSelected(path.id);
    onPathSelect?.(path.id, path);
  };

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: compact ? '0.75rem' : '1rem',
      }}
      data-testid="strategy-cascade-panel"
    >
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          flexWrap: 'wrap',
          gap: '0.75rem',
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flexWrap: 'wrap' }}>
          <Target size={18} color="#a78bfa" />
          <span style={{ fontWeight: 700, fontSize: compact ? '0.95rem' : '1.05rem' }}>
            Kaskada strategii 2026
          </span>
          {view?.deMinimisExhausted && (
            <span
              style={{
                fontSize: '0.7rem',
                background: 'rgba(239,68,68,0.15)',
                color: '#f87171',
                padding: '2px 8px',
                borderRadius: 999,
                fontWeight: 600,
              }}
              title="Limit de minimis wyczerpany — instrumenty oparte o de minimis są zablokowane"
            >
              de minimis wyczerpany
            </span>
          )}
          {view?.mspStatus && (
            <span
              style={{
                fontSize: '0.7rem',
                background: 'rgba(56,189,248,0.12)',
                color: '#7dd3fc',
                padding: '2px 8px',
                borderRadius: 999,
              }}
            >
              MŚP: {view.mspStatus}
            </span>
          )}
        </div>
        <button
          type="button"
          className="btn btn-secondary"
          onClick={() => void load()}
          disabled={loading}
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            gap: 6,
            fontSize: '0.8rem',
            padding: '0.4rem 0.75rem',
          }}
        >
          {loading ? <Loader2 size={14} className="spin" /> : <RefreshCw size={14} />}
          Odśwież
        </button>
      </div>

      <div
        style={{
          display: 'grid',
          gridTemplateColumns: compact ? '1fr' : '1fr 1fr',
          gap: '0.75rem',
        }}
      >
        <div>
          <label
            style={{
              display: 'block',
              fontSize: '0.75rem',
              color: 'var(--text-muted)',
              marginBottom: 4,
              fontWeight: 600,
            }}
          >
            Cel projektu
          </label>
          <div style={{ position: 'relative' }}>
            <Building2
              size={14}
              color="var(--text-muted)"
              style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)' }}
            />
            <input
              type="text"
              className="form-input"
              value={goal}
              onChange={(e) => setGoal(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && void load()}
              placeholder="np. B+R, inwestycja, OZE, deeptech…"
              style={{
                width: '100%',
                padding: '0.55rem 0.75rem 0.55rem 2rem',
                background: 'rgba(255,255,255,0.03)',
                border: '1px solid rgba(255,255,255,0.1)',
                borderRadius: 8,
                color: '#fff',
                fontSize: '0.9rem',
              }}
            />
          </div>
        </div>
        <div>
          <label
            style={{
              display: 'block',
              fontSize: '0.75rem',
              color: 'var(--text-muted)',
              marginBottom: 4,
              fontWeight: 600,
            }}
          >
            Region / województwo
          </label>
          <div style={{ position: 'relative' }}>
            <MapPin
              size={14}
              color="var(--text-muted)"
              style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)' }}
            />
            <input
              type="text"
              className="form-input"
              value={region}
              onChange={(e) => setRegion(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && void load()}
              placeholder="np. śląskie, małopolskie…"
              style={{
                width: '100%',
                padding: '0.55rem 0.75rem 0.55rem 2rem',
                background: 'rgba(255,255,255,0.03)',
                border: '1px solid rgba(255,255,255,0.1)',
                borderRadius: 8,
                color: '#fff',
                fontSize: '0.9rem',
              }}
            />
          </div>
        </div>
      </div>

      {error && (
        <div
          style={{
            background: 'rgba(239,68,68,0.1)',
            border: '1px solid rgba(239,68,68,0.3)',
            borderRadius: 8,
            padding: '0.75rem 1rem',
            color: '#fca5a5',
            fontSize: '0.85rem',
            display: 'flex',
            alignItems: 'center',
            gap: 8,
          }}
        >
          <AlertTriangle size={16} />
          {error}
        </div>
      )}

      {loading && !view && (
        <p style={{ color: 'var(--text-muted)', fontSize: '0.9rem', display: 'flex', alignItems: 'center', gap: 8 }}>
          <Loader2 size={16} className="spin" /> Liczenie kaskady ścieżek…
        </p>
      )}

      {cards.length > 0 && (
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: compact
              ? '1fr'
              : 'repeat(auto-fit, minmax(200px, 1fr))',
            gap: '0.65rem',
          }}
          data-testid="strategy-path-cards"
        >
          {cards.map((path) => {
            const blocked = isBlockedPath(path);
            const isPrimary = Boolean(path.primary);
            const isSelected = selectedId === path.id;
            return (
              <button
                key={path.id}
                type="button"
                data-testid={`strategy-path-${path.id}`}
                data-primary={isPrimary ? 'true' : 'false'}
                data-blocked={blocked ? 'true' : 'false'}
                onClick={() => handleSelect(path)}
                disabled={blocked}
                style={{
                  textAlign: 'left',
                  cursor: blocked ? 'not-allowed' : 'pointer',
                  opacity: blocked ? 0.55 : 1,
                  background: isPrimary
                    ? 'rgba(16,185,129,0.08)'
                    : isSelected
                      ? 'rgba(59,130,246,0.08)'
                      : 'rgba(255,255,255,0.025)',
                  border: isPrimary
                    ? '1px solid rgba(16,185,129,0.45)'
                    : isSelected
                      ? '1px solid rgba(59,130,246,0.45)'
                      : blocked
                        ? '1px dashed rgba(239,68,68,0.35)'
                        : '1px solid rgba(255,255,255,0.06)',
                  borderRadius: 12,
                  padding: compact ? '0.7rem 0.8rem' : '0.85rem 1rem',
                  color: 'inherit',
                  display: 'flex',
                  flexDirection: 'column',
                  gap: '0.45rem',
                  boxShadow: isPrimary ? '0 0 16px rgba(16,185,129,0.12)' : 'none',
                }}
              >
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <div
                      style={{
                        padding: 8,
                        borderRadius: 10,
                        background: 'rgba(255,255,255,0.06)',
                        display: 'flex',
                      }}
                    >
                      {pathIcon(path.id)}
                    </div>
                    <div>
                      <div style={{ fontWeight: 700, fontSize: '0.88rem', lineHeight: 1.3 }}>
                        {path.label}
                      </div>
                      <div style={{ fontSize: '0.7rem', color: 'var(--text-muted)', marginTop: 2 }}>
                        {path.id}
                      </div>
                    </div>
                  </div>
                  <div
                    style={{
                      fontSize: '0.75rem',
                      fontWeight: 700,
                      padding: '2px 8px',
                      borderRadius: 6,
                      background: isPrimary ? 'rgba(16,185,129,0.2)' : 'rgba(255,255,255,0.06)',
                      color: isPrimary ? '#6ee7b7' : 'var(--text-secondary)',
                      flexShrink: 0,
                    }}
                  >
                    {formatScore(path.score)}
                  </div>
                </div>

                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                  {isPrimary && (
                    <span
                      style={{
                        fontSize: '0.68rem',
                        fontWeight: 700,
                        background: 'rgba(16,185,129,0.2)',
                        color: '#6ee7b7',
                        padding: '2px 7px',
                        borderRadius: 999,
                        display: 'inline-flex',
                        alignItems: 'center',
                        gap: 4,
                      }}
                    >
                      <CheckCircle2 size={11} /> Primary
                    </span>
                  )}
                  {blocked && (
                    <span
                      style={{
                        fontSize: '0.68rem',
                        fontWeight: 700,
                        background: 'rgba(239,68,68,0.18)',
                        color: '#fca5a5',
                        padding: '2px 7px',
                        borderRadius: 999,
                        display: 'inline-flex',
                        alignItems: 'center',
                        gap: 4,
                      }}
                    >
                      <AlertTriangle size={11} /> de minimis blocked
                    </span>
                  )}
                  {!blocked && view?.recommendedPathIds.includes(path.id) && !isPrimary && (
                    <span
                      style={{
                        fontSize: '0.68rem',
                        color: '#93c5fd',
                        background: 'rgba(59,130,246,0.12)',
                        padding: '2px 7px',
                        borderRadius: 999,
                      }}
                    >
                      recommended
                    </span>
                  )}
                  {hasTaxChecklists(path) &&
                    (path.checklist_ids || []).map((cid) => (
                      <span
                        key={cid}
                        data-testid={`tax-checklist-${cid}`}
                        title={
                          cid === 'psi' && path.never_say_submit_to_parp
                            ? 'PSI — nie składaj do PARP (decyzja strefowa)'
                            : `Checklist: ${formatTaxChecklistId(cid)}`
                        }
                        style={{
                          fontSize: '0.65rem',
                          fontWeight: 600,
                          color: '#c4b5fd',
                          background: 'rgba(167,139,250,0.14)',
                          border: '1px solid rgba(167,139,250,0.28)',
                          padding: '2px 7px',
                          borderRadius: 999,
                        }}
                      >
                        {formatTaxChecklistId(cid)}
                      </span>
                    ))}
                </div>

                {hasTaxChecklists(path) && path.never_say_submit_to_parp && !compact && (
                  <div
                    data-testid="tax-psi-no-parp"
                    style={{
                      fontSize: '0.7rem',
                      color: '#c4b5fd',
                      lineHeight: 1.35,
                      opacity: 0.95,
                    }}
                  >
                    PSI: nie składaj do PARP — decyzja strefowa / ulga, nie nabór.
                  </div>
                )}

                {path.reasons.slice(0, compact ? 1 : 2).map((r, i) => (
                  <div
                    key={i}
                    style={{
                      fontSize: '0.75rem',
                      color: 'var(--text-secondary)',
                      lineHeight: 1.4,
                    }}
                  >
                    {r}
                  </div>
                ))}
              </button>
            );
          })}
        </div>
      )}

      {!loading && view && cards.length === 0 && (
        <p style={{ color: 'var(--text-muted)', fontSize: '0.85rem' }}>
          Brak ścieżek strategii — spróbuj odświeżyć lub uzupełnij cel/region.
        </p>
      )}

      {view?.notes && view.notes.length > 0 && !compact && (
        <ul
          style={{
            margin: 0,
            paddingLeft: '1.1rem',
            color: 'var(--text-muted)',
            fontSize: '0.75rem',
            lineHeight: 1.5,
          }}
        >
          {view.notes.map((n, i) => (
            <li key={i}>{n}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default StrategyCascadePanel;
