'use client';

import { useCallback, useRef, useState, useEffect } from 'react';
import {
  RiBold,
  RiItalic,
  RiUnderline,
  RiStrikethrough,
  RiH1,
  RiH2,
  RiH3,
  RiListUnordered,
  RiListOrdered,
  RiAlignLeft,
  RiAlignCenter,
  RiAlignRight,
  RiAlignJustify,
  RiLinkM,
  RiLinkUnlinkM,
  RiImageAddLine,
  RiVideoLine,
  RiCodeLine,
  RiSeparator,
  RiFormatClear,
  RiArrowGoBackLine,
  RiArrowGoForwardLine,
  RiQuoteText,
  RiMarkPenLine,
} from '@remixicon/react';
import { Button } from '@/components/ui/button';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { Input } from '@/components/ui/input';

const COLORS = [
  '#000000', '#374151', '#6B7280', '#9CA3AF', '#D1D5DB',
  '#EF4444', '#F97316', '#EAB308', '#22C55E', '#14B8A6',
  '#3B82F6', '#6366F1', '#A855F7', '#EC4899', '#F43F5E',
  '#DC2626', '#EA580C', '#CA8A04', '#16A34A', '#0D9488',
  '#2563EB', '#4F46E5', '#9333EA', '#DB2777', '#E11D48',
];

const HIGHLIGHT_COLORS = ['#FEF08A', '#BBF7D0', '#BFDBFE', '#DDD6FE', '#FBCFE8', '#FED7AA', '#FDE68A', '#D9F99D', '#A5F3FC', '#E9D5FF'];

interface RichTextEditorProps {
  content: string;
  onChange: (html: string) => void;
  placeholder?: string;
  dir?: 'ltr' | 'rtl';
  minHeight?: string;
  onImageUpload?: (file: File) => Promise<string>;
  hideVideoUpload?: boolean;
}

function exec(command: string, value?: string) {
  document.execCommand(command, false, value);
}

function queryState(command: string): boolean {
  return document.queryCommandState(command);
}

export default function RichTextEditor({
  content,
  onChange,
  placeholder = 'Start writing...',
  dir = 'ltr',
  minHeight = '200px',
  onImageUpload,
  hideVideoUpload = false,
}: RichTextEditorProps) {
  const editorRef = useRef<HTMLDivElement>(null);
  const imageInputRef = useRef<HTMLInputElement>(null);
  const videoInputRef = useRef<HTMLInputElement>(null);
  const [linkUrl, setLinkUrl] = useState('');
  const [linkOpen, setLinkOpen] = useState(false);
  const [, forceUpdate] = useState(0);
  const internalHtml = useRef('');
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;

  useEffect(() => {
    if (!editorRef.current) return;
    if (content !== internalHtml.current) {
      editorRef.current.innerHTML = content || '';
      internalHtml.current = content || '';
    }
  }, [content]);

  const handleInput = useCallback(() => {
    if (editorRef.current) {
      const html = editorRef.current.innerHTML;
      internalHtml.current = html;
      onChangeRef.current(html);
    }
  }, []);

  const handleSelectionChange = useCallback(() => {
    forceUpdate((n) => n + 1);
  }, []);

  useEffect(() => {
    document.addEventListener('selectionchange', handleSelectionChange);
    return () => document.removeEventListener('selectionchange', handleSelectionChange);
  }, [handleSelectionChange]);

  const focusEditor = () => {
    editorRef.current?.focus();
  };

  const handleImageUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files) return;
    focusEditor();

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      if (onImageUpload) {
        const url = await onImageUpload(file);
        exec('insertHTML', `<img src="${url}" style="max-width:100%;height:auto;border-radius:0.5rem;margin:0.5em 0;" />`);
        handleInput();
      } else {
        const reader = new FileReader();
        reader.onload = (ev) => {
          const result = ev.target?.result as string;
          focusEditor();
          exec('insertHTML', `<img src="${result}" style="max-width:100%;height:auto;border-radius:0.5rem;margin:0.5em 0;" />`);
          handleInput();
        };
        reader.readAsDataURL(file);
      }
    }
    e.target.value = '';
  }, [onImageUpload, handleInput]);

  const setLink = useCallback(() => {
    focusEditor();
    if (linkUrl === '') {
      exec('unlink');
    } else {
      const url = linkUrl.startsWith('http') ? linkUrl : `https://${linkUrl}`;
      exec('createLink', url);
    }
    setLinkUrl('');
    setLinkOpen(false);
    handleInput();
  }, [linkUrl, handleInput]);

  const handleVideoUpload = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    focusEditor();
    const reader = new FileReader();
    reader.onload = (ev) => {
      const result = ev.target?.result as string;
      exec('insertHTML', `<div style="max-width:100%;margin:0.5em 0;"><video src="${result}" controls playsinline style="max-width:100%;height:auto;border-radius:0.5rem;"></video></div>`);
      handleInput();
    };
    reader.readAsDataURL(file);
    e.target.value = '';
  }, [handleInput]);

  const execAndUpdate = (command: string, value?: string) => {
    focusEditor();
    exec(command, value);
    handleInput();
    forceUpdate((n) => n + 1);
  };

  const formatBlock = (tag: string) => {
    focusEditor();
    exec('formatBlock', tag);
    handleInput();
    forceUpdate((n) => n + 1);
  };

  const ToolbarButton = ({ active, onClick, children, title }: {
    active?: boolean; onClick: () => void; children: React.ReactNode; title: string;
  }) => (
    <button
      type="button"
      onMouseDown={(e) => e.preventDefault()}
      onClick={onClick}
      title={title}
      className={`p-1.5 rounded hover:bg-muted transition-colors ${active ? 'bg-muted text-primary' : 'text-muted-foreground'}`}
    >
      {children}
    </button>
  );

  const isLinkActive = (() => {
    const sel = typeof window !== 'undefined' ? window.getSelection() : null;
    if (!sel || !sel.anchorNode) return false;
    let node: globalThis.Node | null = sel.anchorNode;
    while (node) {
      if (node.nodeName === 'A') return true;
      node = node.parentNode;
    }
    return false;
  })();

  return (
    <div className="border rounded-lg overflow-hidden bg-background">
      <div className="border-b bg-muted/30 px-2 py-1.5 flex flex-wrap gap-0.5 items-center">
        <ToolbarButton title="Undo" onClick={() => execAndUpdate('undo')}>
          <RiArrowGoBackLine className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Redo" onClick={() => execAndUpdate('redo')}>
          <RiArrowGoForwardLine className="size-4" />
        </ToolbarButton>

        <div className="w-px h-5 bg-border mx-1" />

        <ToolbarButton title="Bold" active={queryState('bold')} onClick={() => execAndUpdate('bold')}>
          <RiBold className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Italic" active={queryState('italic')} onClick={() => execAndUpdate('italic')}>
          <RiItalic className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Underline" active={queryState('underline')} onClick={() => execAndUpdate('underline')}>
          <RiUnderline className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Strikethrough" active={queryState('strikeThrough')} onClick={() => execAndUpdate('strikeThrough')}>
          <RiStrikethrough className="size-4" />
        </ToolbarButton>

        <div className="w-px h-5 bg-border mx-1" />

        <ToolbarButton title="Heading 1" onClick={() => formatBlock('h1')}>
          <RiH1 className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Heading 2" onClick={() => formatBlock('h2')}>
          <RiH2 className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Heading 3" onClick={() => formatBlock('h3')}>
          <RiH3 className="size-4" />
        </ToolbarButton>

        <div className="w-px h-5 bg-border mx-1" />

        <ToolbarButton title="Bullet List" active={queryState('insertUnorderedList')} onClick={() => execAndUpdate('insertUnorderedList')}>
          <RiListUnordered className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Ordered List" active={queryState('insertOrderedList')} onClick={() => execAndUpdate('insertOrderedList')}>
          <RiListOrdered className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Blockquote" onClick={() => formatBlock('blockquote')}>
          <RiQuoteText className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Code Block" onClick={() => formatBlock('pre')}>
          <RiCodeLine className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Horizontal Rule" onClick={() => execAndUpdate('insertHorizontalRule')}>
          <RiSeparator className="size-4" />
        </ToolbarButton>

        <div className="w-px h-5 bg-border mx-1" />

        <ToolbarButton title="Align Left" onClick={() => execAndUpdate('justifyLeft')}>
          <RiAlignLeft className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Align Center" onClick={() => execAndUpdate('justifyCenter')}>
          <RiAlignCenter className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Align Right" onClick={() => execAndUpdate('justifyRight')}>
          <RiAlignRight className="size-4" />
        </ToolbarButton>
        <ToolbarButton title="Justify" onClick={() => execAndUpdate('justifyFull')}>
          <RiAlignJustify className="size-4" />
        </ToolbarButton>

        <div className="w-px h-5 bg-border mx-1" />

        <Popover>
          <PopoverTrigger asChild>
            <button
              type="button"
              title="Text Color"
              onMouseDown={(e) => e.preventDefault()}
              className="p-1.5 rounded hover:bg-muted transition-colors"
            >
              <div className="size-4 rounded border bg-foreground" />
            </button>
          </PopoverTrigger>
          <PopoverContent className="w-auto p-2" align="start">
            <div className="grid grid-cols-5 gap-1">
              {COLORS.map((color) => (
                <button
                  key={color}
                  type="button"
                  className="size-6 rounded border hover:scale-110 transition-transform"
                  style={{ backgroundColor: color }}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => execAndUpdate('foreColor', color)}
                />
              ))}
            </div>
            <button
              type="button"
              className="w-full mt-2 text-xs text-muted-foreground hover:text-foreground py-1"
              onMouseDown={(e) => e.preventDefault()}
              onClick={() => execAndUpdate('removeFormat')}
            >
              Reset Color
            </button>
          </PopoverContent>
        </Popover>

        <Popover>
          <PopoverTrigger asChild>
            <button type="button" title="Highlight" onMouseDown={(e) => e.preventDefault()} className="p-1.5 rounded hover:bg-muted transition-colors text-muted-foreground">
              <RiMarkPenLine className="size-4" />
            </button>
          </PopoverTrigger>
          <PopoverContent className="w-auto p-2" align="start">
            <div className="grid grid-cols-5 gap-1">
              {HIGHLIGHT_COLORS.map((c) => (
                <button
                  key={c}
                  type="button"
                  className="size-6 rounded border hover:scale-110 transition-transform"
                  style={{ backgroundColor: c }}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => execAndUpdate('hiliteColor', c)}
                />
              ))}
            </div>
            <button
              type="button"
              className="w-full mt-2 text-xs text-muted-foreground hover:text-foreground py-1"
              onMouseDown={(e) => e.preventDefault()}
              onClick={() => execAndUpdate('hiliteColor', 'transparent')}
            >
              Remove Highlight
            </button>
          </PopoverContent>
        </Popover>

        <div className="w-px h-5 bg-border mx-1" />

        <Popover open={linkOpen} onOpenChange={setLinkOpen}>
          <PopoverTrigger asChild>
            <button type="button" title="Add Link" onMouseDown={(e) => e.preventDefault()} className={`p-1.5 rounded hover:bg-muted transition-colors ${isLinkActive ? 'bg-muted text-primary' : 'text-muted-foreground'}`}>
              <RiLinkM className="size-4" />
            </button>
          </PopoverTrigger>
          <PopoverContent className="w-72 p-3" align="start">
            <div className="flex gap-2">
              <Input
                placeholder="https://example.com"
                value={linkUrl}
                onChange={(e) => setLinkUrl(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && setLink()}
                className="h-8 text-sm"
              />
              <Button size="sm" className="h-8 px-3" onClick={setLink}>Add</Button>
            </div>
          </PopoverContent>
        </Popover>

        {isLinkActive && (
          <ToolbarButton title="Remove Link" onClick={() => execAndUpdate('unlink')}>
            <RiLinkUnlinkM className="size-4" />
          </ToolbarButton>
        )}

        <ToolbarButton title="Insert Image" onClick={() => imageInputRef.current?.click()}>
          <RiImageAddLine className="size-4" />
        </ToolbarButton>

        {!hideVideoUpload && (
          <ToolbarButton title="Upload Video" onClick={() => videoInputRef.current?.click()}>
            <RiVideoLine className="size-4" />
          </ToolbarButton>
        )}

        <div className="w-px h-5 bg-border mx-1" />

        <ToolbarButton title="Clear Formatting" onClick={() => execAndUpdate('removeFormat')}>
          <RiFormatClear className="size-4" />
        </ToolbarButton>
      </div>

      <input
        ref={imageInputRef}
        type="file"
        accept="image/*"
        multiple
        className="hidden"
        onChange={handleImageUpload}
      />
      <input
        ref={videoInputRef}
        type="file"
        accept="video/*"
        className="hidden"
        onChange={handleVideoUpload}
      />

      <div
        ref={editorRef}
        contentEditable
        suppressContentEditableWarning
        onInput={handleInput}
        data-placeholder={placeholder}
        dir={dir}
        className={`tiptap prose prose-sm max-w-none focus:outline-none p-4 ${dir === 'rtl' ? 'text-right' : ''} empty:before:content-[attr(data-placeholder)] empty:before:text-gray-400 empty:before:pointer-events-none`}
        style={{ minHeight, direction: dir }}
      />
    </div>
  );
}
