import { css, html, LitElement } from "lit";
import { PropertyValues } from "lit";
import { repeat } from "lit/directives/repeat.js";
import { customElement, property, state } from "lit/decorators.js";
import { AgentMessage } from "../types";
import "./sketch-timeline-message";
import { Ref } from "lit/directives/ref";

@customElement("sketch-timeline")
export class SketchTimeline extends LitElement {
  @property({ attribute: false })
  messages: AgentMessage[] = [];

  // Track if we should scroll to the bottom
  @state()
  private scrollingState: "pinToLatest" | "floating" = "pinToLatest";

  @property({ attribute: false })
  scrollContainer: Ref<HTMLElement>;

  static styles = css`
    /* Hide views initially to prevent flash of content */
    .timeline-container .timeline,
    .timeline-container .diff-view,
    .timeline-container .chart-view,
    .timeline-container .terminal-view {
      visibility: hidden;
    }

    /* Will be set by JavaScript once we know which view to display */
    .timeline-container.view-initialized .timeline,
    .timeline-container.view-initialized .diff-view,
    .timeline-container.view-initialized .chart-view,
    .timeline-container.view-initialized .terminal-view {
      visibility: visible;
    }

    .timeline-container {
      width: 100%;
      position: relative;
    }

    /* Timeline styles that should remain unchanged */
    .timeline {
      position: relative;
      margin: 10px 0;
      scroll-behavior: smooth;
    }

    .timeline::before {
      content: "";
      position: absolute;
      top: 0;
      bottom: 0;
      left: 15px;
      width: 2px;
      background: #e0e0e0;
      border-radius: 1px;
    }

    /* Hide the timeline vertical line when there are no messages */
    .timeline.empty::before {
      display: none;
    }

    #scroll-container {
      overflow: auto;
      padding-left: 1em;
    }
    #jump-to-latest {
      display: none;
      position: fixed;
      bottom: 100px;
      right: 0;
      background: rgb(33, 150, 243);
      color: white;
      border-radius: 8px;
      padding: 0.5em;
      margin: 0.5em;
      font-size: x-large;
      opacity: 0.5;
      cursor: pointer;
    }
    #jump-to-latest:hover {
      opacity: 1;
    }
    #jump-to-latest.floating {
      display: block;
    }

    /* Welcome box styles for the empty chat state */
    .welcome-box {
      margin: 2rem auto;
      max-width: 80%;
      padding: 2rem;
      border: 2px solid #e0e0e0;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
      background-color: #ffffff;
      text-align: center;
    }

    .welcome-box-title {
      font-size: 1.5rem;
      font-weight: 600;
      margin-bottom: 1.5rem;
      text-align: center;
      color: #333;
    }

    .welcome-box-content {
      color: #666; /* Slightly grey font color */
      line-height: 1.6;
      font-size: 1rem;
      text-align: left;
    }
  `;

  constructor() {
    super();

    // Binding methods
    this._handleShowCommitDiff = this._handleShowCommitDiff.bind(this);
    this._handleScroll = this._handleScroll.bind(this);
  }

  /**
   * Scroll to the bottom of the timeline
   */
  private scrollToBottom(): void {
    this.scrollContainer.value?.scrollTo({
      top: this.scrollContainer.value?.scrollHeight,
      behavior: "smooth",
    });
  }

  /**
   * Called after the component's properties have been updated
   */
  updated(changedProperties: PropertyValues): void {
    // If messages have changed, scroll to bottom if needed
    if (changedProperties.has("messages") && this.messages.length > 0) {
      if (this.scrollingState == "pinToLatest") {
        setTimeout(() => this.scrollToBottom(), 50);
      }
    }
    if (changedProperties.has("scrollContainer")) {
      this.scrollContainer.value?.addEventListener(
        "scroll",
        this._handleScroll,
      );
    }
  }

  /**
   * Handle showCommitDiff event
   */
  private _handleShowCommitDiff(event: CustomEvent) {
    const { commitHash } = event.detail;
    if (commitHash) {
      // Bubble up the event to the app shell
      const newEvent = new CustomEvent("show-commit-diff", {
        detail: { commitHash },
        bubbles: true,
        composed: true,
      });
      this.dispatchEvent(newEvent);
    }
  }

  private _handleScroll(event) {
    const isAtBottom =
      Math.abs(
        this.scrollContainer.value.scrollHeight -
          this.scrollContainer.value.clientHeight -
          this.scrollContainer.value.scrollTop,
      ) <= 1;
    if (isAtBottom) {
      this.scrollingState = "pinToLatest";
    } else {
      // TODO: does scroll direction matter here?
      this.scrollingState = "floating";
    }
  }

  // See https://lit.dev/docs/components/lifecycle/
  connectedCallback() {
    super.connectedCallback();

    // Listen for showCommitDiff events from the renderer
    document.addEventListener(
      "showCommitDiff",
      this._handleShowCommitDiff as EventListener,
    );

    this.scrollContainer.value?.addEventListener("scroll", this._handleScroll);
  }

  // See https://lit.dev/docs/components/lifecycle/
  disconnectedCallback() {
    super.disconnectedCallback();

    // Remove event listeners
    document.removeEventListener(
      "showCommitDiff",
      this._handleShowCommitDiff as EventListener,
    );

    this.scrollContainer.value?.removeEventListener(
      "scroll",
      this._handleScroll,
    );
  }

  // messageKey uniquely identifes a AgentMessage based on its ID and tool_calls, so
  // that we only re-render <sketch-message> elements that we need to re-render.
  messageKey(message: AgentMessage): string {
    // If the message has tool calls, and any of the tool_calls get a response, we need to
    // re-render that message.
    const toolCallResponses = message.tool_calls
      ?.filter((tc) => tc.result_message)
      .map((tc) => tc.tool_call_id)
      .join("-");
    return `message-${message.idx}-${toolCallResponses}`;
  }

  render() {
    // Check if messages array is empty and render welcome box if it is
    if (this.messages.length === 0) {
      return html`
        <div id="scroll-container">
          <div class="welcome-box">
            <h2 class="welcome-box-title">How to use Sketch</h2>
            <p class="welcome-box-content">
              Sketch is an agentic coding assistant.
            </p>

            <p class="welcome-box-content">
              Sketch has created a container with your repo.
            </p>

            <p class="welcome-box-content">
              Ask it to implement a task or answer a question in the chat box
              below. Sketch has created a container with your repo, and it can
              edit and run your code in the container. Sketch will create
              commits, which you can look at and review with comments in the
              Diff tab. Once you're done, you'll find the changes ready to go in
              a
              <code>sketch/*</code> branch.
            </p>
            <p class="welcome-box-content">
              Because Sketch operates a container per session, you can run
              Sketch in parallel to work on multiple ideas or even the same idea
              with different approaches.
            </p>
          </div>
        </div>
      `;
    }

    // Otherwise render the regular timeline with messages
    return html`
      <div id="scroll-container">
        <div class="timeline-container">
          ${repeat(this.messages, this.messageKey, (message, index) => {
            let previousMessage: AgentMessage;
            if (index > 0) {
              previousMessage = this.messages[index - 1];
            }
            return html`<sketch-timeline-message
              .message=${message}
              .previousMessage=${previousMessage}
              .open=${false}
            ></sketch-timeline-message>`;
          })}
        </div>
      </div>
      <div
        id="jump-to-latest"
        class="${this.scrollingState}"
        @click=${this.scrollToBottom}
      >
        ⇩
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-timeline": SketchTimeline;
  }
}
