import { useState, useEffect, useCallback } from 'react';
import type { ChangeEvent } from 'react';
import { SlidersHorizontal, Search, RefreshCw } from 'lucide-react';
import { useAppContext } from '../context/AppContext';
import { useNavigate } from 'react-router-dom';
import { getPlatformAccessToken } from '../lib/authSession';
import { tradingRuntime } from '../lib/runtime';
import { createRequestId } from '../../../shared/request-id.js';
import { SkeletonBlock } from '../components/Skeleton';
import { PageHeader } from '../components/ui/page-header';
import { Button, Input, Select } from '../components/ui/Primitives';
import { Card, CardContent } from '../components/ui/card';

// ─── Types ────────────────────────────────────────────────────────────────────
interface ScreenerRow {
  symbol:        string;
  companyName:   string;
  price:         number;
  changesPercentage: number;
  marketCap:     number;
  pe:            number | null;
  sector:        string;
  volume:        number;
}

const SECTORS = [
  'All', 'Technology', 'Financial Services', 'Healthcare', 'Consumer Cyclical',
  'Consumer Defensive', 'Industrials', 'Energy', 'Utilities', 'Real Estate',
  'Communication Services', 'Basic Materials',
];

const CAP_OPTIONS: { label: string; min: number; max?: number }[] = [
  { label: 'Any Cap', min: 0 },
  { label: 'Mega (>$200B)', min: 200_000_000_000 },
  { label: 'Large ($10B–$200B)', min: 10_000_000_000, max: 200_000_000_000 },
  { label: 'Mid ($2B–$10B)', min: 2_000_000_000, max: 10_000_000_000 },
  { label: 'Small (<$2B)', min: 0, max: 2_000_000_000 },
];

const fmtCap = (n: number) => {
  if (n >= 1e12) return `$${(n / 1e12).toFixed(1)}T`;
  if (n >= 1e9)  return `$${(n / 1e9).toFixed(1)}B`;
  if (n >= 1e6)  return `$${(n / 1e6).toFixed(1)}M`;
  return `$${n.toLocaleString()}`;
};

// ─── Screener fetch ───────────────────────────────────────────────────────────
async function runScreener(params: {
  sector: string;
  marketCapMore?: number;
  marketCapLess?: number;
  limit: number;
}): Promise<ScreenerRow[]> {
  const token = await getPlatformAccessToken();
  const qs = new URLSearchParams({ limit: String(params.limit) });
  if (params.sector && params.sector !== 'All') qs.set('sector', params.sector);
  if (params.marketCapMore) qs.set('marketCapMoreThan', String(params.marketCapMore));
  if (params.marketCapLess) qs.set('marketCapLessThan', String(params.marketCapLess));

  const res = await fetch(`${tradingRuntime.tradingApiUrl}/api/screener?${qs}`, {
    headers: {
      Authorization:  `Bearer ${token}`,
      'x-request-id': createRequestId('web-screener'),
    },
  });
  if (!res.ok) {
    const body = await res.json().catch(() => ({})) as any;
    throw new Error(body?.error ?? `Screener failed (${res.status})`);
  }
  const data = await res.json() as any;
  return Array.isArray(data) ? data : (data.results ?? []);
}

// ─── ScreenerView ─────────────────────────────────────────────────────────────
export function ScreenerView() {
  const { setActiveSymbol } = useAppContext();
  const navigate = useNavigate();

  const [results,  setResults]  = useState<ScreenerRow[]>([]);
  const [loading,  setLoading]  = useState(false);
  const [error,    setError]    = useState<string | null>(null);
  const [query,    setQuery]    = useState('');
  const [sector,   setSector]   = useState('All');
  const [capIdx,   setCapIdx]   = useState(0);
  const [sortKey,  setSortKey]  = useState<keyof ScreenerRow>('marketCap');
  const [sortAsc,  setSortAsc]  = useState(false);

  const fetchResults = useCallback(async () => {
    setLoading(true);
    setError(null);
    const cap = CAP_OPTIONS[capIdx];
    try {
      const rows = await runScreener({
        sector,
        marketCapMore: cap.min > 0 ? cap.min : undefined,
        marketCapLess: cap.max,
        limit: 50,
      });
      setResults(rows);
    } catch (e: any) {
      setError(e?.message ?? 'Screener request failed');
    } finally {
      setLoading(false);
    }
  }, [sector, capIdx]);

  // Fetch on mount and when filters change
  useEffect(() => { fetchResults(); }, [fetchResults]);

  // Client-side search filter + sort
  const filtered = results
    .filter(r => {
      if (!query) return true;
      const q = query.toUpperCase();
      return r.symbol?.includes(q) || r.companyName?.toLowerCase().includes(query.toLowerCase());
    })
    .sort((a, b) => {
      const av = a[sortKey] as any ?? 0;
      const bv = b[sortKey] as any ?? 0;
      return sortAsc ? (av > bv ? 1 : -1) : (av < bv ? 1 : -1);
    });

  const handleSort = (key: keyof ScreenerRow) => {
    if (sortKey === key) setSortAsc(p => !p);
    else { setSortKey(key); setSortAsc(false); }
  };

  const SortIcon = ({ k }: { k: keyof ScreenerRow }) => (
    <span className="screener-sort-icon" data-active={sortKey === k}>
      {sortKey === k ? (sortAsc ? '▲' : '▼') : '⇅'}
    </span>
  );
  const moreSectorSelected = SECTORS.indexOf(sector) >= 6;

  const ScreenerSkeletonRows = () => (
    <div role="status" aria-label="Loading screener results">
      {Array.from({ length: 6 }).map((_, i) => (
        <div
          key={i}
          style={{
            display: 'grid',
            gridTemplateColumns: '100px 1fr 90px 90px 110px 80px 110px',
            padding: '12px 16px',
            borderBottom: i < 5 ? '1px solid var(--border)' : 'none',
            alignItems: 'center',
            columnGap: 0,
          }}
        >
          <SkeletonBlock width={54} height={13} />
          <SkeletonBlock width={`${72 - (i % 3) * 8}%`} height={12} />
          <SkeletonBlock width={58} height={12} />
          <SkeletonBlock width={50} height={12} />
          <SkeletonBlock width={74} height={12} />
          <SkeletonBlock width={38} height={12} />
          <SkeletonBlock width={68} height={12} />
        </div>
      ))}
    </div>
  );

  const handleRowClick = (symbol: string) => {
    setActiveSymbol(symbol);
    navigate('/');
  };

  return (
    <div className="ux-page-stack">
      <PageHeader
        title="Stock Screener"
        description="Filter liquid names by sector and market cap, then jump directly into charting and research."
        action={
          <Button onClick={fetchResults} disabled={loading} variant="outline" size="sm">
            <RefreshCw size={13} style={{ animation: loading ? 'spin 1s linear infinite' : 'none' }} />
            Refresh
          </Button>
        }
      />

      <Card className="screener-filter-card">
        <CardContent>
          <div className="screener-filter-row">
            <div className="screener-search-field">
              <Search size={14} className="screener-search-icon" />
              <Input
                type="text"
                placeholder="Filter by name or ticker…"
                value={query}
                onChange={(e: ChangeEvent<HTMLInputElement>) => setQuery(e.target.value)}
                className="screener-search-input"
              />
            </div>

            <Select
              value={String(capIdx)}
              onChange={(e: ChangeEvent<HTMLSelectElement>) => setCapIdx(Number(e.target.value))}
              className="screener-cap-select"
              options={CAP_OPTIONS.map((c, i) => ({ value: String(i), label: c.label }))}
            />

            <div className="screener-sector-row">
              <SlidersHorizontal size={13} color="var(--muted-foreground)" />
          {SECTORS.slice(0, 6).map(s => (
            <Button
              key={s}
              onClick={() => setSector(s)}
              variant={sector === s ? 'secondary' : 'outline'}
              size="sm"
              className="screener-sector-chip"
              data-active={sector === s}
            >
              {s}
            </Button>
          ))}
              <Select
                aria-label="More sectors"
                value={SECTORS.indexOf(sector) >= 6 ? sector : ''}
                onChange={(e: ChangeEvent<HTMLSelectElement>) => e.target.value && setSector(e.target.value)}
                options={[
                  { value: '', label: 'More sectors…' },
                  ...SECTORS.slice(6).map(s => ({ value: s, label: s })),
                ]}
                className="screener-more-select"
                data-active={moreSectorSelected}
              />
            </div>
          </div>
        </CardContent>
      </Card>

      {error && !loading && (
        <div className="ux-alert">
          {error}
        </div>
      )}

      <div className="ux-data-grid">
        <div className="ux-data-grid-header screener-results-grid">
          {([
            ['symbol', 'Symbol'],
            ['companyName', 'Company'],
            ['price', 'Price'],
            ['changesPercentage', 'Change %'],
            ['marketCap', 'Market Cap'],
            ['pe', 'P/E'],
            ['volume', 'Volume'],
          ] as [keyof ScreenerRow, string][]).map(([key, label]) => (
            <Button
              type="button"
              key={key}
              onClick={() => handleSort(key)}
              variant="ghost"
              size="sm"
              className="ux-data-grid-head screener-sort-button"
            >
              {label}<SortIcon k={key} />
            </Button>
          ))}
        </div>

        {loading && <ScreenerSkeletonRows />}

        {!loading && filtered.map((row) => (
          <div
            key={row.symbol}
            onClick={() => handleRowClick(row.symbol)}
            onKeyDown={(event) => {
              if (event.key === 'Enter' || event.key === ' ') {
                event.preventDefault();
                handleRowClick(row.symbol);
              }
            }}
            className="ux-data-grid-row screener-results-grid"
            role="button"
            tabIndex={0}
          >
            <span className="ux-data-grid-cell screener-symbol-cell">{row.symbol}</span>
            <span className="ux-data-grid-cell">{row.companyName}</span>
            <span className="ux-data-grid-cell screener-price-cell">
              {row.price != null ? `$${row.price.toFixed(2)}` : '—'}
            </span>
            <span className={`screener-change-cell ${row.changesPercentage >= 0 ? 'is-positive' : 'is-negative'}`}>
              {row.changesPercentage >= 0 ? '+' : ''}{row.changesPercentage?.toFixed(2)}%
            </span>
            <span className="ux-data-grid-cell">
              {row.marketCap ? fmtCap(row.marketCap) : '—'}
            </span>
            <span className="ux-data-grid-cell">
              {row.pe != null && row.pe > 0 ? row.pe.toFixed(1) : '—'}
            </span>
            <span className="ux-data-grid-cell">
              {row.volume ? fmtCap(row.volume).replace('$', '') : '—'}
            </span>
          </div>
        ))}

        {!loading && filtered.length === 0 && !error && (
          <div className="ux-empty-state" style={{ border: 0, borderRadius: 0 }}>
            <div>
              <strong>No results match your filters</strong>
              <span>Adjust the query, sector, or market cap filter.</span>
            </div>
          </div>
        )}
      </div>

      {!loading && filtered.length > 0 && (
        <div className="screener-results-summary">
          {filtered.length} companies · Click any row to view chart & research
        </div>
      )}
    </div>
  );
}
