import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { createRef, Ref, ref } from "lit/directives/ref.js";

// See https://rodydavis.com/posts/lit-monaco-editor for some ideas.

import * as monaco from "monaco-editor";

// Configure Monaco to use local workers with correct relative paths

// Define Monaco CSS styles as a string constant
const monacoStyles = `
  /* Import Monaco editor styles */
  @import url('./static/monaco/min/vs/editor/editor.main.css');
  
  /* Codicon font is now defined globally in sketch-app-shell.css */
  
  /* Custom Monaco styles */
  .monaco-editor {
    width: 100%;
    height: 100%;
  }
  
  /* Custom font stack - ensure we have good monospace fonts */
  .monaco-editor .view-lines,
  .monaco-editor .view-line,
  .monaco-editor-pane,
  .monaco-editor .inputarea {
    font-family: "Menlo", "Monaco", "Consolas", "Courier New", monospace !important;
    font-size: 13px !important;
    font-feature-settings: "liga" 0, "calt" 0 !important;
    line-height: 1.5 !important;
  }
  
  /* Ensure light theme colors */
  .monaco-editor, .monaco-editor-background, .monaco-editor .inputarea.ime-input {
    background-color: var(--monaco-editor-bg, #ffffff) !important;
  }
  
  .monaco-editor .margin {
    background-color: var(--monaco-editor-margin, #f5f5f5) !important;
  }
`;

// Configure Monaco to use local workers with correct relative paths
// Monaco looks for this global configuration to determine how to load web workers
// @ts-ignore - MonacoEnvironment is added to the global scope at runtime
self.MonacoEnvironment = {
  getWorkerUrl: function (_moduleId, label) {
    if (label === "json") {
      return "./static/json.worker.js";
    }
    if (label === "css" || label === "scss" || label === "less") {
      return "./static/css.worker.js";
    }
    if (label === "html" || label === "handlebars" || label === "razor") {
      return "./static/html.worker.js";
    }
    if (label === "typescript" || label === "javascript") {
      return "./static/ts.worker.js";
    }
    return "./static/editor.worker.js";
  },
};

@customElement("sketch-monaco-view")
export class CodeDiffEditor extends LitElement {
  // Editable state
  @property({ type: Boolean, attribute: "editable-right" })
  editableRight?: boolean;
  private container: Ref<HTMLElement> = createRef();
  editor?: monaco.editor.IStandaloneDiffEditor;

  // Save state properties
  @state() private saveState: "idle" | "modified" | "saving" | "saved" = "idle";
  @state() private debounceSaveTimeout: number | null = null;
  @state() private lastSavedContent: string = "";
  @property() originalCode?: string = "// Original code here";
  @property() modifiedCode?: string = "// Modified code here";
  @property() originalFilename?: string = "original.js";
  @property() modifiedFilename?: string = "modified.js";

  /* Selected text and indicators */
  @state()
  private selectedText: string | null = null;

  @state()
  private selectionRange: {
    startLineNumber: number;
    startColumn: number;
    endLineNumber: number;
    endColumn: number;
  } | null = null;

  @state()
  private showCommentIndicator: boolean = false;

  @state()
  private indicatorPosition: { top: number; left: number } = {
    top: 0,
    left: 0,
  };

  @state()
  private showCommentBox: boolean = false;

  @state()
  private commentText: string = "";

  @state()
  private activeEditor: "original" | "modified" = "modified"; // Track which editor is active

  // Custom event to request save action from external components
  private requestSave() {
    if (!this.editableRight || this.saveState !== "modified") return;

    this.saveState = "saving";

    // Get current content from modified editor
    const modifiedContent = this.modifiedModel?.getValue() || "";

    // Create and dispatch the save event
    const saveEvent = new CustomEvent("monaco-save", {
      detail: {
        path: this.modifiedFilename,
        content: modifiedContent,
      },
      bubbles: true,
      composed: true,
    });

    this.dispatchEvent(saveEvent);
  }

  // Method to be called from parent when save is complete
  public notifySaveComplete(success: boolean) {
    if (success) {
      this.saveState = "saved";
      // Update last saved content
      this.lastSavedContent = this.modifiedModel?.getValue() || "";
      // Reset to idle after a delay
      setTimeout(() => {
        this.saveState = "idle";
      }, 2000);
    } else {
      // Return to modified state on error
      this.saveState = "modified";
    }
  }

  // Rescue people with strong save-constantly habits
  private setupKeyboardShortcuts() {
    if (!this.editor) return;
    const modifiedEditor = this.editor.getModifiedEditor();
    if (!modifiedEditor) return;

    modifiedEditor.addCommand(
      monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
      () => {
        this.requestSave();
      }
    );

    console.log("Keyboard shortcuts set up for Monaco editor");
  }

  // Setup content change listener for debounced save
  private setupContentChangeListener() {
    if (!this.editor || !this.editableRight) return;

    const modifiedEditor = this.editor.getModifiedEditor();
    if (!modifiedEditor || !modifiedEditor.getModel()) return;

    // Store initial content
    this.lastSavedContent = modifiedEditor.getModel()!.getValue();

    // Listen for content changes
    modifiedEditor.getModel()!.onDidChangeContent(() => {
      const currentContent = modifiedEditor.getModel()!.getValue();

      // Check if content has actually changed from last saved state
      if (currentContent !== this.lastSavedContent) {
        this.saveState = "modified";

        // Debounce save request
        if (this.debounceSaveTimeout) {
          window.clearTimeout(this.debounceSaveTimeout);
        }

        this.debounceSaveTimeout = window.setTimeout(() => {
          this.requestSave();
          this.debounceSaveTimeout = null;
        }, 1000); // 1 second debounce
      }
    });
  }

  static styles = css`
    /* Save indicator styles */
    .save-indicator {
      position: absolute;
      top: 4px;
      right: 4px;
      padding: 3px 8px;
      border-radius: 3px;
      font-size: 12px;
      font-family: system-ui, sans-serif;
      color: white;
      z-index: 100;
      opacity: 0.9;
      pointer-events: none;
      transition: opacity 0.3s ease;
    }

    .save-indicator.idle {
      background-color: #6c757d;
    }

    .save-indicator.modified {
      background-color: #f0ad4e;
    }

    .save-indicator.saving {
      background-color: #5bc0de;
    }

    .save-indicator.saved {
      background-color: #5cb85c;
    }

    /* Editor host styles */
    :host {
      --editor-width: 100%;
      --editor-height: 100%;
      display: flex;
      flex: 1;
      min-height: 0; /* Critical for flex layout */
      position: relative; /* Establish positioning context */
      height: 100%; /* Take full height */
      width: 100%; /* Take full width */
    }
    main {
      width: var(--editor-width);
      height: var(--editor-height);
      border: 1px solid #e0e0e0;
      flex: 1;
      min-height: 300px; /* Ensure a minimum height for the editor */
      position: absolute; /* Absolute positioning to take full space */
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }

    /* Comment indicator and box styles */
    .comment-indicator {
      position: fixed;
      background-color: rgba(66, 133, 244, 0.9);
      color: white;
      border-radius: 3px;
      padding: 3px 8px;
      font-size: 12px;
      cursor: pointer;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
      z-index: 10000;
      animation: fadeIn 0.2s ease-in-out;
      display: flex;
      align-items: center;
      gap: 4px;
      pointer-events: all;
    }

    .comment-indicator:hover {
      background-color: rgba(66, 133, 244, 1);
    }

    .comment-indicator span {
      line-height: 1;
    }

    .comment-box {
      position: fixed;
      background-color: white;
      border: 1px solid #ddd;
      border-radius: 4px;
      box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);
      padding: 12px;
      z-index: 10001;
      width: 350px;
      animation: fadeIn 0.2s ease-in-out;
      max-height: 80vh;
      overflow-y: auto;
    }

    .comment-box-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 8px;
    }

    .comment-box-header h3 {
      margin: 0;
      font-size: 14px;
      font-weight: 500;
    }

    .close-button {
      background: none;
      border: none;
      cursor: pointer;
      font-size: 16px;
      color: #666;
      padding: 2px 6px;
    }

    .close-button:hover {
      color: #333;
    }

    .selected-text-preview {
      background-color: #f5f5f5;
      border: 1px solid #eee;
      border-radius: 3px;
      padding: 8px;
      margin-bottom: 10px;
      font-family: monospace;
      font-size: 12px;
      max-height: 80px;
      overflow-y: auto;
      white-space: pre-wrap;
      word-break: break-all;
    }

    .comment-textarea {
      width: 100%;
      min-height: 80px;
      padding: 8px;
      border: 1px solid #ddd;
      border-radius: 3px;
      resize: vertical;
      font-family: inherit;
      margin-bottom: 10px;
      box-sizing: border-box;
    }

    .comment-actions {
      display: flex;
      justify-content: flex-end;
      gap: 8px;
    }

    .comment-actions button {
      padding: 6px 12px;
      border-radius: 3px;
      cursor: pointer;
      font-size: 12px;
    }

    .cancel-button {
      background-color: transparent;
      border: 1px solid #ddd;
    }

    .cancel-button:hover {
      background-color: #f5f5f5;
    }

    .submit-button {
      background-color: #4285f4;
      color: white;
      border: none;
    }

    .submit-button:hover {
      background-color: #3367d6;
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
  `;

  render() {
    return html`
      <style>
        ${monacoStyles}
      </style>
      <main ${ref(this.container)}></main>

      <!-- Save indicator - shown when editing -->
      ${this.editableRight
        ? html`
            <div class="save-indicator ${this.saveState}">
              ${this.saveState === "idle"
                ? "Editable"
                : this.saveState === "modified"
                  ? "Modified..."
                  : this.saveState === "saving"
                    ? "Saving..."
                    : this.saveState === "saved"
                      ? "Saved"
                      : ""}
            </div>
          `
        : ""}

      <!-- Comment indicator - shown when text is selected -->
      ${this.showCommentIndicator
        ? html`
            <div
              class="comment-indicator"
              style="top: ${this.indicatorPosition.top}px; left: ${this
                .indicatorPosition.left}px;"
              @click="${this.handleIndicatorClick}"
              @mouseenter="${() => {
                this._isHovering = true;
              }}"
              @mouseleave="${() => {
                this._isHovering = false;
              }}"
            >
              <span>💬</span>
              <span>Add comment</span>
            </div>
          `
        : ""}

      <!-- Comment box - shown when indicator is clicked -->
      ${this.showCommentBox
        ? html`
            <div
              class="comment-box"
              style="${this.calculateCommentBoxPosition()}"
              @mouseenter="${() => {
                this._isHovering = true;
              }}"
              @mouseleave="${() => {
                this._isHovering = false;
              }}"
            >
              <div class="comment-box-header">
                <h3>Add comment</h3>
                <button class="close-button" @click="${this.closeCommentBox}">
                  ×
                </button>
              </div>
              <div class="selected-text-preview">${this.selectedText}</div>
              <textarea
                class="comment-textarea"
                placeholder="Type your comment here..."
                .value="${this.commentText}"
                @input="${this.handleCommentInput}"
              ></textarea>
              <div class="comment-actions">
                <button class="cancel-button" @click="${this.closeCommentBox}">
                  Cancel
                </button>
                <button class="submit-button" @click="${this.submitComment}">
                  Add
                </button>
              </div>
            </div>
          `
        : ""}
    `;
  }

  /**
   * Calculate the optimal position for the comment box to keep it in view
   */
  private calculateCommentBoxPosition(): string {
    // Get viewport dimensions
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    // Default position (below indicator)
    let top = this.indicatorPosition.top + 30;
    let left = this.indicatorPosition.left;

    // Estimated box dimensions
    const boxWidth = 350;
    const boxHeight = 300;

    // Check if box would go off the right edge
    if (left + boxWidth > viewportWidth) {
      left = viewportWidth - boxWidth - 20; // Keep 20px margin
    }

    // Check if box would go off the bottom
    const bottomSpace = viewportHeight - top;
    if (bottomSpace < boxHeight) {
      // Not enough space below, try to position above if possible
      if (this.indicatorPosition.top > boxHeight) {
        // Position above the indicator
        top = this.indicatorPosition.top - boxHeight - 10;
      } else {
        // Not enough space above either, position at top of viewport with margin
        top = 10;
      }
    }

    // Ensure box is never positioned off-screen
    top = Math.max(10, top);
    left = Math.max(10, left);

    return `top: ${top}px; left: ${left}px;`;
  }

  setOriginalCode(code: string, filename?: string) {
    this.originalCode = code;
    if (filename) {
      this.originalFilename = filename;
    }

    // Update the model if the editor is initialized
    if (this.editor) {
      const model = this.editor.getOriginalEditor().getModel();
      if (model) {
        model.setValue(code);
        if (filename) {
          monaco.editor.setModelLanguage(
            model,
            this.getLanguageForFile(filename),
          );
        }
      }
    }
  }

  setModifiedCode(code: string, filename?: string) {
    this.modifiedCode = code;
    if (filename) {
      this.modifiedFilename = filename;
    }

    // Update the model if the editor is initialized
    if (this.editor) {
      const model = this.editor.getModifiedEditor().getModel();
      if (model) {
        model.setValue(code);
        if (filename) {
          monaco.editor.setModelLanguage(
            model,
            this.getLanguageForFile(filename),
          );
        }
      }
    }
  }

  private _extensionToLanguageMap: Map<string, string> | null = null;

  private getLanguageForFile(filename: string): string {
    // Get the file extension (including the dot for exact matching)
    const extension = "." + (filename.split(".").pop()?.toLowerCase() || "");

    // Build the extension-to-language map on first use
    if (!this._extensionToLanguageMap) {
      this._extensionToLanguageMap = new Map();
      const languages = monaco.languages.getLanguages();

      for (const language of languages) {
        if (language.extensions) {
          for (const ext of language.extensions) {
            // Monaco extensions already include the dot, so use them directly
            this._extensionToLanguageMap.set(ext.toLowerCase(), language.id);
          }
        }
      }
    }

    return this._extensionToLanguageMap.get(extension) || "plaintext";
  }

  /**
   * Update editor options
   */
  setOptions(value: monaco.editor.IDiffEditorConstructionOptions) {
    if (this.editor) {
      this.editor.updateOptions(value);
    }
  }

  /**
   * Toggle hideUnchangedRegions feature
   */
  toggleHideUnchangedRegions(enabled: boolean) {
    if (this.editor) {
      this.editor.updateOptions({
        hideUnchangedRegions: {
          enabled: enabled,
          contextLineCount: 3,
          minimumLineCount: 3,
          revealLineCount: 10,
        },
      });
    }
  }

  // Models for the editor
  private originalModel?: monaco.editor.ITextModel;
  private modifiedModel?: monaco.editor.ITextModel;

  private initializeEditor() {
    try {
      // Disable semantic validation globally for TypeScript/JavaScript
      monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
        noSemanticValidation: true,
      });
      monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
        noSemanticValidation: true,
      });

      // First time initialization
      if (!this.editor) {
        // Create the diff editor only once
        this.editor = monaco.editor.createDiffEditor(this.container.value!, {
          automaticLayout: true,
          // Make it read-only by default
          // We'll adjust individual editor settings after creation
          readOnly: true,
          theme: "vs", // Always use light mode
          renderSideBySide: true,
          ignoreTrimWhitespace: false,
          // Focus on the differences by hiding unchanged regions
          hideUnchangedRegions: {
            enabled: true, // Enable the feature
            contextLineCount: 3, // Show 3 lines of context around each difference
            minimumLineCount: 3, // Hide regions only when they're at least 3 lines
            revealLineCount: 10, // Show 10 lines when expanding a hidden region
          },
        });

        console.log("Monaco diff editor created");

        // Set up selection change event listeners for both editors
        this.setupSelectionChangeListeners();

        this.setupKeyboardShortcuts();

        // If this is an editable view, set the correct read-only state for each editor
        if (this.editableRight) {
          // Make sure the original editor is always read-only
          this.editor.getOriginalEditor().updateOptions({ readOnly: true });
          // Make sure the modified editor is editable
          this.editor.getModifiedEditor().updateOptions({ readOnly: false });
        }
      }

      // Create or update models
      this.updateModels();
      // Set up content change listener
      this.setupContentChangeListener();

      // Force layout recalculation after a short delay
      // This ensures the editor renders properly, especially with single files
      setTimeout(() => {
        if (this.editor) {
          this.editor.layout();
          console.log("Monaco diff editor layout updated");
        }
      }, 50);

      console.log("Monaco diff editor initialized");
    } catch (error) {
      console.error("Error initializing Monaco editor:", error);
    }
  }

  /**
   * Sets up event listeners for text selection in both editors.
   * This enables showing the comment UI when users select text and
   * manages the visibility of UI components based on user interactions.
   */
  private setupSelectionChangeListeners() {
    try {
      if (!this.editor) {
        console.log("Editor not available for setting up listeners");
        return;
      }

      // Get both original and modified editors
      const originalEditor = this.editor.getOriginalEditor();
      const modifiedEditor = this.editor.getModifiedEditor();

      if (!originalEditor || !modifiedEditor) {
        console.log("Original or modified editor not available");
        return;
      }

      // Add selection change listener to original editor
      originalEditor.onDidChangeCursorSelection((e) => {
        this.handleSelectionChange(e, originalEditor, "original");
      });

      // Add selection change listener to modified editor
      modifiedEditor.onDidChangeCursorSelection((e) => {
        this.handleSelectionChange(e, modifiedEditor, "modified");
      });

      // Create a debounced function for mouse move handling
      let mouseMoveTimeout: number | null = null;
      const handleMouseMove = () => {
        // Clear any existing timeout
        if (mouseMoveTimeout) {
          window.clearTimeout(mouseMoveTimeout);
        }

        // If there's text selected and we're not showing the comment box, keep indicator visible
        if (this.selectedText && !this.showCommentBox) {
          this.showCommentIndicator = true;
          this.requestUpdate();
        }

        // Set a new timeout to hide the indicator after a delay
        mouseMoveTimeout = window.setTimeout(() => {
          // Only hide if we're not showing the comment box and not actively hovering
          if (!this.showCommentBox && !this._isHovering) {
            this.showCommentIndicator = false;
            this.requestUpdate();
          }
        }, 2000); // Hide after 2 seconds of inactivity
      };

      // Add mouse move listeners with debouncing
      originalEditor.onMouseMove(() => handleMouseMove());
      modifiedEditor.onMouseMove(() => handleMouseMove());

      // Track hover state over the indicator and comment box
      this._isHovering = false;

      // Use the global document click handler to detect clicks outside
      this._documentClickHandler = (e: MouseEvent) => {
        try {
          const target = e.target as HTMLElement;
          const isIndicator =
            target.matches(".comment-indicator") ||
            !!target.closest(".comment-indicator");
          const isCommentBox =
            target.matches(".comment-box") || !!target.closest(".comment-box");

          // If click is outside our UI elements
          if (!isIndicator && !isCommentBox) {
            // If we're not showing the comment box, hide the indicator
            if (!this.showCommentBox) {
              this.showCommentIndicator = false;
              this.requestUpdate();
            }
          }
        } catch (error) {
          console.error("Error in document click handler:", error);
        }
      };

      // Add the document click listener
      document.addEventListener("click", this._documentClickHandler);

      console.log("Selection change listeners set up successfully");
    } catch (error) {
      console.error("Error setting up selection listeners:", error);
    }
  }

  // Track mouse hover state
  private _isHovering = false;

  // Store document click handler for cleanup
  private _documentClickHandler: ((e: MouseEvent) => void) | null = null;

  /**
   * Handle selection change events from either editor
   */
  private handleSelectionChange(
    e: monaco.editor.ICursorSelectionChangedEvent,
    editor: monaco.editor.IStandaloneCodeEditor,
    editorType: "original" | "modified",
  ) {
    try {
      // If we're not making a selection (just moving cursor), do nothing
      if (e.selection.isEmpty()) {
        // Don't hide indicator or box if already shown
        if (!this.showCommentBox) {
          this.selectedText = null;
          this.selectionRange = null;
          this.showCommentIndicator = false;
        }
        return;
      }

      // Get selected text
      const model = editor.getModel();
      if (!model) {
        console.log("No model available for selection");
        return;
      }

      // Make sure selection is within valid range
      const lineCount = model.getLineCount();
      if (
        e.selection.startLineNumber > lineCount ||
        e.selection.endLineNumber > lineCount
      ) {
        console.log("Selection out of bounds");
        return;
      }

      // Store which editor is active
      this.activeEditor = editorType;

      // Store selection range
      this.selectionRange = {
        startLineNumber: e.selection.startLineNumber,
        startColumn: e.selection.startColumn,
        endLineNumber: e.selection.endLineNumber,
        endColumn: e.selection.endColumn,
      };

      try {
        // Expand selection to full lines for better context
        const expandedSelection = {
          startLineNumber: e.selection.startLineNumber,
          startColumn: 1, // Start at beginning of line
          endLineNumber: e.selection.endLineNumber,
          endColumn: model.getLineMaxColumn(e.selection.endLineNumber), // End at end of line
        };

        // Get the selected text using the expanded selection
        this.selectedText = model.getValueInRange(expandedSelection);

        // Update the selection range to reflect the full lines
        this.selectionRange = {
          startLineNumber: expandedSelection.startLineNumber,
          startColumn: expandedSelection.startColumn,
          endLineNumber: expandedSelection.endLineNumber,
          endColumn: expandedSelection.endColumn,
        };
      } catch (error) {
        console.error("Error getting selected text:", error);
        return;
      }

      // If there's selected text, show the indicator
      if (this.selectedText && this.selectedText.trim() !== "") {
        // Calculate indicator position safely
        try {
          // Use the editor's DOM node as positioning context
          const editorDomNode = editor.getDomNode();
          if (!editorDomNode) {
            console.log("No editor DOM node available");
            return;
          }

          // Get position from editor
          const position = {
            lineNumber: e.selection.endLineNumber,
            column: e.selection.endColumn,
          };

          // Use editor's built-in method for coordinate conversion
          const selectionCoords = editor.getScrolledVisiblePosition(position);

          if (selectionCoords) {
            // Get accurate DOM position for the selection end
            const editorRect = editorDomNode.getBoundingClientRect();

            // Calculate the actual screen position
            const screenLeft = editorRect.left + selectionCoords.left;
            const screenTop = editorRect.top + selectionCoords.top;

            // Store absolute screen coordinates
            this.indicatorPosition = {
              top: screenTop,
              left: screenLeft + 10, // Slight offset
            };

            // Check window boundaries to ensure the indicator stays visible
            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;

            // Keep indicator within viewport bounds
            if (this.indicatorPosition.left + 150 > viewportWidth) {
              this.indicatorPosition.left = viewportWidth - 160;
            }

            if (this.indicatorPosition.top + 40 > viewportHeight) {
              this.indicatorPosition.top = viewportHeight - 50;
            }

            // Show the indicator
            this.showCommentIndicator = true;

            // Request an update to ensure UI reflects changes
            this.requestUpdate();
          }
        } catch (error) {
          console.error("Error positioning comment indicator:", error);
        }
      }
    } catch (error) {
      console.error("Error handling selection change:", error);
    }
  }

  /**
   * Handle click on the comment indicator
   */
  private handleIndicatorClick(e: Event) {
    try {
      e.stopPropagation();
      e.preventDefault();

      this.showCommentBox = true;
      this.commentText = ""; // Reset comment text

      // Don't hide the indicator while comment box is shown
      this.showCommentIndicator = true;

      // Ensure UI updates
      this.requestUpdate();
    } catch (error) {
      console.error("Error handling indicator click:", error);
    }
  }

  /**
   * Handle changes to the comment text
   */
  private handleCommentInput(e: Event) {
    const target = e.target as HTMLTextAreaElement;
    this.commentText = target.value;
  }

  /**
   * Close the comment box
   */
  private closeCommentBox() {
    this.showCommentBox = false;
    // Also hide the indicator
    this.showCommentIndicator = false;
  }

  /**
   * Submit the comment
   */
  private submitComment() {
    try {
      if (!this.selectedText || !this.commentText) {
        console.log("Missing selected text or comment");
        return;
      }

      // Get the correct filename based on active editor
      const fileContext =
        this.activeEditor === "original"
          ? this.originalFilename || "Original file"
          : this.modifiedFilename || "Modified file";

      // Include editor info to make it clear which version was commented on
      const editorLabel =
        this.activeEditor === "original" ? "[Original]" : "[Modified]";

      // Add line number information if available
      let lineInfo = "";
      if (this.selectionRange) {
        const startLine = this.selectionRange.startLineNumber;
        const endLine = this.selectionRange.endLineNumber;
        if (startLine === endLine) {
          lineInfo = ` (line ${startLine})`;
        } else {
          lineInfo = ` (lines ${startLine}-${endLine})`;
        }
      }

      // Format the comment in a readable way
      const formattedComment = `\`\`\`\n${fileContext} ${editorLabel}${lineInfo}:\n${this.selectedText}\n\`\`\`\n\n${this.commentText}`;

      // Close UI before dispatching to prevent interaction conflicts
      this.closeCommentBox();

      // Use setTimeout to ensure the UI has updated before sending the event
      setTimeout(() => {
        try {
          // Dispatch a custom event with the comment details
          const event = new CustomEvent("monaco-comment", {
            detail: {
              fileContext,
              selectedText: this.selectedText,
              commentText: this.commentText,
              formattedComment,
              selectionRange: this.selectionRange,
              activeEditor: this.activeEditor,
            },
            bubbles: true,
            composed: true,
          });

          this.dispatchEvent(event);
        } catch (error) {
          console.error("Error dispatching comment event:", error);
        }
      }, 0);
    } catch (error) {
      console.error("Error submitting comment:", error);
      this.closeCommentBox();
    }
  }

  private updateModels() {
    try {
      // Get language based on filename
      const originalLang = this.getLanguageForFile(this.originalFilename || "");
      const modifiedLang = this.getLanguageForFile(this.modifiedFilename || "");

      // Always create new models with unique URIs based on timestamp to avoid conflicts
      const timestamp = new Date().getTime();
      // TODO: Could put filename in these URIs; unclear how they're used right now.
      const originalUri = monaco.Uri.parse(
        `file:///original-${timestamp}.${originalLang}`,
      );
      const modifiedUri = monaco.Uri.parse(
        `file:///modified-${timestamp}.${modifiedLang}`,
      );

      // Store references to old models
      const oldOriginalModel = this.originalModel;
      const oldModifiedModel = this.modifiedModel;

      // Nullify instance variables to prevent accidental use
      this.originalModel = undefined;
      this.modifiedModel = undefined;

      // Clear the editor model first to release Monaco's internal references
      if (this.editor) {
        this.editor.setModel(null);
      }

      // Now it's safe to dispose the old models
      if (oldOriginalModel) {
        oldOriginalModel.dispose();
      }

      if (oldModifiedModel) {
        oldModifiedModel.dispose();
      }

      // Create new models
      this.originalModel = monaco.editor.createModel(
        this.originalCode || "",
        originalLang,
        originalUri,
      );

      this.modifiedModel = monaco.editor.createModel(
        this.modifiedCode || "",
        modifiedLang,
        modifiedUri,
      );

      // Set the new models on the editor
      if (this.editor) {
        this.editor.setModel({
          original: this.originalModel,
          modified: this.modifiedModel,
        });
      }
      this.setupContentChangeListener();
    } catch (error) {
      console.error("Error updating Monaco models:", error);
    }
  }

  updated(changedProperties: Map<string, any>) {
    // If any relevant properties changed, just update the models
    if (
      changedProperties.has("originalCode") ||
      changedProperties.has("modifiedCode") ||
      changedProperties.has("originalFilename") ||
      changedProperties.has("modifiedFilename") ||
      changedProperties.has("editableRight")
    ) {
      if (this.editor) {
        this.updateModels();

        // Force layout recalculation after model updates
        setTimeout(() => {
          if (this.editor) {
            this.editor.layout();
          }
        }, 50);
      } else {
        // If the editor isn't initialized yet but we received content,
        // initialize it now
        this.initializeEditor();
      }
    }
  }

  // Add resize observer to ensure editor resizes when container changes
  firstUpdated() {
    // Initialize the editor
    this.initializeEditor();

    // Create a ResizeObserver to monitor container size changes
    if (window.ResizeObserver) {
      const resizeObserver = new ResizeObserver(() => {
        if (this.editor) {
          this.editor.layout();
        }
      });

      // Start observing the container
      if (this.container.value) {
        resizeObserver.observe(this.container.value);
      }

      // Store the observer for cleanup
      this._resizeObserver = resizeObserver;
    }

    // If editable, set up edit mode and content change listener
    if (this.editableRight && this.editor) {
      // Ensure the original editor is read-only
      this.editor.getOriginalEditor().updateOptions({ readOnly: true });
      // Ensure the modified editor is editable
      this.editor.getModifiedEditor().updateOptions({ readOnly: false });
    }
  }

  private _resizeObserver: ResizeObserver | null = null;

  disconnectedCallback() {
    super.disconnectedCallback();

    try {
      // Clean up resources when element is removed
      if (this.editor) {
        this.editor.dispose();
        this.editor = undefined;
      }

      // Dispose models to prevent memory leaks
      if (this.originalModel) {
        this.originalModel.dispose();
        this.originalModel = undefined;
      }

      if (this.modifiedModel) {
        this.modifiedModel.dispose();
        this.modifiedModel = undefined;
      }

      // Clean up resize observer
      if (this._resizeObserver) {
        this._resizeObserver.disconnect();
        this._resizeObserver = null;
      }

      // Remove document click handler if set
      if (this._documentClickHandler) {
        document.removeEventListener("click", this._documentClickHandler);
        this._documentClickHandler = null;
      }
    } catch (error) {
      console.error("Error in disconnectedCallback:", error);
    }
  }

  // disconnectedCallback implementation is defined below
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-monaco-view": CodeDiffEditor;
  }
}
