// sketch-diff-file-picker.ts
// Component for selecting files from a diff

import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { GitDiffFile } from "./git-data-service";

/**
 * Component for selecting files from a diff with next/previous navigation
 */
@customElement("sketch-diff-file-picker")
export class SketchDiffFilePicker extends LitElement {
  @property({ type: Array })
  files: GitDiffFile[] = [];

  @property({ type: String })
  selectedPath: string = "";

  @state()
  private selectedIndex: number = -1;

  static styles = css`
    :host {
      display: block;
      width: 100%;
      font-family: var(--font-family, system-ui, sans-serif);
    }

    .file-picker {
      display: flex;
      gap: 8px;
      align-items: center;
      background-color: var(--background-light, #f8f8f8);
      border-radius: 4px;
      border: 1px solid var(--border-color, #e0e0e0);
      padding: 8px 12px;
      width: 100%;
      box-sizing: border-box;
    }

    .file-select {
      flex: 1;
      min-width: 200px;
      max-width: calc(
        100% - 230px
      ); /* Leave space for the navigation buttons and file info */
      overflow: hidden;
    }

    select {
      width: 100%;
      max-width: 100%;
      padding: 8px 12px;
      border-radius: 4px;
      border: 1px solid var(--border-color, #e0e0e0);
      background-color: white;
      font-size: 14px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .navigation-buttons {
      display: flex;
      gap: 8px;
    }

    button {
      padding: 8px 12px;
      background-color: var(--button-bg, #4a7dfc);
      color: var(--button-text, white);
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
      transition: background-color 0.2s;
    }

    button:hover {
      background-color: var(--button-hover, #3a6eee);
    }

    button:disabled {
      background-color: var(--button-disabled, #cccccc);
      cursor: not-allowed;
    }

    .file-info {
      font-size: 14px;
      color: var(--text-muted, #666);
      margin-left: 8px;
      white-space: nowrap;
    }

    .no-files {
      color: var(--text-muted, #666);
      font-style: italic;
    }

    @media (max-width: 768px) {
      .file-picker {
        flex-direction: column;
        align-items: stretch;
      }

      .file-select {
        max-width: 100%; /* Full width on small screens */
        margin-bottom: 8px;
      }

      .navigation-buttons {
        width: 100%;
        justify-content: space-between;
      }

      .file-info {
        margin-left: 0;
        margin-top: 8px;
        text-align: center;
      }
    }
  `;

  updated(changedProperties: Map<string, any>) {
    // If files changed, reset the selection
    if (changedProperties.has("files")) {
      this.updateSelectedIndex();
    }

    // If selectedPath changed externally, update the index
    if (changedProperties.has("selectedPath")) {
      this.updateSelectedIndex();
    }
  }

  connectedCallback() {
    super.connectedCallback();
    // Initialize the selection when the component is connected, but only if files exist
    if (this.files && this.files.length > 0) {
      this.updateSelectedIndex();

      // Explicitly trigger file selection event for the first file when there's only one file
      // This ensures the diff view is updated even when navigation buttons aren't clicked
      if (this.files.length === 1) {
        this.selectFileByIndex(0);
      }
    }
  }

  render() {
    if (!this.files || this.files.length === 0) {
      return html`<div class="no-files">No files to display</div>`;
    }

    return html`
      <div class="file-picker">
        <div class="file-select">
          <select @change=${this.handleSelect}>
            ${this.files.map(
              (file, index) => html`
                <option
                  value=${index}
                  ?selected=${index === this.selectedIndex}
                >
                  ${this.formatFileOption(file)}
                </option>
              `,
            )}
          </select>
        </div>

        <div class="navigation-buttons">
          <button
            @click=${this.handlePrevious}
            ?disabled=${this.selectedIndex <= 0}
          >
            Previous
          </button>
          <button
            @click=${this.handleNext}
            ?disabled=${this.selectedIndex >= this.files.length - 1}
          >
            Next
          </button>
        </div>

        ${this.selectedIndex >= 0 ? this.renderFileInfo() : ""}
      </div>
    `;
  }

  renderFileInfo() {
    const file = this.files[this.selectedIndex];
    return html`
      <div class="file-info">
        ${this.getFileStatusName(file.status)} | ${this.selectedIndex + 1} of
        ${this.files.length}
      </div>
    `;
  }

  /**
   * Format a file for display in the dropdown
   */
  formatFileOption(file: GitDiffFile): string {
    const statusSymbol = this.getFileStatusSymbol(file.status);
    return `${statusSymbol} ${file.path}`;
  }

  /**
   * Get a short symbol for the file status
   */
  getFileStatusSymbol(status: string): string {
    switch (status.toUpperCase()) {
      case "A":
        return "+";
      case "M":
        return "M";
      case "D":
        return "-";
      case "R":
        return "R";
      default:
        return "?";
    }
  }

  /**
   * Get a descriptive name for the file status
   */
  getFileStatusName(status: string): string {
    switch (status.toUpperCase()) {
      case "A":
        return "Added";
      case "M":
        return "Modified";
      case "D":
        return "Deleted";
      case "R":
        return "Renamed";
      default:
        return "Unknown";
    }
  }

  /**
   * Handle file selection from dropdown
   */
  handleSelect(event: Event) {
    const select = event.target as HTMLSelectElement;
    const index = parseInt(select.value, 10);
    this.selectFileByIndex(index);
  }

  /**
   * Handle previous button click
   */
  handlePrevious() {
    if (this.selectedIndex > 0) {
      this.selectFileByIndex(this.selectedIndex - 1);
    }
  }

  /**
   * Handle next button click
   */
  handleNext() {
    if (this.selectedIndex < this.files.length - 1) {
      this.selectFileByIndex(this.selectedIndex + 1);
    }
  }

  /**
   * Select a file by index and dispatch event
   */
  selectFileByIndex(index: number) {
    if (index >= 0 && index < this.files.length) {
      this.selectedIndex = index;
      this.selectedPath = this.files[index].path;

      const event = new CustomEvent("file-selected", {
        detail: { file: this.files[index] },
        bubbles: true,
        composed: true,
      });

      this.dispatchEvent(event);
    }
  }

  /**
   * Update the selected index based on the selectedPath
   */
  private updateSelectedIndex() {
    // Add defensive check for files array
    if (!this.files || this.files.length === 0) {
      this.selectedIndex = -1;
      return;
    }

    if (this.selectedPath) {
      // Find the file with the matching path
      const index = this.files.findIndex(
        (file) => file.path === this.selectedPath,
      );
      if (index >= 0) {
        this.selectedIndex = index;
        return;
      }
    }

    // Default to first file if no match or no path
    this.selectedIndex = 0;
    const newSelectedPath = this.files[0].path;

    // Only dispatch event if the path has actually changed and files exist
    if (
      this.selectedPath !== newSelectedPath &&
      this.files &&
      this.files.length > 0
    ) {
      this.selectedPath = newSelectedPath;

      // Dispatch the event directly - we've already checked the files array
      const event = new CustomEvent("file-selected", {
        detail: { file: this.files[0] },
        bubbles: true,
        composed: true,
      });

      this.dispatchEvent(event);
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-diff-file-picker": SketchDiffFilePicker;
  }
}
