import React, { useEffect, useState } from 'react';
import { useEditor, EditorContent } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Placeholder from '@tiptap/extension-placeholder';
import Link from '@tiptap/extension-link';
import TextAlign from '@tiptap/extension-text-align';
import Image from '@tiptap/extension-image';
import { ButtonExtension } from './tiptap-button-extension';
import { openWPMediaImage } from '@/lib/wp-media';
import {
  Bold,
  Italic,
  List,
  ListOrdered,
  Link as LinkIcon,
  AlignLeft,
  AlignCenter,
  AlignRight,
  ImageIcon,
  MousePointer,
  Undo,
  Redo,
} from 'lucide-react';
import { Button } from './button';
import { Input } from './input';
import { Label } from './label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './select';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogBody } from './dialog';
import { __ } from '@/lib/i18n';

interface RichTextEditorProps {
  content: string;
  onChange: (content: string) => void;
  placeholder?: string;
  variables?: string[];
  onVariableInsert?: (variable: string) => void;
}

export function RichTextEditor({
  content,
  onChange,
  placeholder = __('Start typing...'),
  variables = [],
  onVariableInsert,
}: RichTextEditorProps) {
  const editor = useEditor({
    extensions: [
      // StarterKit 3.10+ includes Link by default, disable since we configure separately
      StarterKit.configure({ link: false }),
      Placeholder.configure({
        placeholder,
      }),
      // ButtonExtension MUST come before Link to ensure buttons are parsed first
      ButtonExtension,
      Link.configure({
        openOnClick: false,
        HTMLAttributes: {
          class: 'text-primary underline',
        },
      }),
      TextAlign.configure({
        types: ['heading', 'paragraph'],
      }),
      Image.configure({
        inline: true,
        HTMLAttributes: {
          class: 'max-w-full h-auto rounded',
        },
      }),
    ],
    content,
    onUpdate: ({ editor }) => {
      onChange(editor.getHTML());
    },
    editorProps: {
      attributes: {
        class:
          'prose prose-sm max-w-none focus:outline-none min-h-[200px] px-4 py-3 [&_h1]:text-3xl [&_h1]:font-bold [&_h1]:mt-4 [&_h1]:mb-2 [&_h2]:text-2xl [&_h2]:font-bold [&_h2]:mt-3 [&_h2]:mb-2 [&_h3]:text-xl [&_h3]:font-bold [&_h3]:mt-2 [&_h3]:mb-1 [&_h4]:text-lg [&_h4]:font-bold [&_h4]:mt-2 [&_h4]:mb-1',
      },
    },
  });

  // Update editor content when prop changes (fix for default value not showing)
  useEffect(() => {
    if (editor && content) {
      const currentContent = editor.getHTML();
      // Only update if content is different (avoid infinite loops)
      if (content !== currentContent) {
        editor.commands.setContent(content);
      }
    }
  }, [content, editor]);

  if (!editor) {
    return null;
  }

  const insertVariable = (variable: string) => {
    editor.chain().focus().insertContent(`{${variable}}`).run();
    if (onVariableInsert) {
      onVariableInsert(variable);
    }
  };

  const setLink = () => {
    const url = window.prompt(__('Enter URL:'));
    if (url) {
      editor.chain().focus().setLink({ href: url }).run();
    }
  };

  const [buttonDialogOpen, setButtonDialogOpen] = useState(false);
  const [buttonText, setButtonText] = useState('Click Here');
  const [buttonHref, setButtonHref] = useState('{order_url}');
  const [buttonStyle, setButtonStyle] = useState<'solid' | 'outline' | 'link'>('solid');
  const [isEditingButton, setIsEditingButton] = useState(false);
  const [editingButtonPos, setEditingButtonPos] = useState<number | null>(null);

  const addImage = () => {
    openWPMediaImage((file) => {
      editor.chain().focus().setImage({
        src: file.url,
        alt: file.alt || file.title,
        title: file.title,
      }).run();
    });
  };

  const openButtonDialog = () => {
    setButtonText('Click Here');
    setButtonHref('{order_url}');
    setButtonStyle('solid');
    setIsEditingButton(false);
    setEditingButtonPos(null);
    setButtonDialogOpen(true);
  };

  // Handle clicking on buttons in the editor to edit them
  const handleEditorClick = (e: React.MouseEvent<HTMLDivElement>) => {
    const target = e.target as HTMLElement;
    const buttonEl = target.closest('a[data-button]') as HTMLElement | null;

    if (buttonEl && editor) {
      e.preventDefault();
      e.stopPropagation();

      // Get button attributes
      const text = buttonEl.getAttribute('data-text') || buttonEl.textContent?.replace('🔘 ', '') || 'Click Here';
      const href = buttonEl.getAttribute('data-href') || '#';
      const style = (buttonEl.getAttribute('data-style') as 'solid' | 'outline') || 'solid';

      // Find the position of this button node
      const { state } = editor.view;
      let foundPos: number | null = null;

      state.doc.descendants((node, pos) => {
        if (node.type.name === 'button' &&
          node.attrs.text === text &&
          node.attrs.href === href) {
          foundPos = pos;
          return false; // Stop iteration
        }
        return true;
      });

      // Open dialog in edit mode
      setButtonText(text);
      setButtonHref(href);
      setButtonStyle(style);
      setIsEditingButton(true);
      setEditingButtonPos(foundPos);
      setButtonDialogOpen(true);
    }
  };

  const insertButton = () => {
    if (isEditingButton && editingButtonPos !== null && editor) {
      // Delete old button and insert new one at same position
      editor
        .chain()
        .focus()
        .deleteRange({ from: editingButtonPos, to: editingButtonPos + 1 })
        .insertContentAt(editingButtonPos, {
          type: 'button',
          attrs: { text: buttonText, href: buttonHref, style: buttonStyle },
        })
        .run();
    } else {
      // Insert new button
      editor.chain().focus().setButton({ text: buttonText, href: buttonHref, style: buttonStyle }).run();
    }
    setButtonDialogOpen(false);
    setIsEditingButton(false);
    setEditingButtonPos(null);
  };

  const deleteButton = () => {
    if (editingButtonPos !== null && editor) {
      editor
        .chain()
        .focus()
        .deleteRange({ from: editingButtonPos, to: editingButtonPos + 1 })
        .run();
      setButtonDialogOpen(false);
      setIsEditingButton(false);
      setEditingButtonPos(null);
    }
  };

  const getActiveHeading = () => {
    if (editor.isActive('heading', { level: 1 })) return 'h1';
    if (editor.isActive('heading', { level: 2 })) return 'h2';
    if (editor.isActive('heading', { level: 3 })) return 'h3';
    if (editor.isActive('heading', { level: 4 })) return 'h4';
    return 'p';
  };

  const setHeading = (value: string) => {
    if (value === 'p') {
      editor.chain().focus().setParagraph().run();
    } else {
      const level = parseInt(value.replace('h', '')) as 1 | 2 | 3 | 4;
      editor.chain().focus().setHeading({ level }).run();
    }
  };

  return (
    <div className="border rounded-lg overflow-hidden">
      {/* Toolbar */}
      <div className="border-b bg-muted/30 p-2 flex flex-wrap gap-1">
        {/* Heading Selector */}
        <Select value={getActiveHeading()} onValueChange={setHeading}>
          <SelectTrigger className="w-24 h-8 text-xs">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="p">{__('Paragraph')}</SelectItem>
            <SelectItem value="h1">{__('Heading 1')}</SelectItem>
            <SelectItem value="h2">{__('Heading 2')}</SelectItem>
            <SelectItem value="h3">{__('Heading 3')}</SelectItem>
            <SelectItem value="h4">{__('Heading 4')}</SelectItem>
          </SelectContent>
        </Select>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().toggleBold().run()}
          className={editor.isActive('bold') ? 'bg-accent' : ''}
        >
          <Bold className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().toggleItalic().run()}
          className={editor.isActive('italic') ? 'bg-accent' : ''}
        >
          <Italic className="h-4 w-4" />
        </Button>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().toggleBulletList().run()}
          className={editor.isActive('bulletList') ? 'bg-accent' : ''}
        >
          <List className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().toggleOrderedList().run()}
          className={editor.isActive('orderedList') ? 'bg-accent' : ''}
        >
          <ListOrdered className="h-4 w-4" />
        </Button>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={setLink}
          className={editor.isActive('link') ? 'bg-accent' : ''}
        >
          <LinkIcon className="h-4 w-4" />
        </Button>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().setTextAlign('left').run()}
          className={editor.isActive({ textAlign: 'left' }) ? 'bg-accent' : ''}
        >
          <AlignLeft className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().setTextAlign('center').run()}
          className={editor.isActive({ textAlign: 'center' }) ? 'bg-accent' : ''}
        >
          <AlignCenter className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().setTextAlign('right').run()}
          className={editor.isActive({ textAlign: 'right' }) ? 'bg-accent' : ''}
        >
          <AlignRight className="h-4 w-4" />
        </Button>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={addImage}
        >
          <ImageIcon className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={openButtonDialog}
        >
          <MousePointer className="h-4 w-4" />
        </Button>
        <div className="w-px h-6 bg-border mx-1" />
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().undo().run()}
          disabled={!editor.can().undo()}
        >
          <Undo className="h-4 w-4" />
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => editor.chain().focus().redo().run()}
          disabled={!editor.can().redo()}
        >
          <Redo className="h-4 w-4" />
        </Button>
      </div>

      {/* Editor */}
      <div onClick={handleEditorClick}>
        <EditorContent editor={editor} />
      </div>

      {/* Variables - Collapsible and Categorized */}
      {variables.length > 0 && (
        <details className="border-t bg-muted/30">
          <summary className="p-3 text-xs text-muted-foreground cursor-pointer hover:bg-muted/50 flex items-center gap-2 select-none">
            <span className="text-[10px]">▶</span>
            {__('Insert Variable')}
            <span className="text-[10px] opacity-60">({variables.length})</span>
          </summary>
          <div className="p-3 pt-0 space-y-3">
            {/* Order Variables */}
            {variables.some(v => v.startsWith('order')) && (
              <div>
                <div className="text-[10px] uppercase text-muted-foreground mb-1.5 font-medium">{__('Order')}</div>
                <div className="flex flex-wrap gap-1">
                  {variables.filter(v => v.startsWith('order')).map((variable) => (
                    <button
                      key={variable}
                      type="button"
                      onClick={() => insertVariable(variable)}
                      className="text-[11px] px-1.5 py-0.5 bg-blue-50 text-blue-700 rounded hover:bg-blue-100 transition-colors"
                    >
                      {`{${variable}}`}
                    </button>
                  ))}
                </div>
              </div>
            )}
            {/* Subscriber/Customer Variables */}
            {variables.some(v => v.startsWith('customer') || v.startsWith('subscriber') || (v.includes('_name') && !v.startsWith('order') && !v.startsWith('site') && !v.startsWith('store'))) && (
              <div>
                <div className="text-[10px] uppercase text-muted-foreground mb-1.5 font-medium">{__('Subscriber')}</div>
                <div className="flex flex-wrap gap-1">
                  {variables.filter(v => v.startsWith('customer') || v.startsWith('subscriber') || (v.includes('address') && !v.startsWith('shipping'))).map((variable) => (
                    <button
                      key={variable}
                      type="button"
                      onClick={() => insertVariable(variable)}
                      className="text-[11px] px-1.5 py-0.5 bg-green-50 text-green-700 rounded hover:bg-green-100 transition-colors"
                    >
                      {`{${variable}}`}
                    </button>
                  ))}
                </div>
              </div>
            )}
            {/* Shipping/Payment Variables */}
            {variables.some(v => v.startsWith('shipping') || v.startsWith('payment') || v.startsWith('tracking')) && (
              <div>
                <div className="text-[10px] uppercase text-muted-foreground mb-1.5 font-medium">{__('Shipping & Payment')}</div>
                <div className="flex flex-wrap gap-1">
                  {variables.filter(v => v.startsWith('shipping') || v.startsWith('payment') || v.startsWith('tracking')).map((variable) => (
                    <button
                      key={variable}
                      type="button"
                      onClick={() => insertVariable(variable)}
                      className="text-[11px] px-1.5 py-0.5 bg-orange-50 text-orange-700 rounded hover:bg-orange-100 transition-colors"
                    >
                      {`{${variable}}`}
                    </button>
                  ))}
                </div>
              </div>
            )}
            {/* Store/Site Variables */}
            {variables.some(v => v.startsWith('site') || v.startsWith('store') || v.startsWith('shop') || v.startsWith('current') || v.includes('_url') || v.startsWith('support') || v.startsWith('review')) && (
              <div>
                <div className="text-[10px] uppercase text-muted-foreground mb-1.5 font-medium">{__('Store & Links')}</div>
                <div className="flex flex-wrap gap-1">
                  {variables.filter(v => v.startsWith('site') || v.startsWith('store') || v.startsWith('shop') || v.startsWith('current') || v.startsWith('my_account') || v.startsWith('support') || v.startsWith('review') || (v.includes('_url') && !v.startsWith('order') && !v.startsWith('tracking') && !v.startsWith('payment'))).map((variable) => (
                    <button
                      key={variable}
                      type="button"
                      onClick={() => insertVariable(variable)}
                      className="text-[11px] px-1.5 py-0.5 bg-purple-50 text-purple-700 rounded hover:bg-purple-100 transition-colors"
                    >
                      {`{${variable}}`}
                    </button>
                  ))}
                </div>
              </div>
            )}
          </div>
        </details>
      )}

      {/* Button Dialog */}
      <Dialog open={buttonDialogOpen} onOpenChange={(open) => {
        setButtonDialogOpen(open);
        if (!open) {
          setIsEditingButton(false);
          setEditingButtonPos(null);
        }
      }}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{isEditingButton ? __('Edit Button') : __('Insert Button')}</DialogTitle>
            <DialogDescription>
              {isEditingButton
                ? __('Edit the button properties below. Click on the button to save.')
                : __('Add a styled button to your content. Use variables for dynamic links.')}
            </DialogDescription>
          </DialogHeader>

          <DialogBody>
            <div className="space-y-4 !p-4">
              <div className="space-y-2">
                <Label htmlFor="btn-text">{__('Button Text')}</Label>
                <Input
                  id="btn-text"
                  value={buttonText}
                  onChange={(e) => setButtonText(e.target.value)}
                  placeholder={__('e.g., View Order')}
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="btn-href">{__('Button Link')}</Label>
                <Input
                  id="btn-href"
                  value={buttonHref}
                  onChange={(e) => setButtonHref(e.target.value)}
                  placeholder="{order_url}"
                />
                {variables.length > 0 && (
                  <div className="flex flex-wrap gap-1 mt-2">
                    {variables.filter(v => v.includes('_url') || v.includes('_link')).map((variable) => (
                      <code
                        key={variable}
                        className="text-xs bg-muted px-2 py-1 rounded cursor-pointer hover:bg-muted/80"
                        onClick={() => setButtonHref(buttonHref + `{${variable}}`)}
                      >
                        {`{${variable}}`}
                      </code>
                    ))}
                  </div>
                )}
              </div>

              <div className="space-y-2">
                <Label htmlFor="btn-style">{__('Button Style')}</Label>
                <Select value={buttonStyle} onValueChange={(value: 'solid' | 'outline' | 'link') => setButtonStyle(value)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="solid">{__('Solid (Primary)')}</SelectItem>
                    <SelectItem value="outline">{__('Outline (Secondary)')}</SelectItem>
                    <SelectItem value="link">{__('Plain Link')}</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
          </DialogBody>

          <DialogFooter className="flex-col sm:flex-row gap-2">
            {isEditingButton && (
              <Button variant="destructive" onClick={deleteButton} className="sm:mr-auto">
                {__('Delete')}
              </Button>
            )}
            <Button variant="outline" onClick={() => setButtonDialogOpen(false)}>
              {__('Cancel')}
            </Button>
            <Button onClick={insertButton}>
              {isEditingButton ? __('Update Button') : __('Insert Button')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
