import { Component, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
import Globe from 'react-globe.gl'
import { Color, MeshPhongMaterial } from 'three'

// isolate any 3D/WebGL failure so it can't blank the whole section
class GlobeBoundary extends Component<{ children: ReactNode; fallback: ReactNode }, { failed: boolean }> {
  state = { failed: false }
  static getDerivedStateFromError() { return { failed: true } }
  render() { return this.state.failed ? this.props.fallback : this.props.children }
}

interface Plant {
  n: string; o: string; par: string; c: string; s: string
  lat: number; lng: number; cap: number | null; st: string; m: string; y: string; u: string
}

const faNum = (n: number) => n.toLocaleString('fa-IR')
const faDigits = (s: string) => s.replace(/[0-9]/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[+d])

// production-method colors (match the GEM legend)
const METHOD_COLOR: Record<string, string> = {
  'Electric': '#22c55e',
  'Electric, oxygen': '#4f46e5',
  'Oxygen': '#f97316',
  'Induction': '#eab308',
  'Ironmaking (BF)': '#fb7185',
  'Integrated (BF & DRI)': '#8b5cf6',
  'Ironmaking (DRI)': '#38bdf8',
  'Integrated (DRI)': '#15803d',
  'Integrated (BF)': '#dc2626',
  'Integrated (unknown)': '#6b7280',
  'Steel other/unspecified': '#cbd5e1',
  'Iron other/unspecified': '#e5e7eb',
}
const METHOD_FA: Record<string, string> = {
  'Electric': 'کوره قوس الکتریکی (EAF)',
  'Electric, oxygen': 'الکتریک + اکسیژن',
  'Oxygen': 'کوره اکسیژنی (BOF)',
  'Induction': 'کوره القایی (IF)',
  'Ironmaking (BF)': 'آهن‌سازی (کوره بلند)',
  'Integrated (BF & DRI)': 'یکپارچه (BF و DRI)',
  'Ironmaking (DRI)': 'آهن‌سازی (DRI)',
  'Integrated (DRI)': 'یکپارچه (DRI)',
  'Integrated (BF)': 'یکپارچه (کوره بلند)',
  'Integrated (unknown)': 'یکپارچه (نامشخص)',
  'Steel other/unspecified': 'فولاد سایر/نامشخص',
  'Iron other/unspecified': 'آهن سایر/نامشخص',
}
const METHOD_ORDER = Object.keys(METHOD_COLOR)

const STATUS_FA: Record<string, string> = {
  operating: 'در حال بهره‌برداری',
  announced: 'اعلام‌شده',
  'operating pre-retirement': 'بهره‌برداری پیش از بازنشستگی',
  cancelled: 'لغوشده',
  construction: 'در حال ساخت',
  retired: 'بازنشسته',
  mothballed: 'تعطیل موقت',
}
const STATUS_ORDER = ['announced', 'construction', 'operating', 'operating pre-retirement', 'mothballed', 'retired', 'cancelled']
const STATUS_COLOR: Record<string, string> = {
  operating: '#16a34a', announced: '#d97706', 'operating pre-retirement': '#0891b2',
  construction: '#2563eb', mothballed: '#64748b', retired: '#94a3b8', cancelled: '#dc2626',
}

const COUNTRY_FA: Record<string, string> = {
  China: 'چین', India: 'هند', Iran: 'ایران', Russia: 'روسیه', Japan: 'ژاپن', 'United States': 'آمریکا',
  Italy: 'ایتالیا', Germany: 'آلمان', Turkey: 'ترکیه', 'Türkiye': 'ترکیه', Brazil: 'برزیل',
}

export default function SteelPlantsGlobe() {
  const [plants, setPlants] = useState<Plant[]>([])
  const [countries, setCountries] = useState<{ features: object[] } | null>(null)
  const [methodsOn, setMethodsOn] = useState<Set<string>>(new Set(METHOD_ORDER))
  const [statusOn, setStatusOn] = useState<Set<string>>(new Set(STATUS_ORDER))
  const [selected, setSelected] = useState<Plant | null>(null)
  const [dims, setDims] = useState({ w: 700, h: 560 })

  const wrapRef = useRef<HTMLDivElement>(null)
  const globeRef = useRef<any>(null)

  useEffect(() => {
    let alive = true
    fetch('/steel-plants.json').then((r) => r.json()).then((d) => { if (alive) setPlants(d) }).catch(() => {})
    fetch('/globe-countries.geojson').then((r) => r.json()).then((g) => { if (alive) setCountries(g) }).catch(() => {})
    return () => { alive = false }
  }, [])

  // light ocean sphere
  const globeMaterial = useMemo(() => new MeshPhongMaterial({ color: new Color('#bcd9f2'), emissive: new Color('#dcebf9'), emissiveIntensity: 0.25, shininess: 4 }), [])

  // measure container
  useEffect(() => {
    const el = wrapRef.current
    if (!el) return
    const ro = new ResizeObserver(() => {
      const w = el.clientWidth
      setDims({ w, h: Math.max(440, Math.min(620, w * 0.72)) })
    })
    ro.observe(el)
    return () => ro.disconnect()
  }, [])

  // autorotate
  useEffect(() => {
    const g = globeRef.current
    if (!g) return
    const c = g.controls()
    if (c) { c.autoRotate = true; c.autoRotateSpeed = 0.35; c.enableZoom = true }
  }, [plants, countries])

  const configControls = () => {
    const c = globeRef.current?.controls()
    if (c) { c.autoRotate = true; c.autoRotateSpeed = 0.35; c.enableZoom = true; c.enablePan = false }
  }

  const methodCounts = useMemo(() => {
    const m: Record<string, number> = {}
    plants.forEach((p) => { if (statusOn.has(p.st)) m[p.m] = (m[p.m] || 0) + 1 })
    return m
  }, [plants, statusOn])
  const statusCounts = useMemo(() => {
    const m: Record<string, number> = {}
    plants.forEach((p) => { if (methodsOn.has(p.m)) m[p.st] = (m[p.st] || 0) + 1 })
    return m
  }, [plants, methodsOn])

  const filtered = useMemo(() => plants.filter((p) => methodsOn.has(p.m) && statusOn.has(p.st)), [plants, methodsOn, statusOn])

  const countryRanking = useMemo(() => {
    const m: Record<string, number> = {}
    filtered.forEach((p) => { m[p.c] = (m[p.c] || 0) + 1 })
    return Object.entries(m).sort((a, b) => b[1] - a[1]).slice(0, 12)
  }, [filtered])

  const toggle = (set: Set<string>, key: string, setter: (s: Set<string>) => void) => {
    const next = new Set(set)
    next.has(key) ? next.delete(key) : next.add(key)
    setter(next)
  }

  return (
    <div style={{ background: '#fff', border: '1px solid #e2e6eb', borderRadius: 8, marginBottom: 16, overflow: 'hidden' }}>
      <div style={{ borderLeft: '3px solid #1e40af', padding: '12px 16px', background: '#f8fafc', borderBottom: '1px solid #e2e6eb', display: 'flex', alignItems: 'center', gap: 10, direction: 'rtl', flexWrap: 'wrap' }}>
        <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: '1.5px', textTransform: 'uppercase' as const, color: '#1e40af' }}>نقشه جهانی کارخانه‌های آهن و فولاد</span>
        <span style={{ fontSize: 11, color: '#94a3b8' }}>Global Iron & Steel Tracker · {faNum(plants.length)} کارخانه</span>
        <a href="https://globalenergymonitor.org/projects/global-iron-steel-tracker/" target="_blank" rel="noopener noreferrer" style={{ marginRight: 'auto', fontSize: 10, fontWeight: 700, color: '#1e40af', textDecoration: 'none' }}>منبع: GEM ↗</a>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 300px) 1fr', gap: 0 }} className="plants-globe-grid">
        {/* control panel */}
        <div style={{ padding: 16, direction: 'rtl', borderLeft: '1px solid #eef2f6', maxHeight: 640, overflowY: 'auto' }}>
          <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: 1, color: '#94a3b8' }}>کل کارخانه‌های انتخاب‌شده</div>
          <div style={{ fontSize: 30, fontWeight: 800, color: '#0f172a', fontFamily: 'Vazir, sans-serif', marginBottom: 14, lineHeight: 1 }}>{faNum(filtered.length)}</div>

          {/* production method */}
          <Section title="روش تولید" onAll={() => setMethodsOn(new Set(METHOD_ORDER))} onClear={() => setMethodsOn(new Set())} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 16 }}>
            {METHOD_ORDER.map((m) => (
              <Row key={m} on={methodsOn.has(m)} onClick={() => toggle(methodsOn, m, setMethodsOn)} dot={METHOD_COLOR[m]} label={METHOD_FA[m]} count={methodCounts[m] || 0} />
            ))}
          </div>

          {/* plant status */}
          <Section title="وضعیت کارخانه" onAll={() => setStatusOn(new Set(STATUS_ORDER))} onClear={() => setStatusOn(new Set())} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 16 }}>
            {STATUS_ORDER.map((s) => (
              <Row key={s} on={statusOn.has(s)} onClick={() => toggle(statusOn, s, setStatusOn)} dot={STATUS_COLOR[s]} label={STATUS_FA[s]} count={statusCounts[s] || 0} />
            ))}
          </div>

          {/* top countries */}
          <div style={{ fontSize: 11, fontWeight: 800, color: '#0f172a', marginBottom: 8 }}>کشورهای برتر</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
            {countryRanking.map(([c, n]) => {
              const max = countryRanking[0][1]
              return (
                <div key={c} style={{ position: 'relative', display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 8px', borderRadius: 5, background: '#f8fafc', overflow: 'hidden' }}>
                  <div style={{ position: 'absolute', top: 0, right: 0, bottom: 0, width: `${(n / max) * 100}%`, background: '#1e40af14' }} />
                  <span style={{ position: 'relative', fontSize: 11, color: '#334155' }}>{COUNTRY_FA[c] || c}</span>
                  <span style={{ position: 'relative', fontSize: 11, fontWeight: 800, color: '#1e40af', fontFamily: 'Vazir, sans-serif' }}>{faNum(n)}</span>
                </div>
              )
            })}
          </div>
        </div>

        {/* globe */}
        <div ref={wrapRef} style={{ position: 'relative', background: '#f3f4f6', minHeight: 460, overflow: 'hidden' }}>
          <GlobeBoundary fallback={<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#94a3b8', fontSize: 13, padding: 20, textAlign: 'center' }}>نمایش سه‌بعدی کره در این مرورگر در دسترس نیست.</div>}>
            <Globe
              ref={globeRef}
              width={dims.w}
              height={dims.h}
              backgroundColor="rgba(0,0,0,0)"
              onGlobeReady={configControls}
              globeMaterial={globeMaterial}
              showAtmosphere
              atmosphereColor="#9cc4f0"
              atmosphereAltitude={0.22}
              polygonsData={countries ? countries.features : []}
              polygonCapColor={() => 'rgba(228,233,239,0.95)'}
              polygonSideColor={() => 'rgba(150,180,220,0.12)'}
              polygonStrokeColor={() => '#8aa0b8'}
              polygonAltitude={0.006}
              pointsData={filtered}
              pointLat={(d: object) => (d as Plant).lat}
              pointLng={(d: object) => (d as Plant).lng}
              pointColor={(d: object) => METHOD_COLOR[(d as Plant).m] || '#94a3b8'}
              pointAltitude={(d: object) => 0.01 + Math.min(0.18, Math.sqrt((d as Plant).cap || 500) / 1400)}
              pointRadius={(d: object) => 0.18 + Math.min(0.5, Math.sqrt((d as Plant).cap || 500) / 600)}
              pointResolution={6}
              pointLabel={(d: object) => {
                const p = d as Plant
                return `<div style="background:#0f172a;color:#fff;padding:8px 11px;border-radius:8px;font-family:Vazir,sans-serif;direction:rtl;max-width:240px;border-top:3px solid ${METHOD_COLOR[p.m] || '#94a3b8'};box-shadow:0 8px 20px rgba(0,0,0,.3)">
                  <div style="font-weight:800;font-size:12px;margin-bottom:4px">${p.n}</div>
                  <div style="font-size:10px;color:#cbd5e1">${COUNTRY_FA[p.c] || p.c} · ${p.s || ''}</div>
                  <div style="font-size:10px;margin-top:5px">روش: <b style="color:${METHOD_COLOR[p.m] || '#fff'}">${METHOD_FA[p.m] || p.m}</b></div>
                  <div style="font-size:10px">ظرفیت: <b style="color:#CD9E53">${p.cap ? faNum(p.cap) + ' هزار تن' : '—'}</b> · ${STATUS_FA[p.st] || p.st}</div>
                </div>`
              }}
              onPointClick={(d: object) => setSelected(d as Plant)}
            />
          </GlobeBoundary>
          {(!plants.length || !countries) && (
            <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#64748b', fontSize: 13 }}>در حال بارگذاری کره زمین…</div>
          )}

          {/* selected plant detail */}
          {selected && (
            <div style={{ position: 'absolute', bottom: 14, right: 14, maxWidth: 280, background: '#0f172a', color: '#fff', borderRadius: 10, padding: '12px 14px', direction: 'rtl', borderTop: `3px solid ${METHOD_COLOR[selected.m] || '#94a3b8'}`, boxShadow: '0 14px 36px rgba(0,0,0,0.35)', zIndex: 5 }}>
              <button onClick={() => setSelected(null)} style={{ position: 'absolute', top: 8, left: 8, background: 'rgba(255,255,255,0.1)', border: 'none', color: '#fff', borderRadius: '50%', width: 22, height: 22, cursor: 'pointer', fontSize: 13 }}>×</button>
              <div style={{ fontWeight: 800, fontSize: 13, marginBottom: 5, paddingLeft: 20 }}>{selected.n}</div>
              <div style={{ fontSize: 10, color: '#94a3b8', marginBottom: 8 }}>{selected.o}</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5, marginBottom: 8 }}>
                <span style={{ fontSize: 9, fontWeight: 700, background: METHOD_COLOR[selected.m] || '#475569', color: '#fff', padding: '2px 8px', borderRadius: 99 }}>{METHOD_FA[selected.m] || selected.m}</span>
                <span style={{ fontSize: 9, fontWeight: 700, background: `${STATUS_COLOR[selected.st]}33`, color: STATUS_COLOR[selected.st], padding: '2px 8px', borderRadius: 99 }}>{STATUS_FA[selected.st] || selected.st}</span>
              </div>
              <div style={{ fontSize: 11, color: '#cbd5e1', lineHeight: 1.8 }}>
                کشور: {COUNTRY_FA[selected.c] || selected.c} · {selected.s}<br />
                ظرفیت: <b style={{ color: '#CD9E53' }}>{selected.cap ? `${faNum(selected.cap)} هزار تن/سال` : '—'}</b><br />
                سال راه‌اندازی: {selected.y ? faDigits(selected.y) : '—'}
              </div>
              <a href={selected.u} target="_blank" rel="noopener noreferrer" style={{ display: 'inline-block', marginTop: 8, fontSize: 10, fontWeight: 700, color: '#7cc4ff', textDecoration: 'none' }}>جزئیات در GEM ↗</a>
            </div>
          )}
        </div>
      </div>

      <div style={{ padding: '8px 16px', borderTop: '1px solid #eef2f6', background: '#f8fafc', fontSize: 10, color: '#94a3b8', direction: 'rtl' }}>
        روی هر نقطه نگه دارید یا کلیک کنید برای جزئیات · با اسکرول زوم کنید · کره به‌صورت خودکار می‌چرخد
      </div>
    </div>
  )
}

function Section({ title, onAll, onClear }: { title: string; onAll: () => void; onClear: () => void }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
      <span style={{ fontSize: 12, fontWeight: 800, color: '#0f172a' }}>{title}</span>
      <span style={{ fontSize: 9, color: '#94a3b8' }}>
        <button onClick={onAll} style={linkBtn}>همه</button> · <button onClick={onClear} style={linkBtn}>هیچ</button>
      </span>
    </div>
  )
}
const linkBtn: React.CSSProperties = { background: 'none', border: 'none', color: '#1e40af', cursor: 'pointer', fontSize: 9, padding: 0, fontFamily: 'inherit' }

function Row({ on, onClick, dot, label, count }: { on: boolean; onClick: () => void; dot: string; label: string; count: number }) {
  return (
    <button onClick={onClick} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 6px', borderRadius: 6, border: 'none', background: on ? 'transparent' : '#f1f5f9', cursor: 'pointer', fontFamily: 'inherit', opacity: on ? 1 : 0.55, transition: 'all 0.15s', width: '100%', textAlign: 'right' }}>
      <span style={{ width: 14, height: 14, borderRadius: 4, border: `2px solid ${dot}`, background: on ? dot : 'transparent', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 9, color: '#fff' }}>{on ? '✓' : ''}</span>
      <span style={{ flex: 1, fontSize: 11, color: '#334155' }}>{label}</span>
      <span style={{ fontSize: 11, fontWeight: 700, color: '#64748b', fontFamily: 'Vazir, sans-serif' }}>{count.toLocaleString('fa-IR')}</span>
    </button>
  )
}
