import { useState, useEffect } from "react";
import { Link } from "react-router";
import Navbar from "../components/Navbar";
import type { TradingDecision } from "../types/agents";

interface Indicators {
  rsi: number | null;
  sma20: number | null;
  sma50: number | null;
  ema12: number | null;
  ema26: number | null;
  macd: number | null;
  bbUpper: number | null;
  bbMiddle: number | null;
  bbLower: number | null;
  atr: number | null;
  avgVolume: number | null;
}

interface StockRow {
  id: string;
  ticker: string;
  currentPrice: number | null;
  position: number;
  indicators: Indicators;
  analysis: TradingDecision | null;
  loading: boolean;
  indicatorsLoading: boolean;
}

export const meta = () => [
  { title: "Portfolio Analysis - AITrader" },
  { name: "description", content: "Analyze your stock portfolio with AI trading insights" },
];

function RsiBadge({ value }: { value: number }) {
  const color = value > 70 ? "bg-red-100 text-red-700" : value < 30 ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-700";
  const label = value > 70 ? "Overbought" : value < 30 ? "Oversold" : "Neutral";
  return <span className={`px-1.5 py-0.5 rounded text-xs font-medium ${color}`}>{value.toFixed(0)} {label}</span>;
}

function MacdBadge({ value }: { value: number }) {
  const color = value > 0 ? "text-green-600" : "text-red-600";
  return <span className={`text-xs font-medium ${color}`}>{value > 0 ? "▲" : "▼"} {value.toFixed(2)}</span>;
}

function PriceVsSma({ price, sma, label }: { price: number; sma: number; label: string }) {
  if (!price || !sma) return <span className="text-xs text-gray-400">-</span>;
  const above = price > sma;
  const pct = ((price - sma) / sma * 100).toFixed(1);
  return (
    <span className={`text-xs ${above ? "text-green-600" : "text-red-600"}`}>
      {above ? "▲" : "▼"} {pct}%
    </span>
  );
}

function SignalSummary({ price, indicators }: { price: number | null; indicators: Indicators }) {
  if (!price) return <span className="text-xs text-gray-400">No data</span>;

  const signals: string[] = [];

  if (indicators.rsi != null) {
    if (indicators.rsi > 70) signals.push("RSI overbought");
    else if (indicators.rsi < 30) signals.push("RSI oversold");
  }

  if (indicators.sma20 != null && indicators.sma50 != null) {
    if (indicators.sma20 > indicators.sma50) signals.push("SMA bullish cross");
    else signals.push("SMA bearish cross");
  }

  if (indicators.macd != null) {
    if (indicators.macd > 0) signals.push("MACD positive");
    else signals.push("MACD negative");
  }

  if (indicators.bbUpper != null && indicators.bbLower != null) {
    if (price > indicators.bbUpper) signals.push("Above BB upper");
    else if (price < indicators.bbLower) signals.push("Below BB lower");
  }

  if (signals.length === 0) return <span className="text-xs text-gray-400">-</span>;

  const bullish = signals.filter(s => s.includes("oversold") || s.includes("bullish") || s.includes("positive") || s.includes("Below BB")).length;
  const bearish = signals.filter(s => s.includes("overbought") || s.includes("bearish") || s.includes("negative") || s.includes("Above BB")).length;
  const net = bullish - bearish;
  const bias = net > 0 ? "bullish" : net < 0 ? "bearish" : "neutral";
  const biasColor = bias === "bullish" ? "text-green-600" : bias === "bearish" ? "text-red-600" : "text-gray-500";

  return (
    <div>
      <span className={`text-xs font-semibold capitalize ${biasColor}`}>{bias}</span>
      <div className="text-xs text-gray-500 mt-0.5 space-y-0.5">
        {signals.slice(0, 3).map((s, i) => <div key={i}>{s}</div>)}
      </div>
    </div>
  );
}

function IndicatorsPopover({ indicators, price, visible, onClose }: { indicators: Indicators; price: number | null; visible: boolean; onClose: () => void }) {
  if (!visible) return null;

  const rows = [
    { label: "RSI (14)", value: indicators.rsi != null ? <RsiBadge value={indicators.rsi} /> : "-" },
    { label: "SMA 20", value: indicators.sma20 != null ? `${indicators.sma20.toFixed(2)}` : "-" },
    { label: "SMA 50", value: indicators.sma50 != null ? `${indicators.sma50.toFixed(2)}` : "-" },
    { label: "EMA 12", value: indicators.ema12 != null ? `${indicators.ema12.toFixed(2)}` : "-" },
    { label: "EMA 26", value: indicators.ema26 != null ? `${indicators.ema26.toFixed(2)}` : "-" },
    { label: "MACD", value: indicators.macd != null ? <MacdBadge value={indicators.macd} /> : "-" },
    { label: "BB Upper", value: indicators.bbUpper != null ? `$${indicators.bbUpper.toFixed(2)}` : "-" },
    { label: "BB Middle", value: indicators.bbMiddle != null ? `$${indicators.bbMiddle.toFixed(2)}` : "-" },
    { label: "BB Lower", value: indicators.bbLower != null ? `$${indicators.bbLower.toFixed(2)}` : "-" },
    { label: "ATR (14)", value: indicators.atr != null ? `$${indicators.atr.toFixed(2)}` : "-" },
    { label: "Avg Vol (20)", value: indicators.avgVolume != null ? indicators.avgVolume.toFixed(0) : "-" },
  ];

  return (
    <>
      <div className="fixed inset-0 z-40" onClick={onClose} />
      <div className="absolute z-50 left-0 top-full mt-1 w-64 bg-white rounded-lg shadow-xl border border-gray-200 p-3">
        <h4 className="text-xs font-semibold text-gray-700 mb-2">Technical Indicators</h4>
        <div className="space-y-1">
          {rows.map((r) => (
            <div key={r.label} className="flex justify-between text-xs">
              <span className="text-gray-500">{r.label}</span>
              <span className="text-gray-900 font-medium">{r.value}</span>
            </div>
          ))}
        </div>
        {price && indicators.sma20 && indicators.sma50 && (
          <div className="mt-2 pt-2 border-t border-gray-100 space-y-1">
            <div className="flex justify-between text-xs">
              <span className="text-gray-500">Price vs SMA20</span>
              <PriceVsSma price={price} sma={indicators.sma20} label="SMA20" />
            </div>
            <div className="flex justify-between text-xs">
              <span className="text-gray-500">Price vs SMA50</span>
              <PriceVsSma price={price} sma={indicators.sma50} label="SMA50" />
            </div>
          </div>
        )}
      </div>
    </>
  );
}

export default function Analyze() {
  const [stocks, setStocks] = useState<StockRow[]>([]);
  const [newTicker, setNewTicker] = useState("");

  useEffect(() => {
    const loadPortfolio = async () => {
      try {
        const [positionsRes, dbStocksRes] = await Promise.all([
          fetch("/api/alpaca/positions"),
          fetch("/api/stocks"),
        ]);

        const positions = positionsRes.ok ? await positionsRes.json() : [];
        const dbStocks = dbStocksRes.ok ? await dbStocksRes.json() : [];

        const alpacaTickers = new Set(positions.map((p: { ticker: string }) => p.ticker));

        const buildStock = async (ticker: string, qty: number) => {
          try {
            const quoteRes = await fetch(`/api/alpaca/quote/${ticker}`);
            const quote = quoteRes.ok ? await quoteRes.json() : null;
            return {
              id: `alpaca-${ticker}`,
              ticker,
              currentPrice: quote?.price ?? null,
              position: qty,
              indicators: { rsi: null, sma20: null, sma50: null, ema12: null, ema26: null, macd: null, bbUpper: null, bbMiddle: null, bbLower: null, atr: null, avgVolume: null },
              analysis: null,
              loading: false,
              indicatorsLoading: false,
            };
          } catch {
            return {
              id: `alpaca-${ticker}`,
              ticker,
              currentPrice: null,
              position: qty,
              indicators: { rsi: null, sma20: null, sma50: null, ema12: null, ema26: null, macd: null, bbUpper: null, bbMiddle: null, bbLower: null, atr: null, avgVolume: null },
              analysis: null,
              loading: false,
              indicatorsLoading: false,
            };
          }
        };

        const alpacaStocks = await Promise.all(
          positions.map((p: { ticker: string; qty: number }) => buildStock(p.ticker, p.qty))
        );

        const dbOnlyStocks = [];
        for (const stock of dbStocks) {
          if (!alpacaTickers.has(stock.ticker)) {
            dbOnlyStocks.push(await buildStock(stock.ticker, 0));
          }
        }

        setStocks([...alpacaStocks, ...dbOnlyStocks]);
      } catch (err) {
        console.error("[analyze] Portfolio load error:", err);
      }
    };

    loadPortfolio();
  }, []);

  // Auto-load indicators for stocks that don't have them yet (sequential with delay to avoid rate limits)
  useEffect(() => {
    const unloaded = stocks.filter((s) => !s.indicatorsLoading && s.indicators.rsi == null);
    if (unloaded.length === 0) return;

    let cancelled = false;
    const loadSequential = async () => {
      for (const stock of unloaded) {
        if (cancelled) break;
        setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: true } : st));
        const indicators = await loadIndicators(stock.ticker);
        if (cancelled) break;
        if (indicators) {
          setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicators, indicatorsLoading: false } : st));
        } else {
          setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: false } : st));
        }
        // 500ms delay between each stock to avoid rate limiting
        await new Promise((r) => setTimeout(r, 500));
      }
    };
    loadSequential();
    return () => { cancelled = true; };
  }, [stocks]);

  useEffect(() => {
    const interval = setInterval(() => {
      stocks.forEach((stock) => {
        fetch(`/api/alpaca/quote/${stock.ticker}`)
          .then((res) => res.ok ? res.json() : null)
          .then((data) => {
            if (data?.price) {
              setStocks((s) => s.map((st) =>
                st.ticker === stock.ticker ? { ...st, currentPrice: data.price } : st
              ));
            }
          })
          .catch(() => {});
      });
    }, 60000);

    return () => clearInterval(interval);
  }, [stocks]);

  const loadIndicators = async (ticker: string) => {
    try {
      const res = await fetch(`/api/indicators?symbol=${ticker}`);
      if (!res.ok) return null;
      const data = await res.json();
      const ind = data.indicators || {};
      return {
        rsi: ind.rsi ?? null,
        sma20: ind.sma ?? null,
        sma50: ind.sma50 ?? null,
        ema12: ind.ema12 ?? null,
        ema26: ind.ema26 ?? null,
        macd: ind.macd ?? null,
        bbUpper: ind.bbUpper ?? null,
        bbMiddle: ind.bbMiddle ?? null,
        bbLower: ind.bbLower ?? null,
        atr: ind.atr ?? null,
        avgVolume: ind.avgVolume ?? null,
      };
    } catch {
      return null;
    }
  };

  const addStock = async () => {
    if (!newTicker.trim()) return;
    const ticker = newTicker.trim().toUpperCase();

    if (stocks.some((s) => s.ticker === ticker)) return;

    try {
      const formData = new FormData();
      formData.append("ticker", ticker);
      await fetch("/api/stocks", { method: "POST", body: formData });
    } catch (err) {
      console.error("[analyze] Error saving stock:", err);
    }

    const newStock: StockRow = {
      id: `db-${ticker}`,
      ticker,
      currentPrice: null,
      position: 0,
      indicators: { rsi: null, sma20: null, sma50: null, ema12: null, ema26: null, macd: null, bbUpper: null, bbMiddle: null, bbLower: null, atr: null, avgVolume: null },
      analysis: null,
      loading: true,
      indicatorsLoading: true,
    };

    setStocks((s) => [...s, newStock]);
    setNewTicker("");

    try {
      const [quoteRes, positionsRes] = await Promise.all([
        fetch(`/api/alpaca/quote/${ticker}`),
        fetch("/api/alpaca/positions"),
      ]);

      const quote = quoteRes.ok ? await quoteRes.json() : null;
      const positions = positionsRes.ok ? await positionsRes.json() : [];
      const position = positions.find((p: { ticker: string }) => p.ticker === ticker)?.qty ?? 0;

      const indicators = await loadIndicators(ticker);

      setStocks((s) => s.map((st) =>
        st.ticker === ticker
          ? { ...st, loading: false, indicatorsLoading: false, currentPrice: quote?.price ?? null, position, indicators: indicators || st.indicators }
          : st
      ));
    } catch (err) {
      console.error("[analyze] Error adding stock:", err);
      setStocks((s) => s.map((st) => st.ticker === ticker ? { ...st, loading: false, indicatorsLoading: false } : st));
    }
  };

  useEffect(() => {
    if (stocks.length === 0) return;

    const updatePositions = async () => {
      try {
        const res = await fetch("/api/alpaca/positions");
        if (res.ok) {
          const positions = await res.json();
          setStocks((s) => s.map((st) => {
            const pos = positions.find((p: { ticker: string }) => p.ticker === st.ticker);
            return pos ? { ...st, position: pos.qty } : st;
          }));
        }
      } catch (err) {
        console.error("[analyze] Position update error:", err);
      }
    };

    updatePositions();
  }, [stocks.length]);

  const removeStock = async (id: string) => {
    const stock = stocks.find((s) => s.id === id);
    if (!stock) return;

    if (id.startsWith("db-")) {
      try {
        const formData = new FormData();
        formData.append("_method", "DELETE");
        formData.append("ticker", stock.ticker);
        const res = await fetch("/api/stocks", { method: "POST", body: formData });
        if (!res.ok) {
          console.error("[analyze] Delete API failed:", res.status);
          return;
        }
      } catch (err) {
        console.error("[analyze] Error deleting stock:", err);
        return;
      }
    }

    setStocks((s) => s.filter((st) => st.id !== id));
  };

  const runAnalysis = async (id: string, ticker: string) => {
    setStocks((s) => s.map((st) => st.id === id ? { ...st, loading: true } : st));

    try {
      const [quoteRes, indicatorsRes] = await Promise.all([
        fetch(`/api/alpaca/quote/${ticker}`),
        fetch(`/api/indicators?symbol=${ticker}`),
      ]);

      const quote = quoteRes.ok ? await quoteRes.json() : null;
      const indicatorsData = indicatorsRes.ok ? await indicatorsRes.json() : null;

      const analysisRes = await fetch("/api/analyze", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ticker }),
      });
      const analysis = analysisRes.ok ? await analysisRes.json() : null;

      const indicators: Indicators = {
        rsi: indicatorsData?.indicators?.rsi ?? null,
        sma20: indicatorsData?.indicators?.sma ?? null,
        sma50: indicatorsData?.indicators?.sma50 ?? null,
        ema12: indicatorsData?.indicators?.ema12 ?? null,
        ema26: indicatorsData?.indicators?.ema26 ?? null,
        macd: indicatorsData?.indicators?.macd ?? null,
        bbUpper: indicatorsData?.indicators?.bbUpper ?? null,
        bbMiddle: indicatorsData?.indicators?.bbMiddle ?? null,
        bbLower: indicatorsData?.indicators?.bbLower ?? null,
        atr: indicatorsData?.indicators?.atr ?? null,
        avgVolume: indicatorsData?.indicators?.avgVolume ?? null,
      };

      setStocks((s) => s.map((st) =>
        st.id === id
          ? { ...st, loading: false, currentPrice: quote?.price ?? null, indicators, analysis }
          : st
      ));
    } catch {
      setStocks((s) => s.map((st) => st.id === id ? { ...st, loading: false } : st));
    }
  };

  const loadAllIndicators = async () => {
    for (const stock of stocks) {
      setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: true } : st));
      const indicators = await loadIndicators(stock.ticker);
      if (indicators) {
        setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicators, indicatorsLoading: false } : st));
      } else {
        setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: false } : st));
      }
      await new Promise((r) => setTimeout(r, 500));
    }
  };

  const [openIndicatorId, setOpenIndicatorId] = useState<string | null>(null);

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 to-blue-50">
      <Navbar />
      <div className="mx-auto max-w-7xl px-6 py-8">
        <div className="flex items-center justify-between mb-6">
          <h1 className="text-3xl font-bold text-gray-900">Portfolio Analysis</h1>
          <button onClick={loadAllIndicators} className="text-sm text-blue-600 hover:underline font-medium">
            Refresh Indicators
          </button>
        </div>

        <div className="bg-white rounded-xl shadow-lg p-6 mb-6 border border-gray-200">
          <div className="flex gap-3 mb-4">
            <input
              type="text"
              value={newTicker}
              onChange={(e) => setNewTicker(e.target.value.toUpperCase())}
              placeholder="Add ticker (e.g. AAPL)"
              className="flex-1 border border-gray-300 rounded-lg px-4 py-2.5 text-gray-900 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500"
              onKeyDown={(e) => e.key === "Enter" && addStock()}
            />
            <button
              onClick={addStock}
              className="bg-blue-600 text-white px-6 py-2.5 rounded-lg font-medium hover:bg-blue-700 transition-colors"
            >
              Add Stock
            </button>
          </div>

          {stocks.length === 0 ? (
            <p className="text-gray-500 text-center py-8">No stocks added. Add a ticker to get started.</p>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead>
                  <tr className="border-b border-gray-200">
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">Ticker</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">Price</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">Position</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">Technical Summary</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">RSI</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">MACD</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">SMA 20/50</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">AI Analysis</th>
                    <th className="text-left py-3 px-3 font-medium text-gray-700 text-sm">Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {stocks.map((stock) => (
                    <tr key={stock.id} className="border-b border-gray-100 hover:bg-gray-50">
                      <td className="py-3 px-3">
                        <Link to={`/analyze/${stock.ticker}`} className="font-bold text-gray-900 text-blue-600 hover:underline">
                          {stock.ticker}
                        </Link>
                      </td>
                      <td className="py-3 px-3 text-gray-900 text-sm">
                        {stock.currentPrice ? `$${stock.currentPrice.toFixed(2)}` : "-"}
                      </td>
                      <td className="py-3 px-3 text-sm">
                        {stock.position > 0 ? (
                          <span className="font-medium text-green-600">{stock.position} shares</span>
                        ) : (
                          <span className="text-gray-400">-</span>
                        )}
                      </td>
                      <td className="py-3 px-3 relative">
                        <div className="flex items-center gap-2">
                          {stock.indicatorsLoading ? (
                            <span className="text-xs text-gray-400 animate-pulse">Loading...</span>
                          ) : (
                            <>
                              <SignalSummary price={stock.currentPrice} indicators={stock.indicators} />
                              <button
                                onClick={() => setOpenIndicatorId(openIndicatorId === stock.id ? null : stock.id)}
                                className="text-xs text-blue-600 hover:underline shrink-0"
                              >
                                Details
                              </button>
                            </>
                          )}
                        </div>
                        <IndicatorsPopover
                          indicators={stock.indicators}
                          price={stock.currentPrice}
                          visible={openIndicatorId === stock.id}
                          onClose={() => setOpenIndicatorId(null)}
                        />
                      </td>
                      <td className="py-3 px-3">
                        {stock.indicators.rsi != null ? (
                          <RsiBadge value={stock.indicators.rsi} />
                        ) : stock.indicatorsLoading ? (
                          <span className="text-xs text-gray-400">...</span>
                        ) : "-"}
                      </td>
                      <td className="py-3 px-3">
                        {stock.indicators.macd != null ? (
                          <MacdBadge value={stock.indicators.macd} />
                        ) : stock.indicatorsLoading ? (
                          <span className="text-xs text-gray-400">...</span>
                        ) : "-"}
                      </td>
                      <td className="py-3 px-3">
                        {stock.indicatorsLoading ? (
                          <span className="text-xs text-gray-400">...</span>
                        ) : stock.currentPrice && stock.indicators.sma20 && stock.indicators.sma50 ? (
                          <div className="space-y-0.5">
                            <PriceVsSma price={stock.currentPrice} sma={stock.indicators.sma20} label="SMA20" />
                            <PriceVsSma price={stock.currentPrice} sma={stock.indicators.sma50} label="SMA50" />
                          </div>
                        ) : "-"}
                      </td>
                      <td className="py-3 px-3">
                        {stock.analysis ? (
                          <div>
                            <span className={`font-semibold text-sm ${
                              stock.analysis.action === "buy" ? "text-green-600" :
                              stock.analysis.action === "sell" ? "text-red-600" : "text-gray-500"
                            }`}>
                              {stock.analysis.action.toUpperCase()}
                            </span>
                            <div className="text-xs text-gray-500">
                              {(stock.analysis.confidence ?? 0 * 100).toFixed(0)}%
                            </div>
                          </div>
                        ) : stock.loading ? (
                          <span className="text-xs text-blue-600">Analyzing...</span>
                        ) : "-"}
                      </td>
                      <td className="py-3 px-3">
                        <div className="flex gap-1.5">
                          <button
                            onClick={() => runAnalysis(stock.id, stock.ticker)}
                            disabled={stock.loading}
                            className="bg-blue-600 text-white px-2.5 py-1 rounded text-xs font-medium hover:bg-blue-700 disabled:opacity-50"
                          >
                            {stock.loading ? "..." : "Analyze"}
                          </button>
                          <button
                            onClick={async () => {
                              if (confirm(`Remove ${stock.ticker}?`)) await removeStock(stock.id);
                            }}
                            className="bg-red-600 text-white px-2.5 py-1 rounded text-xs font-medium hover:bg-red-700"
                          >
                            Delete
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
