import { useEffect, useState } from 'react';
import { useThread, useMessages } from '@insignia/iios-message-web';
import { InboxProvider, useInbox } from '@insignia/iios-inbox-web';
import { SupportProvider, useEscalate } from '@insignia/iios-support-web';

const SERVICE = 'http://localhost:3200';
const APP_ID = 'portal-demo';

async function devToken(userId: string, name: string): Promise<string> {
  const r = await fetch(`${SERVICE}/v1/dev/token`, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ appId: APP_ID, userId, name }),
  });
  if (!r.ok) throw new Error(`devToken ${r.status} (is the service running with IIOS_DEV_TOKENS=1?)`);
  return ((await r.json()) as { token: string }).token;
}

function ChatInner({
  label,
  threadId,
  onCreated,
}: {
  label: string;
  threadId: string | null;
  onCreated?: (id: string) => void;
}) {
  const { open } = useThread();
  const [tid, setTid] = useState<string | null>(threadId);
  const [text, setText] = useState('');

  useEffect(() => {
    if (threadId) {
      setTid(threadId);
      return;
    }
    if (onCreated) {
      void open().then((id) => {
        setTid(id);
        onCreated(id);
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [threadId]);

  const { messages, send, typing, typingUsers, markRead, reads } = useMessages(tid);
  const escalate = useEscalate();

  return (
    <div style={{ flex: 1, border: '1px solid #ccc', borderRadius: 8, padding: 12, margin: 8, fontFamily: 'sans-serif' }}>
      <h3 style={{ marginTop: 0 }}>{label}</h3>
      <div style={{ color: '#888', fontSize: 12 }}>thread: {tid ?? '…'}</div>
      <div style={{ height: 240, overflow: 'auto', background: '#fafafa', padding: 8, margin: '8px 0' }}>
        {messages.map((m) => (
          <div key={m.id} style={{ padding: '2px 0' }}>
            <b>{m.senderActorId.slice(0, 6)}:</b> {m.content} {reads.includes(m.id) ? '✓✓' : ''}
          </div>
        ))}
        {typingUsers.length > 0 && <em style={{ color: '#888' }}>{typingUsers.join(', ')} typing…</em>}
      </div>
      <input
        value={text}
        placeholder="type a message + Enter"
        style={{ width: '100%', padding: 6 }}
        onChange={(e) => {
          setText(e.target.value);
          typing();
        }}
        onKeyDown={(e) => {
          if (e.key === 'Enter' && text.trim()) {
            void send(text.trim());
            setText('');
          }
        }}
      />
      <button
        style={{ marginTop: 8 }}
        onClick={() => {
          const last = messages.at(-1);
          if (last) void markRead(last.id);
        }}
      >
        mark last read
      </button>
      <button
        style={{ marginTop: 8, marginLeft: 4 }}
        disabled={!tid}
        onClick={() => {
          if (tid) void escalate(tid, 'Support request');
        }}
      >
        escalate to support
      </button>
    </div>
  );
}

function InboxSidebar() {
  const { items, done, snooze } = useInbox({ state: 'OPEN' });
  return (
    <div style={{ width: 170, borderRight: '1px solid #ddd', padding: 8, fontSize: 12, fontFamily: 'sans-serif' }}>
      <b>Inbox ({items.length})</b>
      {items.length === 0 && <div style={{ color: '#999', marginTop: 6 }}>nothing to reply to</div>}
      {items.map((i) => (
        <div key={i.id} style={{ padding: '6px 0', borderBottom: '1px solid #eee' }}>
          <div style={{ fontWeight: 600 }}>{i.title}</div>
          <div style={{ color: '#999' }}>{i.kind}</div>
          <button style={{ marginRight: 4 }} onClick={() => void done(i.id)}>done</button>
          <button onClick={() => void snooze(i.id)}>snooze</button>
        </div>
      ))}
    </div>
  );
}

function Pane(props: { token: string | null; label: string; threadId: string | null; onCreated?: (id: string) => void }) {
  if (!props.token) return <div style={{ flex: 1, margin: 8 }}>loading {props.label}…</div>;
  return (
    <div style={{ flex: 1, display: 'flex', margin: 8, border: '1px solid #ccc', borderRadius: 8, overflow: 'hidden' }}>
      <InboxProvider serviceUrl={SERVICE} token={props.token}>
        <InboxSidebar />
      </InboxProvider>
      <SupportProvider serviceUrl={SERVICE} token={props.token}>
        <ChatInner label={props.label} threadId={props.threadId} onCreated={props.onCreated} />
      </SupportProvider>
    </div>
  );
}

export function App() {
  const [alice, setAlice] = useState<string | null>(null);
  const [bob, setBob] = useState<string | null>(null);
  const [threadId, setThreadId] = useState<string | null>(null);

  useEffect(() => {
    void devToken('alice', 'Alice').then(setAlice);
    void devToken('bob', 'Bob').then(setBob);
  }, []);

  return (
    <div style={{ padding: 16 }}>
      <h2 style={{ fontFamily: 'sans-serif' }}>IIOS P2 — realtime demo (Alice ↔ Bob)</h2>
      <p style={{ fontFamily: 'sans-serif', color: '#666' }}>
        Type in either pane — it appears live in the other. ✓✓ = read receipt.
      </p>
      <div style={{ display: 'flex' }}>
        <Pane token={alice} label="Alice (creates thread)" threadId={null} onCreated={setThreadId} />
        <Pane token={bob} label="Bob (joins)" threadId={threadId} />
      </div>
    </div>
  );
}
