"use client";

import { CKEditor } from "@ckeditor/ckeditor5-react";
import {
  ClassicEditor,
  Bold,
  Italic,
  Underline,
  Strikethrough,
  Subscript,
  Superscript,
  Font,
  FontSize,
  FontFamily,
  FontColor,
  FontBackgroundColor,
  Essentials,
  Paragraph,
  Heading,
  Link,
  List,
  Indent,
  IndentBlock,
  BlockQuote,
  CodeBlock,
  Alignment,
  Table,
  TableToolbar,
  TableCellProperties,
  TableProperties,
  Image,
  ImageToolbar,
  ImageCaption,
  ImageStyle,
  ImageResize,
  ImageUpload,
  MediaEmbed,
  HorizontalLine,
  RemoveFormat,
  SourceEditing,
  type Editor,
} from "ckeditor5";

import "ckeditor5/ckeditor5.css";

interface CKEditorWrapperProps {
  value: string;
  onChange: (value: string) => void;
  uploadEndpoint: string;
  placeholder?: string;
}

// Custom upload adapter that sends the image file to our own endpoint
// (which forwards it to the external upload server) instead of CKEditor's
// default base64 embedding.
class CustomUploadAdapter {
  loader: any;
  uploadEndpoint: string;

  constructor(loader: any, uploadEndpoint: string) {
    this.loader = loader;
    this.uploadEndpoint = uploadEndpoint;
  }

  async upload() {
    const file = await this.loader.file;

    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch(this.uploadEndpoint, {
      method: "POST",
      body: formData,
    });

    const result = await response.json();

    if (!result.success || !result.url) {
      throw result.message || "Image upload failed";
    }

    return { default: result.url };
  }

  abort() {
    // no-op: fetch requests here aren't cancellable without extra
    // AbortController wiring, which isn't needed for typical usage
  }
}

export default function CKEditorWrapper({
  value,
  onChange,
  uploadEndpoint,
  placeholder,
}: CKEditorWrapperProps) {
  return (
    <CKEditor
      editor={ClassicEditor}
      data={value}
      config={{
        licenseKey: "GPL",
        plugins: [
          Essentials,
          Paragraph,
          Heading,
          Bold,
          Italic,
          Underline,
          Strikethrough,
          Subscript,
          Superscript,
          Font,
          FontSize,
          FontFamily,
          FontColor,
          FontBackgroundColor,
          Link,
          List,
          Indent,
          IndentBlock,
          BlockQuote,
          CodeBlock,
          Alignment,
          Table,
          TableToolbar,
          TableCellProperties,
          TableProperties,
          Image,
          ImageToolbar,
          ImageCaption,
          ImageStyle,
          ImageResize,
          ImageUpload,
          MediaEmbed,
          HorizontalLine,
          RemoveFormat,
          SourceEditing,
        ],
        toolbar: [
          "undo",
          "redo",
          "|",
          "heading",
          "|",
          "fontFamily",
          "fontSize",
          "fontColor",
          "fontBackgroundColor",
          "|",
          "bold",
          "italic",
          "underline",
          "strikethrough",
          "subscript",
          "superscript",
          "removeFormat",
          "|",
          "alignment",
          "bulletedList",
          "numberedList",
          "outdent",
          "indent",
          "|",
          "link",
          "insertTable",
          "blockQuote",
          "codeBlock",
          "horizontalLine",
          "mediaEmbed",
          "uploadImage",
          "|",
          "sourceEditing",
        ],
        image: {
          toolbar: [
            "imageStyle:inline",
            "imageStyle:block",
            "imageStyle:side",
            "|",
            "toggleImageCaption",
            "imageTextAlternative",
            "|",
            "resizeImage",
          ],
        },
        table: {
          contentToolbar: [
            "tableColumn",
            "tableRow",
            "mergeTableCells",
            "tableProperties",
            "tableCellProperties",
          ],
        },
        placeholder,
      }}
      onReady={(editor: Editor) => {
        // @ts-ignore - FileRepository is available on the editor's plugin registry
        editor.plugins.get("FileRepository").createUploadAdapter = (
          loader: any
        ) => new CustomUploadAdapter(loader, uploadEndpoint);
      }}
      onChange={(_event, editor) => {
        onChange(editor.getData());
      }}
    />
  );
}