'use client'

import { Node, mergeAttributes } from '@tiptap/core'
import { ReactNodeViewRenderer, NodeViewWrapper, type NodeViewProps } from '@tiptap/react'
import type { Editor } from '@tiptap/core'
import type { Node as PMNode } from '@tiptap/pm/model'
import { StructuredViewBlockEmbed } from '@/components/structured-view-block-embed'

function StructuredViewBlockView(props: NodeViewProps) {
  return (
    <NodeViewWrapper className="structured-view-block-wrapper" data-drag-handle contentEditable={false}>
      <StructuredViewBlockEmbed
        notebookId={props.node.attrs.notebookId}
        displayMode={props.node.attrs.displayMode}
        filterJson={props.node.attrs.filterJson}
        isLocal={props.node.attrs.isLocal}
        localColumnsJson={props.node.attrs.localColumnsJson}
        localRowsJson={props.node.attrs.localRowsJson}
        updateAttributes={props.updateAttributes}
        editor={props.editor}
      />
    </NodeViewWrapper>
  )
}

const defaultColumns = [
  { id: 'col-title', name: 'Nom', type: 'text' },
  { id: 'col-done', name: 'Fait', type: 'checkbox' },
  { id: 'col-status', name: 'Statut', type: 'select', options: ['À faire', 'En cours', 'Terminé'] }
]
const defaultRows = [
  { id: 'row-1', values: { 'col-title': '', 'col-done': false, 'col-status': 'À faire' } },
  { id: 'row-2', values: { 'col-title': '', 'col-done': false, 'col-status': 'À faire' } }
]

export const StructuredViewBlockExtension = Node.create({
  name: 'structuredViewBlock',
  group: 'block',
  atom: true,
  draggable: true,
  selectable: true,

  addAttributes() {
    return {
      notebookId: {
        default: null,
        parseHTML: (el) => el.getAttribute('data-sv-notebook-id'),
        renderHTML: (attrs) => attrs.notebookId
          ? { 'data-sv-notebook-id': attrs.notebookId }
          : {},
      },
      displayMode: {
        default: 'table',
        parseHTML: (el) => el.getAttribute('data-sv-mode') || 'table',
        renderHTML: (attrs) => ({ 'data-sv-mode': attrs.displayMode || 'table' }),
      },
      filterJson: {
        default: '{}',
        parseHTML: (el) => el.getAttribute('data-sv-filter') || '{}',
        renderHTML: (attrs) => ({ 'data-sv-filter': attrs.filterJson || '{}' }),
      },
      isLocal: {
        default: true, // Par défaut, on crée une base de données locale autonome
        parseHTML: (el) => el.getAttribute('data-sv-is-local') === 'true',
        renderHTML: (attrs) => attrs.isLocal
          ? { 'data-sv-is-local': 'true' }
          : { 'data-sv-is-local': 'false' },
      },
      localColumnsJson: {
        default: JSON.stringify(defaultColumns),
        parseHTML: (el) => el.getAttribute('data-sv-local-cols') || '[]',
        renderHTML: (attrs) => ({ 'data-sv-local-cols': attrs.localColumnsJson || '[]' }),
      },
      localRowsJson: {
        default: JSON.stringify(defaultRows),
        parseHTML: (el) => el.getAttribute('data-sv-local-rows') || '[]',
        renderHTML: (attrs) => ({ 'data-sv-local-rows': attrs.localRowsJson || '[]' }),
      },
    }
  },

  parseHTML() {
    return [
      { tag: 'div[data-structured-view-block]' },
      {
        tag: 'div[data-database-block]',
        getAttrs: () => ({
          isLocal: true,
          localColumnsJson: JSON.stringify(defaultColumns),
          localRowsJson: JSON.stringify(defaultRows),
        })
      }
    ]
  },

  renderHTML({ HTMLAttributes }) {
    return ['div', mergeAttributes(HTMLAttributes, { 'data-structured-view-block': 'true' })]
  },

  addNodeView() {
    return ReactNodeViewRenderer(StructuredViewBlockView)
  },
})

export function insertStructuredViewBlockAtSelection(editor: Editor, notebookId?: string | null): boolean {
  const type = editor.schema.nodes.structuredViewBlock
  if (!type) return false

  // Par défaut, si la note a un carnet et qu'on n'est pas dans l'inbox, on peut l'insérer liée au carnet.
  // Mais si aucun notebookId n'est passé ou si on veut favoriser la base locale autonome Notion-like par défaut :
  // On l'insère en base locale autonome par défaut !
  const attrs = {
    notebookId: null,
    displayMode: 'table',
    filterJson: '{}',
    isLocal: true,
    localColumnsJson: JSON.stringify(defaultColumns),
    localRowsJson: JSON.stringify(defaultRows)
  }
  const { empty, $from } = editor.state.selection
  const parent = $from.parent

  if (empty && parent.type.name === 'paragraph' && parent.content.size === 0) {
    const pos = $from.before()
    return editor
      .chain()
      .focus()
      .command(({ tr, dispatch }) => {
        tr.replaceWith(pos, pos + parent.nodeSize, type.create(attrs))
        if (dispatch) dispatch(tr)
        return true
      })
      .run()
  }

  return editor.chain().focus().insertContent({ type: 'structuredViewBlock', attrs }).run()
}

export function replaceBlockWithStructuredView(
  editor: Editor,
  blockPos: number,
  blockNode: PMNode,
  notebookId?: string | null
): void {
  const type = editor.schema.nodes.structuredViewBlock
  if (!type || blockPos < 0 || !blockNode) return
  const attrs = {
    notebookId: null,
    displayMode: 'table',
    filterJson: '{}',
    isLocal: true,
    localColumnsJson: JSON.stringify(defaultColumns),
    localRowsJson: JSON.stringify(defaultRows)
  }
  const svNode = type.create(attrs)
  editor.view.dispatch(editor.state.tr.replaceWith(blockPos, blockPos + blockNode.nodeSize, svNode))
  editor.commands.focus()
}
