import { useState, useEffect, useCallback } from 'react';
import { MapContainer, TileLayer } from 'react-leaflet';
import NodeMarkers from './components/NodeMarkers';
import Sidebar from './components/Sidebar';
import SeismicSection from './SeismicSection';
import H5Coverage from './components/H5Coverage';
import DataDocumentation from './components/DataDocumentation';
import H5Dashboard from './components/H5Dashboard';
import CampaignDocs from "./components/CampaignDocs";
import { Node, DataWindow } from './types';

const API_BASE = '/seismic/api';
const DEFAULT_CENTER: [number, number] = [43.40, 3.70];

function App() {
  const [nodes, setNodes] = useState<Node[]>([]);
  const [dates, setDates] = useState<string[]>([]);
  const [selectedDate, setSelectedDate] = useState<string>('');
  const [selectedChannel, setSelectedChannel] = useState<string>('ch0');
  const [selectedNode, setSelectedNode] = useState<Node | null>(null);
  const [currentTime, setCurrentTime] = useState<number>(0);
  const [dataWindow, setDataWindow] = useState<DataWindow | null>(null);
  const [loading, setLoading] = useState(true);
  const [sampleRate, setSampleRate] = useState(200);
  const [showOnlyWithData, setShowOnlyWithData] = useState(false);
  const [rmsTimeline, setRmsTimeline] = useState<any>(null);
  const [allAdcValues, setAllAdcValues] = useState<Record<string, number>>({});
  const [isPlaying, setIsPlaying] = useState(false);
  const [playSpeed, setPlaySpeed] = useState(1);
  const [chatOpen, setChatOpen] = useState(false);
  const [chatMsg, setChatMsg] = useState('');
  const [chatHistory, setChatHistory] = useState<any[]>([]);
  const [showSection, setShowSection] = useState(false);
  const [showDashboard, setShowDashboard] = useState(false);
  const [showCampaignDocs, setShowCampaignDocs] = useState(false);
  const [showDocumentation, setShowDocumentation] = useState(false);
  const [showCoverage, setShowCoverage] = useState(false);
  const [migrationStatus, setMigrationStatus] = useState<any>(null);

  // 🔗 Deep-linking: Lire les paramètres URL au démarrage
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    
    const urlDate = params.get('date');
    const urlChannel = params.get('channel');
    const urlTime = params.get('time');
    const urlNode = params.get('node');
    
    if (urlDate) setSelectedDate(urlDate);
    if (urlChannel) setSelectedChannel(urlChannel);
    if (urlTime) setCurrentTime(parseFloat(urlTime));
    if (urlNode && nodes.length > 0) {
      const node = nodes.find(n => n.id === urlNode);
      if (node) setSelectedNode(node);
    }
  }, [nodes]); // Se déclenche quand les nodes sont chargés

  // 🔗 Deep-linking: Synchroniser l'URL quand les états changent
  useEffect(() => {
    const params = new URLSearchParams();
    
    if (selectedDate) params.set('date', selectedDate);
    if (selectedChannel) params.set('channel', selectedChannel);
    if (currentTime > 1000000) params.set('time', currentTime.toString());
    if (selectedNode) params.set('node', selectedNode.id);
    
    const newUrl = `${window.location.pathname}?${params.toString()}`;
    window.history.pushState({}, '', newUrl);
  }, [selectedDate, selectedChannel, currentTime, selectedNode]);

  useEffect(() => {
    fetch(`${API_BASE}/nodes`).then(r => r.json()).then(data => {
      setNodes(data.nodes || []);
      setSampleRate(data.sampleRateHz || 200);
      setLoading(false);
    });
  }, []);

  useEffect(() => {
    fetch(`${API_BASE}/dates`).then(r => r.json()).then(data => {
      const dateList = data.dates || [];
      setDates(dateList);
      if (dateList.length > 0 && !selectedDate) setSelectedDate(dateList[dateList.length - 1]);
    });
  }, []);

  // Polling de la migration
  useEffect(() => {
    const checkStatus = () => {
      fetch(`${API_BASE}/migration-status`)
        .then(r => r.json())
        .then(data => setMigrationStatus(data))
        .catch(() => {});
    };
    const interval = setInterval(checkStatus, 5000);
    checkStatus();
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    if (!selectedDate || !selectedChannel) return;
    setRmsTimeline(null);
    fetch(`${API_BASE}/rms-timeline?date=${selectedDate}&channel=${selectedChannel}`)
      .then(res => res.json())
      .then(data => {
        if (data && data.nodes && Object.keys(data.nodes).length > 0) {
          setRmsTimeline(data);
          const allPts = Object.values(data.nodes).flat() as any[];
          if (allPts.length > 0) {
            const minTs = Math.min(...allPts.map(p => p.ts));
            if (minTs > 1000000) setCurrentTime(minTs);
          }
        } else {
          const ts = new Date(selectedDate).getTime() / 1000;
          if (!isNaN(ts)) setCurrentTime(ts);
        }
      });
  }, [selectedDate, selectedChannel]);

  useEffect(() => {
    if (!isPlaying) return;
    const interval = setInterval(() => {
      setCurrentTime(prev => prev + (60 * (playSpeed / 5))); 
    }, 200);
    return () => clearInterval(interval);
  }, [isPlaying, playSpeed]);

  useEffect(() => {
    if (!rmsTimeline || !rmsTimeline.nodes || !currentTime) {
      setAllAdcValues({});
      return;
    }
    const values: Record<string, number> = {};
    Object.entries(rmsTimeline.nodes).forEach(([nodeId, dataPoints]) => {
      const pts = dataPoints as any[];
      const point = pts.find(p => p.ts >= currentTime) || pts[pts.length - 1];
      if (point) values[nodeId] = point.rms;
    });
    setAllAdcValues(values);
  }, [currentTime, rmsTimeline]);

  const loadNodeData = useCallback(async () => {
    if (!selectedNode || !selectedDate || currentTime < 1000000) return;
    setLoading(true);
    try {
      const res = await fetch(`${API_BASE}/data?node=${selectedNode.id}&date=${selectedDate}&channel=${selectedChannel}&start=${Math.floor(currentTime)}`);
      const data = await res.json();
      if (data && data.samples) setDataWindow({ ...data, node: selectedNode.id, date: selectedDate, channel: selectedChannel });
      else setDataWindow(null);
    } catch (e) { setDataWindow(null); }
    setLoading(false);
  }, [selectedNode, selectedDate, selectedChannel, currentTime]);

  useEffect(() => { loadNodeData(); }, [selectedNode, selectedDate, selectedChannel]);

  const formatTime = (ts: number) => {
    if (ts < 1000000) return '--:--:--';
    return new Date(ts * 1000).toISOString().substr(11, 8);
  };

  const sendChat = async () => {
    if (!chatMsg) return;
    const newHist = [...chatHistory, { role: 'user', text: chatMsg }];
    setChatHistory(newHist);
    setChatMsg('');
    try {
      const res = await fetch(`${API_BASE}/chat`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: chatMsg })
      });
      const data = await res.json();
      setChatHistory([...newHist, { role: 'agent', text: data.response }]);
    } catch (e) { setChatHistory([...newHist, { role: 'agent', text: "Erreur agent." }]); }
  };

  return (<>
    <div className="app-container" style={{ display: 'flex', flexDirection: 'column', height: '100vh', width: '100vw', background: '#0f172a', color: '#fff' }}>
      <header style={{ height: '60px', display: 'flex', alignItems: 'center', padding: '0 20px', background: '#1e293b', borderBottom: '1px solid #334155' }}>
        <h1 style={{ margin: 0, fontSize: '1.2rem' }}>Seismic Viewer</h1>
        
        {migrationStatus && migrationStatus.processed_files < migrationStatus.total_files && (
          <div style={{ marginLeft: '20px', background: '#334155', padding: '5px 10px', borderRadius: '15px', fontSize: '0.75rem', border: '1px solid #4ade80' }}>
            <span style={{ color: '#4ade80', fontWeight: 'bold' }}>⚡ Migration : </span>
            {Math.round((migrationStatus.processed_files / migrationStatus.total_files) * 100)}% 
            ({migrationStatus.processed_files}/{migrationStatus.total_files})
          </div>
        )}

        <div style={{ color: '#94a3b8', fontSize: '0.8rem', marginLeft: '20px' }}>
          Nodes: {nodes.length} | Actifs: {nodes.filter(n=>n.hasDates).length}
          <button onClick={() => setShowDashboard(true)} style={{ background: '#f59e0b', color: '#fff', border: 'none', padding: '5px 15px', borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold' }}>🎯 Dashboard H5</button>
              <button onClick={() => setShowCampaignDocs(true)} style={{ background: "#8b5cf6", border: "none", color: "#fff", padding: "8px 16px", borderRadius: "6px", cursor: "pointer", fontWeight: "bold", fontSize: "0.9rem" }}>📚 Documentation Campagne</button>
        </div>
        <div style={{ marginLeft: 'auto', display: 'flex', gap: '10px' }}>
          <button onClick={() => setShowSection(true)} style={{ background: '#8b5cf6', color: '#fff', border: 'none', padding: '5px 15px', borderRadius: '4px', cursor: 'pointer' }}>Vue Globale</button>
          <button onClick={() => setShowDocumentation(true)} style={{ background: '#10b981', color: '#fff', border: 'none', padding: '5px 15px', borderRadius: '4px', cursor: 'pointer' }}>📖 Documentation</button>
          <button onClick={() => setShowCoverage(true)} style={{ background: '#3b82f6', color: '#fff', border: 'none', padding: '5px 15px', borderRadius: '4px', cursor: 'pointer' }}>Coverage H5</button>
          <select value={selectedDate} onChange={e => setSelectedDate(e.target.value)} style={{ background: '#0f172a', color: '#fff', border: '1px solid #334155' }}>
            {dates.map(d => <option key={d} value={d}>{d}</option>)}
          </select>
          <select value={selectedChannel} onChange={e => setSelectedChannel(e.target.value)} style={{ background: '#0f172a', color: '#fff', border: '1px solid #334155' }}>
            {['ch0', 'ch1', 'ch2', 'ch3'].map(ch => <option key={ch} value={ch}>{ch.toUpperCase()}</option>)}
          </select>
        </div>
      </header>

      <div style={{ height: '50px', background: '#0f172a', display: 'flex', alignItems: 'center', padding: '0 20px', gap: '15px', borderBottom: '1px solid #334155' }}>
        <button onClick={() => setIsPlaying(!isPlaying)} aria-label={isPlaying ? 'Mettre en pause' : 'Lancer la lecture'} style={{ background: isPlaying ? '#ef4444' : '#22c55e', color: '#fff', border: 'none', padding: '5px 15px', borderRadius: '4px', fontWeight: 'bold', cursor: 'pointer' }}>
          {isPlaying ? 'PAUSE' : 'PLAY'}
        </button>
        <div style={{ display: 'flex', gap: '2px', background: '#1e293b', padding: '2px', borderRadius: '4px' }}>
          {[1, 10, 100, 1000].map(s => (
            <button key={s} onClick={() => setPlaySpeed(s)} aria-label={`Vitesse ${s}x`} style={{ background: playSpeed === s ? '#3b82f6' : 'transparent', color: '#fff', border: 'none', padding: '2px 8px', fontSize: '0.7rem', cursor: 'pointer' }}>x{s}</button>
          ))}
        </div>
        <span style={{ fontFamily: 'monospace', color: '#4ade80', fontSize: '1.1rem', minWidth: '80px' }}>{formatTime(currentTime)}</span>
        <input type="range" aria-label="Curseur temporel" style={{ flex: 1 }} min={currentTime - 1800} max={currentTime + 1800} value={currentTime} onChange={e => { setCurrentTime(Number(e.target.value)); setIsPlaying(false); }} />
      </div>

      <main style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
        <div style={{ flex: 1, position: 'relative' }}>
          <MapContainer center={DEFAULT_CENTER} zoom={13} style={{ height: '100%', width: '100%' }}>
            <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
            <NodeMarkers nodes={nodes} selectedNode={selectedNode} onSelectNode={setSelectedNode} adcValues={allAdcValues} showOnlyWithData={showOnlyWithData} />
          </MapContainer>
        </div>
        <Sidebar selectedNode={selectedNode} dataWindow={dataWindow} loading={loading} sampleRate={sampleRate} />
      </main>

      <SeismicSection nodes={nodes} currentTime={currentTime} channel={selectedChannel} visible={showSection} onClose={() => setShowSection(false)} />

      <div style={{ position: 'fixed', bottom: '20px', right: '20px', zIndex: 10000 }}>
        {!chatOpen ? (
          <button onClick={() => setChatOpen(true)} aria-label="Ouvrir le chat assistant" style={{ width: '50px', height: '50px', borderRadius: '25px', background: '#e94560', border: 'none', color: '#fff', fontSize: '20px', cursor: 'pointer', boxShadow: '0 4px 12px rgba(0,0,0,0.3)' }}>💬</button>
        ) : (
          <div style={{ background: '#1e293b', width: '300px', height: '400px', borderRadius: '8px', display: 'flex', flexDirection: 'column', border: '1px solid #334155', boxShadow: '0 8px 24px rgba(0,0,0,0.4)' }}>
            <div style={{ padding: '10px', background: '#334155', display: 'flex', justifyContent: 'space-between', borderRadius: '8px 8px 0 0' }}>
              <span style={{ fontSize: '0.8rem', fontWeight: 'bold' }}>Assistant</span>
              <button onClick={() => setChatOpen(false)} aria-label="Fermer le chat" style={{ background: 'none', border: 'none', color: '#fff', cursor: 'pointer' }}>×</button>
            </div>
            <div style={{ flex: 1, overflowY: 'auto', padding: '10px', display: 'flex', flexDirection: 'column', gap: '8px' }}>
              {chatHistory.map((m, i) => (
                <div key={i} style={{ alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start', background: m.role === 'user' ? '#3b82f6' : '#475569', padding: '6px 10px', borderRadius: '8px', fontSize: '0.8rem', maxWidth: '85%' }}>{m.text}</div>
              ))}
            </div>
            <div style={{ padding: '10px', borderTop: '1px solid #334155', display: 'flex', gap: '5px' }}>
              <input value={chatMsg} onChange={e => setChatMsg(e.target.value)} onKeyPress={e => e.key === 'Enter' && sendChat()} aria-label="Poser une question" style={{ flex: 1, background: '#0f172a', border: '1px solid #334155', color: '#fff', padding: '5px', borderRadius: '4px', fontSize: '0.8rem' }} placeholder="Question…" />
              <button onClick={sendChat} style={{ background: '#e94560', border: 'none', color: '#fff', padding: '5px 10px', borderRadius: '4px', fontSize: '0.8rem' }}>OK</button>
            </div>
          </div>
        )}
      </div>
      {showDashboard && (
        <div style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "#f1f5f9", zIndex: 9998, overflow: "auto" }}>
          <div style={{ position: "relative" }}>
            <button onClick={() => setShowDashboard(false)} style={{ position: "fixed", top: "10px", right: "10px", background: "#ef4444", color: "white", border: "none", padding: "10px 20px", borderRadius: "4px", cursor: "pointer", fontWeight: "bold", zIndex: 9999 }}>✕ Fermer Dashboard</button>
            <H5Dashboard />
          </div>
        </div>
      )}
      {showCampaignDocs && (
        <div style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "#f1f5f9", zIndex: 9998, overflow: "auto" }}>
          <div style={{ position: "relative" }}>
            <button onClick={() => setShowCampaignDocs(false)} style={{ position: "fixed", top: "10px", right: "10px", background: "#ef4444", color: "white", border: "none", padding: "10px 20px", borderRadius: "4px", cursor: "pointer", fontWeight: "bold", zIndex: 9999 }}>✕ Fermer</button>
            <CampaignDocs />
          </div>
        </div>
      )}
      {showDocumentation && <DataDocumentation onClose={() => setShowDocumentation(false)} />}
      {showCoverage && <H5Coverage onClose={() => setShowCoverage(false)} />}
    </div>
    </>
  );
}

export default App;
