import Head from 'next/head';
import { useEffect, useMemo, useState } from 'react';

interface ApiStatus {
  message: string;
  docs: string;
}

interface MqttMessage {
  topic: string;
  payload: string;
  receivedAt: string;
}

declare global {
  interface Window {
    Paho?: {
      Client: new (...args: any[]) => any;
    };
  }
}

export default function Home() {
  const [status, setStatus] = useState<ApiStatus | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [messages, setMessages] = useState<MqttMessage[]>([]);
  const [connected, setConnected] = useState(false);

  const clientId = useMemo(() => `ulhub-web-${Math.random().toString(16).slice(2)}`, []);

  useEffect(() => {
    fetch('/api/status')
      .then((res) => res.json())
      .then(setStatus)
      .catch((err) => setError(err.message));
  }, []);

  useEffect(() => {
    const script = document.createElement('script');
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js';
    script.async = true;
    console.log('Appending Paho script to page:', script.src);
    script.onerror = () => {
      console.error('Failed to load Paho MQTT script from CDN');
      setError('Failed to load MQTT client script');
    };
    script.onload = () => {
      console.log('Paho script loaded', !!window.Paho);
      console.log('Paho global:', window.Paho);
      // connect to same-origin via nginx proxy at /mqtt so browsers use wss on HTTPS
      const scheme = window.location.protocol === 'https:' ? 'wss' : 'ws';
      const uri = `${scheme}://${window.location.host}/mqtt`;
      console.log('Connecting Paho client to', uri);

      let client: any;
      try {
        if (window.Paho && typeof (window.Paho as any).Client === 'function') {
          client = new (window.Paho as any).Client(uri, clientId);
        } else if (window.Paho && (window.Paho as any).MQTT && typeof (window.Paho as any).MQTT.Client === 'function') {
          // Paho.MQTT.Client(host, port, path, clientId)
          const url = new URL(uri);
          const host = url.hostname;
          const port = url.port ? Number(url.port) : (url.protocol === 'wss:' ? 443 : 80);
          const path = url.pathname + (url.search || '');
          client = new (window.Paho as any).MQTT.Client(host, port, path, clientId);
        } else {
          console.error('Paho client constructor not found', window.Paho);
          setError('MQTT client not available in browser');
          return;
        }
      } catch (e) {
        console.error('Failed to instantiate Paho client', e);
        setError(String(e));
        return;
      }

      client.onConnectionLost = (responseObject: { errorCode: number; errorMessage: string }) => {
        console.warn('Paho connection lost', responseObject);
        setConnected(false);
        setError(responseObject.errorMessage || 'MQTT connection lost');
      };

      client.onMessageArrived = (message: { topic: string; payloadString: string }) => {
        setMessages((prev) => [
          {
            topic: message.topic,
            payload: message.payloadString,
            receivedAt: new Date().toLocaleTimeString(),
          },
          ...prev,
        ].slice(0, 10));
      };

      const connectOptions: any = {
        onSuccess: () => {
          console.log('Paho connected');
          setConnected(true);
          setError(null);
          client.subscribe('devices/#');
        },
        onFailure: (err: { errorMessage: string }) => {
          console.error('Paho connect failure', err);
          setConnected(false);
          setError(err.errorMessage || 'Unable to connect to MQTT broker');
        },
      };
      // force secure websocket when page is served over HTTPS
      connectOptions.useSSL = window.location.protocol === 'https:';
      console.log('Paho connect options:', connectOptions);
      client.connect(connectOptions);

      return () => {
        client.disconnect();
      };
    };

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, [clientId]);

  return (
    <>
      <Head>
        <title>UlHub</title>
        <meta name="description" content="UlHub monolithic app" />
      </Head>
      <main style={{ padding: '3rem', fontFamily: 'system-ui, sans-serif', maxWidth: '900px' }}>
        <h1>UlHub</h1>
        <p>React + Next.js frontend with NestJS backend and live MQTT WebSocket data.</p>

        <section style={{ marginTop: '1.5rem' }}>
          <h2>API Status</h2>
          {error && <p style={{ color: 'red' }}>{error}</p>}
          {status ? (
            <div>
              <p>{status.message}</p>
              <p>{status.docs}</p>
            </div>
          ) : (
            <p>Loading status...</p>
          )}
        </section>

        <section style={{ marginTop: '1.5rem' }}>
          <h2>MQTT WebSocket</h2>
          <p>Status: {connected ? 'Connected' : 'Connecting...'}</p>
          <ul>
            {messages.map((msg, index) => (
              <li key={`${msg.topic}-${index}`} style={{ marginBottom: '0.75rem' }}>
                <strong>{msg.topic}</strong> <span style={{ color: '#666' }}>{msg.receivedAt}</span>
                <br />
                {msg.payload}
              </li>
            ))}
          </ul>
        </section>
      </main>
    </>
  );
}
