import { useCallback, useEffect, useState } from 'react'
import { ChevronDown, ChevronUp, Lock, Pencil, Trash2 } from 'lucide-react'
import { fetchEntries as fetchEntriesFromPb } from '@/lib/pocketbase'
import { toEditorHtml } from '@/lib/instructionHtml'
import { buildPrintDocumentHtml } from '@/lib/buildPrintDocumentHtml'
import { RichTextEditor } from '@/components/RichTextEditor'

const ADDRESS_PLACEHOLDER = '101- 444 Concession St\nHamilton, ON\nL9A 1C2'

const cardStyle = {
  padding: 12,
  borderRadius: 8,
  background: '#18181b',
  border: '1px solid #27272a',
}
const buttonStyle = {
  padding: '6px 12px',
  borderRadius: 6,
  border: 'none',
  background: '#3f3f46',
  color: '#e4e4e7',
  fontSize: '0.8125rem',
  fontWeight: 500,
  cursor: 'pointer',
}
const primaryButtonStyle = { ...buttonStyle, background: '#7c3aed' }
const iconButtonStyle = {
  ...buttonStyle,
  display: 'inline-flex',
  alignItems: 'center',
  justifyContent: 'center',
  padding: 6,
  lineHeight: 0,
}
const removeButtonStyle = {
  ...iconButtonStyle,
  background: '#dc2626',
  color: '#fff',
}

function slotId() {
  return typeof crypto !== 'undefined' && crypto.randomUUID
    ? crypto.randomUUID()
    : `slot-${Date.now()}-${Math.random().toString(36).slice(2)}`
}

export function Instructions() {
  const [entries, setEntries] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
  const [canvasItems, setCanvasItems] = useState([])
  const [pdfLoading, setPdfLoading] = useState(false)
  const [pdfError, setPdfError] = useState(null)
  const [editingSlotId, setEditingSlotId] = useState(null)
  const [editBaseline, setEditBaseline] = useState(null)

  const fetchEntries = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const list = await fetchEntriesFromPb()
      setEntries(list)
    } catch (e) {
      const msg = e instanceof Error ? e.message : String(e)
      setError(msg)
      setEntries([])
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    fetchEntries()
  }, [fetchEntries])

  function addToCanvas(entry) {
    setCanvasItems((prev) => [
      ...prev,
      { slotId: slotId(), id: entry.id, vaccine: entry.vaccine, instruction: entry.instruction ?? '' },
    ])
  }

  function moveUp(index) {
    if (index <= 0) return
    setCanvasItems((prev) => {
      const next = [...prev]
      ;[next[index - 1], next[index]] = [next[index], next[index - 1]]
      return next
    })
  }

  function moveDown(index) {
    if (index >= canvasItems.length - 1) return
    setCanvasItems((prev) => {
      const next = [...prev]
      ;[next[index], next[index + 1]] = [next[index + 1], next[index]]
      return next
    })
  }

  function startPreviewEdit(slotId) {
    const item = canvasItems.find((it) => it.slotId === slotId)
    if (item) {
      setEditBaseline({ instruction: item.instruction ?? '' })
    }
    setEditingSlotId(slotId)
  }

  function cancelPreviewEdit() {
    if (editingSlotId && editBaseline) {
      updateCanvasInstruction(editingSlotId, editBaseline.instruction)
    }
    setEditBaseline(null)
    setEditingSlotId(null)
  }

  function lockPreviewEdit() {
    setEditBaseline(null)
    setEditingSlotId(null)
  }

  function remove(index) {
    const removedId = canvasItems[index]?.slotId
    setCanvasItems((prev) => prev.filter((_, i) => i !== index))
    if (removedId != null) {
      setEditingSlotId((current) => (current === removedId ? null : current))
      if (editingSlotId === removedId) setEditBaseline(null)
    }
  }

  function updateCanvasInstruction(slotId, instruction) {
    setCanvasItems((prev) =>
      prev.map((it) => (it.slotId === slotId ? { ...it, instruction } : it))
    )
  }

  const editingItem = editingSlotId
    ? canvasItems.find((it) => it.slotId === editingSlotId)
    : null

  async function handleDownloadPdf() {
    if (canvasItems.length === 0 || pdfLoading) return
    setPdfLoading(true)
    setPdfError(null)
    try {
      const { base64: logoBase64 } = await window.ipcRenderer.invoke('pdf:getLogo')
      const html = buildPrintDocumentHtml({
        items: canvasItems,
        logoBase64,
        address: ADDRESS_PLACEHOLDER,
      })
      const { base64 } = await window.ipcRenderer.invoke('pdf:generate', { html })
      const res = await window.ipcRenderer.invoke('pdf:save', {
        base64,
        defaultName: 'vaccine-instructions.pdf',
      })
      if (res && !res.ok) {
        setPdfError('Save cancelled')
      }
    } catch (e) {
      const msg = e instanceof Error ? e.message : String(e)
      setPdfError(msg || 'PDF export failed')
      console.error('PDF export failed:', e)
    } finally {
      setPdfLoading(false)
    }
  }

  return (
    <div
      style={{
        display: 'flex',
        flex: 1,
        minHeight: 'calc(100vh - 52px)',
        background: '#0f0f12',
      }}
    >
      <aside
        style={{
          width: 320,
          flexShrink: 0,
          borderRight: '1px solid #27272a',
          padding: 16,
          overflowY: 'auto',
        }}
      >
        <h2 style={{ margin: '0 0 12px', fontSize: '1rem', fontWeight: 600, color: '#e4e4e7' }}>
          Library
        </h2>
        {error && (
          <p style={{ margin: '0 0 12px', padding: 12, borderRadius: 8, background: 'rgba(239,68,68,0.15)', color: '#fca5a5', fontSize: '0.875rem' }}>
            {error}
          </p>
        )}
        <div style={{
          maxHeight: '80vh',
          overflowY: 'auto',
          }}
        >
          {loading ? (
            <p style={{ color: '#71717a', margin: 0 }}>Loading…</p>
          ) : entries.length === 0 ? (
            <p style={{ color: '#71717a', margin: 0 }}>No entries yet. Add some in Paragraph Manager.</p>
          ) : (
            <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {entries.map((e) => (
                <li
                  key={e.id}
                  role="button"
                  tabIndex={0}
                  onClick={() => addToCanvas(e)}
                  onKeyDown={(ev) => {
                    if (ev.key === 'Enter' || ev.key === ' ') {
                      ev.preventDefault()
                      addToCanvas(e)
                    }
                  }}
                  style={{
                    ...cardStyle,
                    cursor: 'pointer',
                    color: '#e4e4e7',
                  }}
                >
                  <p style={{ margin: 0, lineHeight: 1.5, fontSize: '0.9375rem' }}>{e.vaccine}</p>
                </li>
              ))}
            </ul>
          )}
        </div>
      </aside>

      <div
        style={{
          flex: 1,
          display: 'flex',
          flexDirection: 'column',
          padding: 24,
          overflow: 'hidden',
        }}
      >
        <h2 style={{ margin: '0 0 16px', fontSize: '1rem', fontWeight: 600, color: '#e4e4e7' }}>
          Document Workspace
        </h2>

        <div
          style={{
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
            gap: 16,
            minHeight: 0,
          }}
        >
          <div style={{ flexShrink: 0, display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
            <button
              type="button"
              onClick={handleDownloadPdf}
              disabled={canvasItems.length === 0 || pdfLoading}
              style={{
                ...primaryButtonStyle,
                background: canvasItems.length === 0 || pdfLoading ? '#3f3f46' : '#7c3aed',
              }}
            >
              {pdfLoading ? 'Generating…' : 'Download PDF'}
            </button>
            {pdfError && (
              <span style={{ fontSize: '0.875rem', color: '#fca5a5' }}>{pdfError}</span>
            )}
          </div>

          <div
            style={{
              flex: 1,
              display: 'flex',
              gap: 16,
              minHeight: 0,
              overflow: 'hidden',
            }}
          >
            <div
              style={{
                flex: '1 1 50%',
                display: 'flex',
                flexDirection: 'column',
                minWidth: 0,
                overflow: 'hidden',
              }}
            >
              <h3 style={{ margin: '0 0 8px', fontSize: '0.875rem', fontWeight: 600, color: '#a1a1aa' }}>
                Canvas
              </h3>
              <ul
                style={{
                  listStyle: 'none',
                  margin: 0,
                  padding: 0,
                  display: 'flex',
                  flexDirection: 'column',
                  gap: 8,
                  overflowY: 'auto',
                  flex: 1,
                }}
              >
                {canvasItems.length === 0 ? (
                  <li style={{ color: '#a1a1aa', fontSize: '0.75rem' }}>
                    Click entries in the Library to add them here.
                  </li>
                ) : (
                  canvasItems.map((it, idx) => (
                    <li
                      key={it.slotId}
                      style={{
                        ...cardStyle,
                        display: 'flex',
                        alignItems: 'flex-start',
                        gap: 8,
                        borderColor: it.slotId === editingSlotId ? '#7c3aed' : '#27272a',
                      }}
                    >
                      <p style={{ margin: 0, flex: 1, lineHeight: 1.5, fontSize: '0.9375rem', color: '#e4e4e7' }}>
                        {it.vaccine}
                      </p>
                      <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                        <button
                          type="button"
                          onClick={() => startPreviewEdit(it.slotId)}
                          disabled={editingSlotId != null && editingSlotId !== it.slotId}
                          aria-label={`Edit instruction for ${it.vaccine}`}
                          style={{
                            ...iconButtonStyle,
                            opacity: editingSlotId != null && editingSlotId !== it.slotId ? 0.5 : 1,
                            cursor:
                              editingSlotId != null && editingSlotId !== it.slotId
                                ? 'not-allowed'
                                : 'pointer',
                          }}
                        >
                          <Pencil size={16} strokeWidth={2} aria-hidden />
                        </button>
                        <button
                          type="button"
                          onClick={() => moveUp(idx)}
                          disabled={idx === 0}
                          aria-label="Move up"
                          style={{ ...iconButtonStyle, opacity: idx === 0 ? 0.5 : 1 }}
                        >
                          <ChevronUp size={16} strokeWidth={2} aria-hidden />
                        </button>
                        <button
                          type="button"
                          onClick={() => moveDown(idx)}
                          disabled={idx === canvasItems.length - 1}
                          aria-label="Move down"
                          style={{ ...iconButtonStyle, opacity: idx === canvasItems.length - 1 ? 0.5 : 1 }}
                        >
                          <ChevronDown size={16} strokeWidth={2} aria-hidden />
                        </button>
                        <button
                          type="button"
                          onClick={() => remove(idx)}
                          aria-label={`Remove ${it.vaccine}`}
                          style={removeButtonStyle}
                        >
                          <Trash2 size={16} strokeWidth={2} aria-hidden />
                        </button>
                      </div>
                    </li>
                  ))
                )}
              </ul>
            </div>

            <div
              style={{
                flex: '1 1 50%',
                display: 'flex',
                flexDirection: 'column',
                minWidth: 0,
                overflow: 'hidden',
              }}
            >
              <h3 style={{ margin: '0 0 8px', fontSize: '0.875rem', fontWeight: 600, color: '#a1a1aa' }}>
                Preview
              </h3>
              <p style={{ margin: '0 0 8px', fontSize: '0.75rem', color: '#a1a1aa' }}>
                {editingSlotId
                  ? 'Editing one instruction | Lock when done.'
                  : 'Edits here apply to this document and PDF only.'}
              </p>
              <div
                style={{
                  flex: 1,
                  ...cardStyle,
                  maxHeight: '70vh',
                  overflowY: 'auto',
                  fontSize: '0.9375rem',
                  lineHeight: 1.6,
                  color: '#e4e4e7',
                  display: editingSlotId ? 'flex' : 'block',
                  flexDirection: editingSlotId ? 'column' : undefined,
                  minHeight: 0,
                }}
              >
                {canvasItems.length === 0 ? (
                  'Preview will appear here.'
                ) : editingSlotId && editingItem ? (
                  <>
                    <p style={{ margin: 0, fontWeight: 600, lineHeight: 1.5, flexShrink: 0 }}>
                      {editingItem.vaccine}
                    </p>
                    <div
                      style={{
                        flex: 1,
                        minHeight: 0,
                        marginTop: 4,
                        display: 'flex',
                        flexDirection: 'column',
                      }}
                    >
                      <RichTextEditor
                        key={editingSlotId}
                        value={toEditorHtml(editingItem.instruction)}
                        onChange={(html) => updateCanvasInstruction(editingSlotId, html)}
                        placeholder="Edit instruction…"
                      />
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 8, flexShrink: 0, gap: 8 }}>
                      <button
                        type="button"
                        onClick={cancelPreviewEdit}
                        style={{
                          ...buttonStyle,
                          display: 'inline-flex',
                          alignItems: 'center',
                          gap: 6,
                        }}
                      >
                        Cancel
                      </button>
                      <button
                        type="button"
                        onClick={lockPreviewEdit}
                        style={{
                          ...buttonStyle,
                          background: '#7c3aed',
                          display: 'inline-flex',
                          alignItems: 'center',
                          gap: 6,
                        }}
                      >
                        <Lock size={16} strokeWidth={2} aria-hidden />
                        Lock
                      </button>
                    </div>
                  </>
                ) : (
                  canvasItems.map((it) => (
                    <div key={it.slotId} style={{ marginBottom: 14 }}>
                      <p style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600, lineHeight: 1.5 }}>{it.vaccine}</p>
                      <div
                        className="instruction-html-preview"
                        style={{ marginTop: 4 }}
                        dangerouslySetInnerHTML={{ __html: toEditorHtml(it.instruction) }}
                      />
                    </div>
                  ))
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
