import { useEffect, useMemo, useRef, useState } from 'react';

const TABS = [
  'House',
  'Generals',
  'Captains',
  'Master Chiefs',
  'Detectors',
  'Intake',
  'Capital State',
  'Calculations'
];

function formatError(err) {
  if (!err) return 'Unknown error';
  if (typeof err === 'string') return err;
  return err.message || 'Unknown error';
}

function blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onloadend = () => {
      try {
        const result = String(reader.result || '');
        const parts = result.split(',');
        resolve(parts[1] || '');
      } catch (err) {
        reject(err);
      }
    };

    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}

export default function Home() {
  const [input, setInput] = useState('');
  const [messages, setMessages] = useState([
    {
      role: 'assistant',
      content: 'I am AURA. The gateway is live. Speak, and I will answer here.'
    }
  ]);
  const [threadId, setThreadId] = useState(null);
  const [status, setStatus] = useState(null);
  const [activeTab, setActiveTab] = useState('House');
  const [isSending, setIsSending] = useState(false);
  const [lastError, setLastError] = useState('');
  const [selectedFile, setSelectedFile] = useState(null);
  const [audioBlob, setAudioBlob] = useState(null);
  const [audioTranscript, setAudioTranscript] = useState('');
  const [isRecording, setIsRecording] = useState(false);
  const [isTranscribing, setIsTranscribing] = useState(false);
  const [isMobile, setIsMobile] = useState(false);

  const outputRef = useRef(null);
  const fileInputRef = useRef(null);
  const mediaRecorderRef = useRef(null);
  const audioChunksRef = useRef([]);
  const streamRef = useRef(null);

  useEffect(() => {
    function handleResize() {
      setIsMobile(window.innerWidth < 900);
    }

    handleResize();
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  useEffect(() => {
    if (outputRef.current) {
      outputRef.current.scrollTop = outputRef.current.scrollHeight;
    }
  }, [messages]);

  const canSend = useMemo(() => {
    return input.trim().length > 0 && !isSending;
  }, [input, isSending]);

  function appendMessage(role, content) {
    setMessages(prev => [...prev, { role, content }]);
  }

  function handleFileChange(event) {
    const file = event.target.files && event.target.files[0];
    if (!file) return;

    setSelectedFile(file);
    appendMessage('user', `File attached: ${file.name} (${Math.round(file.size / 1024)} KB)`);
  }

  async function startRecording() {
    try {
      setLastError('');
      setAudioTranscript('');

      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      streamRef.current = stream;

      const recorder = new MediaRecorder(stream);
      mediaRecorderRef.current = recorder;
      audioChunksRef.current = [];

      recorder.ondataavailable = event => {
        if (event.data && event.data.size > 0) {
          audioChunksRef.current.push(event.data);
        }
      };

      recorder.onstop = () => {
        const blob = new Blob(audioChunksRef.current, { type: 'audio/webm' });
        setAudioBlob(blob);
        appendMessage('user', `Audio recorded: ${Math.round(blob.size / 1024)} KB`);

        if (streamRef.current) {
          streamRef.current.getTracks().forEach(track => track.stop());
          streamRef.current = null;
        }
      };

      recorder.start();
      setIsRecording(true);
    } catch (err) {
      setLastError('Microphone access failed: ' + formatError(err));
    }
  }

  function stopRecording() {
    try {
      if (mediaRecorderRef.current && isRecording) {
        mediaRecorderRef.current.stop();
      }
    } catch (err) {
      setLastError('Microphone stop failed: ' + formatError(err));
    } finally {
      setIsRecording(false);
    }
  }

  async function transcribeAudio() {
    if (!audioBlob || isTranscribing) return;

    setIsTranscribing(true);
    setLastError('');

    try {
      const base64Audio = await blobToBase64(audioBlob);

      const res = await fetch('/api/whisper', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          audio: base64Audio,
          context: {
            mimeType: audioBlob.type || 'audio/webm',
            activeSurface: activeTab
          }
        })
      });

      const data = await res.json();

      if (!res.ok) {
        throw new Error(data?.message || data?.error || 'Whisper request failed');
      }

      const transcript = data?.text || '';
      setAudioTranscript(transcript);

      if (transcript) {
        appendMessage('assistant', `Governed transcript: ${transcript}`);
        setInput(transcript);
      } else {
        appendMessage('assistant', 'No governed transcript was returned.');
      }
    } catch (err) {
      setLastError('Transcription failed: ' + formatError(err));
      appendMessage('assistant', 'I am AURA. Audio transcription failed: ' + formatError(err));
    } finally {
      setIsTranscribing(false);
    }
  }

  async function sendMessage() {
    const trimmed = input.trim();
    if (!trimmed || isSending) return;

    appendMessage('user', trimmed);
    setInput('');
    setIsSending(true);
    setLastError('');

    try {
      const payload = {
        message: trimmed,
        thread_id: threadId,
        history: messages.slice(-8),
        active_surface: activeTab,
        file: selectedFile
          ? {
              name: selectedFile.name,
              size: selectedFile.size,
              type: selectedFile.type,
              lastModified: selectedFile.lastModified || null
            }
          : null,
        audio: audioBlob
          ? {
              type: audioBlob.type,
              size: audioBlob.size
            }
          : null,
        transcript: audioTranscript || null
      };

      const res = await fetch('/api/embodiment', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });

      let data;
      try {
        data = await res.json();
      } catch (jsonErr) {
        throw new Error('Non-JSON response from embodiment');
      }

      if (!res.ok) {
        throw new Error(data?.message || data?.error || 'Embodiment request failed');
      }

      if (data?.meta?.thread_id) {
        setThreadId(data.meta.thread_id);
      }

      appendMessage('assistant', data?.response || 'AURA returned no visible response.');
      setStatus(data?.governance || null);

      setSelectedFile(null);
      setAudioBlob(null);
      setAudioTranscript('');

      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    } catch (err) {
      const msg = formatError(err);
      setLastError(msg);
      appendMessage('assistant', 'I am AURA. An error occurred: ' + msg);
    } finally {
      setIsSending(false);
    }
  }

  function onKeyDown(e) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  }

  return (
    <div
      style={{
        minHeight: '100vh',
        background: '#0b1020',
        color: '#e8eefc',
        fontFamily: 'Inter, Arial, sans-serif',
        padding: isMobile ? 0 : 16,
        paddingBottom: isMobile ? 140 : 16
      }}
    >
      <div style={{ maxWidth: 1440, margin: '0 auto' }}>
        <div
          style={{
            marginBottom: isMobile ? 8 : 16,
            padding: isMobile ? '12px 14px 0 14px' : 0
          }}
        >
          <div
            style={{
              fontSize: 12,
              letterSpacing: 1.5,
              textTransform: 'uppercase',
              color: '#9fb0d9'
            }}
          >
            AURAL-M
          </div>
          <h1 style={{ margin: '6px 0 4px 0', fontSize: isMobile ? 22 : 28 }}>
            AURA Gateway
          </h1>
          <div style={{ color: '#aeb9d6', fontSize: isMobile ? 14 : 16 }}>
            Primary communication surface for embodiment, mediator, vault, and Mars hierarchy.
          </div>
        </div>

        <div
          style={{
            display: 'grid',
            gridTemplateColumns: isMobile ? '1fr' : '260px 1fr 320px',
            gap: 16,
            alignItems: 'start'
          }}
        >
          {!isMobile && (
            <aside
              style={{
                background: '#121a30',
                border: '1px solid #223052',
                borderRadius: 14,
                padding: 14
              }}
            >
              <div style={{ fontWeight: 700, marginBottom: 12 }}>Mars Surfaces</div>
              <div style={{ display: 'grid', gap: 8 }}>
                {TABS.map(tab => (
                  <button
                    key={tab}
                    onClick={() => setActiveTab(tab)}
                    style={{
                      textAlign: 'left',
                      padding: '10px 12px',
                      borderRadius: 10,
                      border: activeTab === tab ? '1px solid #5a7cff' : '1px solid #2a375d',
                      background: activeTab === tab ? '#18264d' : '#0f1730',
                      color: '#e8eefc',
                      cursor: 'pointer'
                    }}
                  >
                    {tab}
                  </button>
                ))}
              </div>
            </aside>
          )}

          <main
            style={{
              background: '#121a30',
              border: isMobile ? 'none' : '1px solid #223052',
              borderRadius: isMobile ? 0 : 14,
              padding: isMobile ? '0 0 12px 0' : 14
            }}
          >
            <div
              style={{
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
                marginBottom: 12,
                gap: 12,
                padding: isMobile ? '0 14px' : 0
              }}
            >
              <div>
                <div
                  style={{
                    fontSize: 12,
                    color: '#9fb0d9',
                    textTransform: 'uppercase',
                    letterSpacing: 1
                  }}
                >
                  Active Surface
                </div>
                <div style={{ fontSize: isMobile ? 18 : 20, fontWeight: 700 }}>
                  {activeTab}
                </div>
              </div>
              <div style={{ fontSize: 12, color: '#9fb0d9' }}>
                Thread: {threadId || 'not established yet'}
              </div>
            </div>

            {isMobile && (
              <div
                style={{
                  display: 'flex',
                  gap: 8,
                  overflowX: 'auto',
                  padding: '0 14px 10px 14px'
                }}
              >
                {TABS.map(tab => (
                  <button
                    key={tab}
                    onClick={() => setActiveTab(tab)}
                    style={{
                      whiteSpace: 'nowrap',
                      padding: '10px 12px',
                      borderRadius: 10,
                      border: activeTab === tab ? '1px solid #5a7cff' : '1px solid #2a375d',
                      background: activeTab === tab ? '#18264d' : '#0f1730',
                      color: '#e8eefc',
                      cursor: 'pointer'
                    }}
                  >
                    {tab}
                  </button>
                ))}
              </div>
            )}

            <div
              ref={outputRef}
              style={{
                minHeight: isMobile ? '56vh' : 360,
                maxHeight: isMobile ? '60vh' : 520,
                overflowY: 'auto',
                background: '#0a1124',
                border: isMobile ? 'none' : '1px solid #25345d',
                borderRadius: isMobile ? 0 : 12,
                padding: 12,
                marginBottom: 12
              }}
            >
              {messages.map((m, i) => (
                <div
                  key={i}
                  style={{
                    marginBottom: 10,
                    padding: '10px 12px',
                    borderRadius: 12,
                    background: m.role === 'user' ? '#1a2750' : '#121a30',
                    border: m.role === 'user' ? '1px solid #4560bb' : '1px solid #2b3962'
                  }}
                >
                  <div style={{ fontSize: 12, color: '#9fb0d9', marginBottom: 4 }}>
                    {m.role === 'user' ? 'You' : 'AURA'}
                  </div>
                  <div style={{ whiteSpace: 'pre-wrap', lineHeight: 1.45 }}>{m.content}</div>
                </div>
              ))}
            </div>

            <div
              style={{
                position: isMobile ? 'fixed' : 'static',
                left: 0,
                right: 0,
                bottom: 0,
                background: '#121a30',
                borderTop: '1px solid #223052',
                padding: isMobile ? 12 : 0,
                zIndex: 20
              }}
            >
              <div style={{ display: 'grid', gap: 10, padding: isMobile ? 0 : '0 0 0 0' }}>
                <textarea
                  value={input}
                  onChange={e => setInput(e.target.value)}
                  onKeyDown={onKeyDown}
                  placeholder={'Speak to AURA about ' + activeTab + '...'}
                  rows={isMobile ? 2 : 4}
                  style={{
                    width: '100%',
                    resize: 'vertical',
                    borderRadius: 12,
                    border: '1px solid #32457a',
                    background: '#0a1124',
                    color: '#e8eefc',
                    padding: 12,
                    outline: 'none',
                    fontSize: 16
                  }}
                />

                <div
                  style={{
                    display: 'flex',
                    gap: 8,
                    flexWrap: 'wrap',
                    alignItems: 'center'
                  }}
                >
                  <input
                    ref={fileInputRef}
                    type="file"
                    onChange={handleFileChange}
                    style={{ color: '#e8eefc', flex: 1, minWidth: 0 }}
                  />

                  {!isRecording ? (
                    <button
                      onClick={startRecording}
                      style={{
                        padding: '14px 16px',
                        borderRadius: 12,
                        border: '1px solid #5a7cff',
                        background: '#18264d',
                        color: '#fff',
                        cursor: 'pointer',
                        fontSize: 16
                      }}
                    >
                      Mic
                    </button>
                  ) : (
                    <button
                      onClick={stopRecording}
                      style={{
                        padding: '14px 16px',
                        borderRadius: 12,
                        border: '1px solid #ff8a8a',
                        background: '#4d1818',
                        color: '#fff',
                        cursor: 'pointer',
                        fontSize: 16
                      }}
                    >
                      Stop
                    </button>
                  )}

                  <button
                    onClick={transcribeAudio}
                    disabled={!audioBlob || isTranscribing}
                    style={{
                      padding: '14px 16px',
                      borderRadius: 12,
                      border: '1px solid #5a7cff',
                      background: !audioBlob || isTranscribing ? '#23335e' : '#3658d5',
                      color: '#fff',
                      cursor: !audioBlob || isTranscribing ? 'not-allowed' : 'pointer',
                      fontSize: 16
                    }}
                  >
                    {isTranscribing ? 'Transcribing...' : 'Transcribe'}
                  </button>
                </div>

                <div style={{ fontSize: 12, color: '#9fb0d9' }}>
                  {selectedFile
                    ? `Attached file: ${selectedFile.name}`
                    : 'No file attached'}
                  {' | '}
                  {audioBlob
                    ? `Audio ready: ${Math.round(audioBlob.size / 1024)} KB`
                    : isRecording
                      ? 'Recording in progress'
                      : 'No audio recorded'}
                  {' | '}
                  {audioTranscript ? 'Transcript ready' : 'No transcript'}
                </div>

                <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                  <button
                    onClick={sendMessage}
                    disabled={!canSend}
                    style={{
                      padding: '14px 18px',
                      borderRadius: 12,
                      border: '1px solid #5a7cff',
                      background: canSend ? '#3658d5' : '#23335e',
                      color: '#fff',
                      cursor: canSend ? 'pointer' : 'not-allowed',
                      fontSize: 16
                    }}
                  >
                    {isSending ? 'Sending...' : 'Send'}
                  </button>
                  <div style={{ fontSize: 12, color: '#9fb0d9' }}>
                    Enter sends. Shift+Enter makes a new line.
                  </div>
                </div>

                {lastError ? (
                  <div style={{ color: '#ffb4b4', fontSize: 13 }}>{lastError}</div>
                ) : null}
              </div>
            </div>
          </main>

          {!isMobile && (
            <aside
              style={{
                background: '#121a30',
                border: '1px solid #223052',
                borderRadius: 14,
                padding: 14
              }}
            >
              <div style={{ fontWeight: 700, marginBottom: 12 }}>Governance</div>
              {status ? (
                <pre
                  style={{
                    margin: 0,
                    whiteSpace: 'pre-wrap',
                    wordBreak: 'break-word',
                    color: '#d8e2ff',
                    fontSize: 13
                  }}
                >
                  {JSON.stringify(status, null, 2)}
                </pre>
              ) : (
                <div style={{ color: '#9fb0d9', fontSize: 14 }}>
                  No governance output yet. Send the first message and it will appear here.
                </div>
              )}
            </aside>
          )}
        </div>
      </div>
    </div>
  );
}