'use client'

import * as React from 'react'
import { useState, useCallback } from 'react'
import {
  Section,
  Block,
  ColumnLayout,
  GlobalStyles,
  MergeFieldDefinition,
  EditorSelection,
  DEFAULT_GLOBAL_STYLES,
  getColumnWidths,
} from './types'
import { useDragDrop } from './hooks/useDragDrop'
import { useEmailEditorState } from './hooks/useEmailEditorState'
import { BlockRenderer } from './BlockRenderer'
import { BlockToolbar } from './block-toolbar'
import { AddBlockMenu } from './add-block-menu'
import { EditorSidebar } from './editor-sidebar'
import { Button } from '../ui/button'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '../ui/select'
import {
  Undo,
  Redo,
  Plus,
  Settings,
  Columns2,
  Columns3,
  RectangleHorizontal,
  Trash2,
} from 'lucide-react'
import { cn } from '../../lib/utils'

interface EmailEditorProps {
  sections: Section[]
  onChange: (sections: Section[]) => void
  globalStyles?: GlobalStyles
  onGlobalStylesChange?: (styles: GlobalStyles) => void
  mergeFields?: MergeFieldDefinition[]
  readOnly?: boolean
  /** Optional custom rich text editor for the text block. */
  renderTextEditor?: (props: {
    content: string
    onChange: (html: string) => void
    placeholder?: string
    className?: string
  }) => React.ReactNode
}

// --- Main Editor ---
export function EmailEditor({
  sections: sectionsProp,
  onChange,
  globalStyles = DEFAULT_GLOBAL_STYLES,
  onGlobalStylesChange,
  mergeFields,
  readOnly = false,
  renderTextEditor,
}: EmailEditorProps) {
  const {
    sections,
    selection,
    setSelection,
    updateBlock,
    addBlock,
    removeBlock,
    duplicateBlock,
    moveBlock,
    addSection,
    removeSection,
    addRow,
    changeRowLayout,
    removeRow,
    undo: handleUndo,
    redo: handleRedo,
    canUndo: canUndoVal,
    canRedo: canRedoVal,
    commitChange,
  } = useEmailEditorState({ initialSections: sectionsProp, onChange })

  const [showSidebar, setShowSidebar] = useState(false)

  const {
    dragState,
    dragOverTarget,
    setDragOverTarget,
    handleDragStart,
    handleDragOver,
    handleDrop,
    handleDragEnd,
  } = useDragDrop({ sections, commitChange, setSelection })

  // Get selected block
  const selectedBlock = selection
    ? sections[selection.sectionIndex]?.rows[selection.rowIndex]?.columns[selection.columnIndex]?.[
        selection.blockIndex
      ] ?? null
    : null

  // --- Block update handler ---
  const handleBlockUpdate = useCallback(
    (sel: EditorSelection, updates: Partial<Block>) => {
      const current =
        sections[sel.sectionIndex]?.rows[sel.rowIndex]?.columns[sel.columnIndex]?.[sel.blockIndex]
      if (!current) return
      updateBlock(sel.sectionIndex, sel.rowIndex, sel.columnIndex, sel.blockIndex, {
        ...current,
        ...updates,
      } as Block)
    },
    [sections, updateBlock]
  )

  // --- Read-only mode ---
  if (readOnly) {
    return (
      <div
        className="mx-auto"
        style={{
          maxWidth: globalStyles.contentWidth,
          backgroundColor: globalStyles.backgroundColor,
          fontFamily: globalStyles.fontFamily,
        }}
      >
        {sections.map((section, si) => (
          <div
            key={section.id}
            style={{
              backgroundColor: section.backgroundColor || '#ffffff',
              paddingTop: section.paddingTop,
              paddingBottom: section.paddingBottom,
              paddingLeft: section.paddingLeft,
              paddingRight: section.paddingRight,
              borderRadius: 8,
              marginBottom: 4,
            }}
          >
            {section.rows.map((row, ri) => {
              const widths = getColumnWidths(row.layout)
              return (
                <div key={row.id} className="flex gap-2">
                  {row.columns.map((col, ci) => (
                    <div key={ci} style={{ width: `${widths[ci]}%` }}>
                      {col.map((block, bi) => (
                        <div key={block.id}>
                          <BlockRenderer
                            block={block}
                            editing={!readOnly}
                            onChange={(updates) =>
                              handleBlockUpdate(
                                { sectionIndex: si, rowIndex: ri, columnIndex: ci, blockIndex: bi },
                                updates
                              )
                            }
                            mergeFields={mergeFields ?? []}
                            renderTextEditor={renderTextEditor}
                          />
                        </div>
                      ))}
                    </div>
                  ))}
                </div>
              )
            })}
          </div>
        ))}
      </div>
    )
  }

  // --- Editor mode ---
  return (
    <div className="flex h-full">
      {/* Main canvas */}
      <div className="flex-1 overflow-y-auto">
        {/* Toolbar */}
        <div className="sticky top-0 z-30 bg-background border-b px-4 py-2 flex items-center gap-2">
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8"
            onClick={handleUndo}
            disabled={!canUndoVal}
            title="Undo (Cmd+Z)"
          >
            <Undo className="h-4 w-4" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8"
            onClick={handleRedo}
            disabled={!canRedoVal}
            title="Redo (Cmd+Shift+Z)"
          >
            <Redo className="h-4 w-4" />
          </Button>
          <div className="w-px h-6 bg-border mx-1" />
          <Button
            variant={showSidebar ? 'secondary' : 'ghost'}
            size="sm"
            className="h-8 gap-1 text-xs"
            onClick={() => setShowSidebar(!showSidebar)}
          >
            <Settings className="h-3.5 w-3.5" />
            Settings
          </Button>
        </div>

        {/* Canvas area */}
        <div
          className="p-6"
          style={{ backgroundColor: globalStyles.backgroundColor }}
          onClick={() => setSelection(null)}
        >
          <div
            className="mx-auto"
            style={{ maxWidth: globalStyles.contentWidth }}
          >
            {sections.map((section, si) => (
              <div key={section.id} className="mb-2">
                {/* Section wrapper */}
                <div
                  className="relative group/section rounded-lg"
                  style={{
                    backgroundColor: section.backgroundColor || '#ffffff',
                    paddingTop: section.paddingTop,
                    paddingBottom: section.paddingBottom,
                    paddingLeft: section.paddingLeft,
                    paddingRight: section.paddingRight,
                  }}
                >
                  {/* Section controls */}
                  <div className="absolute -right-10 top-2 flex flex-col gap-1 opacity-0 group-hover/section:opacity-100 transition-opacity z-20">
                    {sections.length > 1 && (
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-6 w-6 text-destructive hover:text-destructive"
                        onClick={(e) => {
                          e.stopPropagation()
                          removeSection(si)
                        }}
                        title="Remove section"
                      >
                        <Trash2 className="h-3 w-3" />
                      </Button>
                    )}
                  </div>

                  {/* Rows */}
                  {section.rows.map((row, ri) => {
                    const widths = getColumnWidths(row.layout)
                    return (
                      <div key={row.id} className="relative group/row mb-1">
                        {/* Row layout controls */}
                        <div className="absolute -right-10 top-0 opacity-0 group-hover/row:opacity-100 transition-opacity z-10">
                          <Select
                            value={row.layout}
                            onValueChange={(v) =>
                              changeRowLayout(si, ri, v as ColumnLayout)
                            }
                          >
                            <SelectTrigger className="h-6 w-6 p-0 border-0 bg-transparent [&>svg]:hidden">
                              {row.layout === '1' ? (
                                <RectangleHorizontal className="h-3.5 w-3.5 text-muted-foreground" />
                              ) : row.layout === '3' ? (
                                <Columns3 className="h-3.5 w-3.5 text-muted-foreground" />
                              ) : (
                                <Columns2 className="h-3.5 w-3.5 text-muted-foreground" />
                              )}
                            </SelectTrigger>
                            <SelectContent>
                              <SelectItem value="1">1 Column</SelectItem>
                              <SelectItem value="2">2 Equal</SelectItem>
                              <SelectItem value="3">3 Equal</SelectItem>
                              <SelectItem value="2-1">2/3 + 1/3</SelectItem>
                              <SelectItem value="1-2">1/3 + 2/3</SelectItem>
                            </SelectContent>
                          </Select>
                        </div>

                        {/* Columns */}
                        <div className="flex gap-2">
                          {row.columns.map((col, ci) => (
                            <div
                              key={ci}
                              style={{ width: `${widths[ci]}%` }}
                              className={cn(
                                'min-h-[40px] rounded transition-colors',
                                col.length === 0 && 'border-2 border-dashed border-gray-200'
                              )}
                              onDragOver={(e) => {
                                e.preventDefault()
                                if (col.length === 0) {
                                  setDragOverTarget({
                                    sectionIndex: si,
                                    rowIndex: ri,
                                    colIndex: ci,
                                    blockIndex: 0,
                                  })
                                }
                              }}
                              onDrop={(e) => {
                                if (col.length === 0) {
                                  handleDrop(e, si, ri, ci, 0)
                                }
                              }}
                            >
                              {col.length === 0 && (
                                <div className="flex items-center justify-center h-full p-2">
                                  <AddBlockMenu
                                    onAdd={(type) => addBlock(si, ri, ci, type)}
                                    variant="inline"
                                  />
                                </div>
                              )}

                              {col.map((block, bi) => {
                                const blockSel: EditorSelection = {
                                  sectionIndex: si,
                                  rowIndex: ri,
                                  columnIndex: ci,
                                  blockIndex: bi,
                                }
                                const isSelected =
                                  selection?.sectionIndex === si &&
                                  selection?.rowIndex === ri &&
                                  selection?.columnIndex === ci &&
                                  selection?.blockIndex === bi
                                const isDragOver =
                                  dragOverTarget?.sectionIndex === si &&
                                  dragOverTarget?.rowIndex === ri &&
                                  dragOverTarget?.colIndex === ci &&
                                  dragOverTarget?.blockIndex === bi

                                return (
                                  <div key={block.id}>
                                    {/* Drop zone indicator */}
                                    {isDragOver && dragState && (
                                      <div className="h-0.5 bg-primary rounded-full mx-2 my-1" />
                                    )}
                                    <div
                                      className={cn(
                                        'group relative rounded transition-all cursor-pointer',
                                        isSelected
                                          ? 'ring-2 ring-foreground ring-offset-1'
                                          : 'hover:ring-1 hover:ring-muted-foreground/30'
                                      )}
                                      onClick={(e) => {
                                        e.stopPropagation()
                                        setSelection(blockSel)
                                      }}
                                      draggable
                                      onDragStart={(e) => {
                                        e.stopPropagation()
                                        handleDragStart(si, ri, ci, bi)
                                      }}
                                      onDragOver={(e) =>
                                        handleDragOver(e, si, ri, ci, bi)
                                      }
                                      onDrop={(e) =>
                                        handleDrop(e, si, ri, ci, bi)
                                      }
                                      onDragEnd={handleDragEnd}
                                    >
                                      {/* Block toolbar (on hover when selected) */}
                                      {isSelected && (
                                        <BlockToolbar
                                          onDelete={() => removeBlock(si, ri, ci, bi)}
                                          onDuplicate={() => duplicateBlock(si, ri, ci, bi)}
                                          onMoveUp={() =>
                                            moveBlock(si, ri, ci, bi, 'up')
                                          }
                                          onMoveDown={() =>
                                            moveBlock(si, ri, ci, bi, 'down')
                                          }
                                          canMoveUp={bi > 0}
                                          canMoveDown={bi < col.length - 1}
                                        />
                                      )}

                                      {/* Block content */}
                                      <div className="p-1">
                                        <BlockRenderer
                                          block={block}
                                          editing={!readOnly}
                                          onChange={(updates) =>
                                            handleBlockUpdate(blockSel, updates)
                                          }
                                          mergeFields={mergeFields ?? []}
                                          renderTextEditor={renderTextEditor}
                                        />
                                      </div>
                                    </div>

                                    {/* Add block between items */}
                                    {isSelected && (
                                      <div className="flex justify-center py-1 opacity-0 group-hover:opacity-100 hover:!opacity-100 transition-opacity">
                                        <AddBlockMenu
                                          onAdd={(type) =>
                                            addBlock(si, ri, ci, type, bi)
                                          }
                                          variant="small"
                                        />
                                      </div>
                                    )}
                                  </div>
                                )
                              })}

                              {/* Add block at end of column */}
                              {col.length > 0 && (
                                <div className="flex justify-center py-1 opacity-0 hover:opacity-100 transition-opacity">
                                  <AddBlockMenu
                                    onAdd={(type) =>
                                      addBlock(
                                        si,
                                        ri,
                                        ci,
                                        type,
                                        col.length - 1
                                      )
                                    }
                                    variant="small"
                                  />
                                </div>
                              )}
                            </div>
                          ))}
                        </div>

                        {/* Add row button */}
                        {ri === section.rows.length - 1 && (
                          <div className="flex justify-center py-2 opacity-0 group-hover/section:opacity-100 transition-opacity">
                            <Button
                              variant="ghost"
                              size="sm"
                              className="h-6 text-xs gap-1 text-muted-foreground"
                              onClick={(e) => {
                                e.stopPropagation()
                                addRow(si)
                              }}
                            >
                              <Plus className="h-3 w-3" />
                              Add Row
                            </Button>
                          </div>
                        )}
                      </div>
                    )
                  })}
                </div>

                {/* Add section between */}
                <div className="flex justify-center py-2">
                  <Button
                    variant="ghost"
                    size="sm"
                    className="h-6 text-xs gap-1 text-muted-foreground opacity-0 hover:opacity-100 transition-opacity"
                    onClick={(e) => {
                      e.stopPropagation()
                      addSection(si)
                    }}
                  >
                    <Plus className="h-3 w-3" />
                    Add Section
                  </Button>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Sidebar */}
      {showSidebar && (
        <EditorSidebar
          selectedBlock={selectedBlock}
          onBlockChange={(block) => {
            if (selection) updateBlock(selection.sectionIndex, selection.rowIndex, selection.columnIndex, selection.blockIndex, block)
          }}
          globalStyles={globalStyles}
          onGlobalStylesChange={onGlobalStylesChange || (() => {})}
          onClose={() => setShowSidebar(false)}
        />
      )}
    </div>
  )
}
