import { useEffect, useState, type FormEvent, type ReactElement } from 'react';
import styled from '@lilith/ui-styled-components';
import { FileText, Plus, Trash2 } from 'lucide-react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  createNote,
  deleteNote,
  fetchNotes,
  fetchNoteStats,
  updateNote,
  type Note,
  type NoteInput,
  type NoteStats,
} from '@/api/notes';
import { EmptyState } from '@/components/EmptyState';
import { PageError } from '@/components/PageError';

const Root = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
`;

const PageHeading = styled.h1`
  margin: 0;
  padding: 14px 20px;
  font-size: 18px;
  font-weight: 700;
  color: #e0e0f0;
  border-bottom: 1px solid #2a2a38;
  background: #0a0a0f;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
`;

const Stats = styled.span`
  font-size: 11px;
  color: #8a8a9a;
  font-weight: 500;
`;

const Body = styled.div`
  display: flex;
  flex: 1;
  overflow: hidden;
`;

const SidePanel = styled.aside`
  width: 280px;
  flex-shrink: 0;
  border-right: 1px solid #2a2a38;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #0d0d14;
`;

const Toolbar = styled.div`
  display: flex;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid #1e1e2a;
`;

const PrimaryButton = styled.button`
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  color: #0a0a0f;
  background: #c9a84c;
  border: 1px solid #c9a84c;
  border-radius: 5px;
  cursor: pointer;

  &:hover { background: #d4b455; }
  &:disabled { opacity: 0.5; cursor: not-allowed; }
`;

const SecondaryButton = styled.button`
  padding: 6px 12px;
  font-size: 12px;
  color: #b0b0c0;
  background: transparent;
  border: 1px solid #2a2a38;
  border-radius: 5px;
  cursor: pointer;
  &:hover { color: #e0e0f0; border-color: #4a4a58; }
`;

const DangerButton = styled.button`
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  font-size: 12px;
  color: #ff8a8a;
  background: transparent;
  border: 1px solid #3a2a2a;
  border-radius: 5px;
  cursor: pointer;
  &:hover { background: rgba(255,107,107,0.08); border-color: #5a3a3a; }
`;

const NoteList = styled.ul`
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
`;

const NoteItem = styled.li<{ $selected: boolean }>`
  padding: 10px 14px;
  border-bottom: 1px solid #1e1e2a;
  cursor: pointer;
  background: ${({ $selected }) => ($selected ? 'rgba(201,168,76,0.12)' : 'transparent')};

  &:hover { background: ${({ $selected }) => ($selected ? 'rgba(201,168,76,0.14)' : '#13131a')}; }
`;

const NoteName = styled.div<{ $selected: boolean }>`
  font-size: 13px;
  font-weight: 600;
  color: ${({ $selected }) => ($selected ? '#c9a84c' : '#e0e0f0')};
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 6px;
`;

const NotePreview = styled.div`
  font-size: 11px;
  color: #8a8a9a;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
`;

const Content = styled.div`
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #0d0d14;
`;

const EditorHeader = styled.div`
  display: flex;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid #1e1e2a;
  align-items: center;
`;

const TitleInput = styled.input`
  flex: 1;
  padding: 7px 9px;
  font-size: 14px;
  font-weight: 600;
  color: #e0e0f0;
  background: #0a0a0f;
  border: 1px solid #2a2a38;
  border-radius: 4px;
  outline: none;
  &:focus { border-color: #c9a84c; }
`;

const FolderInput = styled.input`
  width: 140px;
  padding: 7px 9px;
  font-size: 12px;
  color: #e0e0f0;
  background: #0a0a0f;
  border: 1px solid #2a2a38;
  border-radius: 4px;
  outline: none;
  &:focus { border-color: #c9a84c; }
`;

const BodyTextArea = styled.textarea`
  flex: 1;
  padding: 14px 16px;
  font-size: 13px;
  line-height: 1.5;
  color: #e0e0f0;
  background: #0a0a0f;
  border: none;
  outline: none;
  resize: none;
  font-family: inherit;
`;

const PendingBadge = styled.span`
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #c9a84c;
  background: rgba(201,168,76,0.12);
  border: 1px solid rgba(201,168,76,0.3);
  border-radius: 3px;
  padding: 1px 5px;
  text-transform: uppercase;
`;

const SpinnerWrap = styled.div`
  padding: 20px;
  font-size: 12px;
  color: #8a8a9a;
  text-align: center;
`;

const DEVICE_ID: string | undefined = undefined;

function stripHtml(html: string): string {
  return html.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim();
}

interface EditorState {
  name: string;
  folder: string;
  body: string;
}

export function NotesTab(): ReactElement {
  const qc = useQueryClient();
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [creating, setCreating] = useState(false);
  const [editor, setEditor] = useState<EditorState>({ name: '', folder: '', body: '' });
  const [pendingIds, setPendingIds] = useState<ReadonlySet<string>>(new Set());

  const statsQ = useQuery<NoteStats>({
    queryKey: ['note-stats'],
    queryFn: fetchNoteStats,
    refetchInterval: 30_000,
  });

  const listQ = useQuery<Note[]>({
    queryKey: ['notes', DEVICE_ID],
    queryFn: () => fetchNotes({ limit: 50 }),
    refetchInterval: 30_000,
  });

  const notes = listQ.data ?? [];
  const selected = creating ? null : (notes.find((n) => n.noteIdentifier === selectedId) ?? null);

  useEffect(() => {
    if (selected) {
      setEditor({
        name: selected.name,
        folder: selected.folder ?? '',
        body: stripHtml(selected.body),
      });
    }
  }, [selected]);

  const markPending = (id: string): void => {
    setPendingIds((prev) => {
      const next = new Set(prev);
      next.add(id);
      return next;
    });
  };

  const startCreate = (): void => {
    setCreating(true);
    setSelectedId(null);
    setEditor({ name: 'Untitled note', folder: '', body: '' });
  };

  const cancelCreate = (): void => {
    setCreating(false);
    setEditor({ name: '', folder: '', body: '' });
  };

  const createMut = useMutation({
    mutationFn: (input: NoteInput) => createNote(input, DEVICE_ID ?? ''),
    onSuccess: (res) => {
      markPending(res.sendQueueId);
      qc.invalidateQueries({ queryKey: ['notes'] });
      qc.invalidateQueries({ queryKey: ['note-stats'] });
      setCreating(false);
    },
  });

  const updateMut = useMutation({
    mutationFn: (vars: { id: string; patch: Partial<NoteInput> }) =>
      updateNote(vars.id, vars.patch, DEVICE_ID ?? ''),
    onSuccess: (_, vars) => {
      markPending(vars.id);
      qc.invalidateQueries({ queryKey: ['notes'] });
    },
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteNote(id, DEVICE_ID ?? ''),
    onSuccess: (_, id) => {
      markPending(id);
      setSelectedId(null);
      qc.invalidateQueries({ queryKey: ['notes'] });
      qc.invalidateQueries({ queryKey: ['note-stats'] });
    },
  });

  const onSubmit = (e: FormEvent<HTMLFormElement>): void => {
    e.preventDefault();
    if (!editor.name) return;
    if (creating) {
      createMut.mutate({
        name: editor.name,
        body: editor.body,
        ...(editor.folder ? { folder: editor.folder } : {}),
      });
    } else if (selected) {
      updateMut.mutate({
        id: selected.noteIdentifier,
        patch: {
          name: editor.name,
          body: editor.body,
          ...(editor.folder ? { folder: editor.folder } : {}),
        },
      });
    }
  };

  const onDelete = (): void => {
    if (!selected) return;
    if (window.confirm(`Delete "${selected.name}"?`)) {
      deleteMut.mutate(selected.noteIdentifier);
    }
  };

  const stats = statsQ.data;
  const statsLine = stats
    ? `${stats.totalNotes} note${stats.totalNotes !== 1 ? 's' : ''} · ${stats.totalFolders} folder${stats.totalFolders !== 1 ? 's' : ''}${stats.lastSyncAt ? ` · synced ${new Date(stats.lastSyncAt).toLocaleTimeString()}` : ''}`
    : '';

  return (
    <Root>
      <PageHeading>
        <span>Notes</span>
        <Stats>{statsLine}</Stats>
      </PageHeading>
      <Body>
        <SidePanel aria-label="Note list">
          <Toolbar>
            <PrimaryButton type="button" onClick={startCreate}>
              <Plus size={13} /> New note
            </PrimaryButton>
          </Toolbar>
          {listQ.isLoading && <SpinnerWrap aria-live="polite">Loading…</SpinnerWrap>}
          {listQ.error && <PageError message="Failed to load notes" />}
          {!listQ.isLoading && !listQ.error && notes.length === 0 && !creating && (
            <EmptyState
              icon={<FileText size={28} />}
              heading="No notes yet"
              sub="Click New note to create one."
            />
          )}
          {!listQ.isLoading && notes.length > 0 && (
            <NoteList role="listbox" aria-label="Notes">
              {notes.map((n) => {
                const isPending = pendingIds.has(n.noteIdentifier);
                return (
                  <NoteItem
                    key={n.noteIdentifier}
                    $selected={n.noteIdentifier === selectedId}
                    onClick={() => {
                      setCreating(false);
                      setSelectedId(n.noteIdentifier);
                    }}
                    role="option"
                    aria-selected={n.noteIdentifier === selectedId}
                  >
                    <NoteName $selected={n.noteIdentifier === selectedId}>
                      {n.name || '(untitled)'}
                      {isPending && <PendingBadge>Pending</PendingBadge>}
                    </NoteName>
                    <NotePreview>
                      {n.folder ? `${n.folder} · ` : ''}
                      {stripHtml(n.body).slice(0, 80) || 'No content'}
                    </NotePreview>
                  </NoteItem>
                );
              })}
            </NoteList>
          )}
        </SidePanel>
        <Content>
          {(creating || selected) ? (
            <form onSubmit={onSubmit} style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }}>
              <EditorHeader>
                <TitleInput
                  type="text"
                  value={editor.name}
                  onChange={(e) => setEditor({ ...editor, name: e.target.value })}
                  placeholder="Note title"
                  required
                />
                <FolderInput
                  type="text"
                  value={editor.folder}
                  onChange={(e) => setEditor({ ...editor, folder: e.target.value })}
                  placeholder="Folder"
                />
                <PrimaryButton type="submit" disabled={createMut.isPending || updateMut.isPending}>
                  {creating ? 'Create' : 'Save'}
                </PrimaryButton>
                {creating ? (
                  <SecondaryButton type="button" onClick={cancelCreate}>Cancel</SecondaryButton>
                ) : (
                  <DangerButton type="button" onClick={onDelete}>
                    <Trash2 size={13} /> Delete
                  </DangerButton>
                )}
              </EditorHeader>
              <BodyTextArea
                value={editor.body}
                onChange={(e) => setEditor({ ...editor, body: e.target.value })}
                placeholder="Write your note…"
              />
            </form>
          ) : (
            <EmptyState
              icon={<FileText size={36} />}
              heading="Select a note"
              sub="Choose a note from the left or create a new one."
            />
          )}
        </Content>
      </Body>
    </Root>
  );
}
