import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { ConnectionStatus, DataManager } from "../data";
import { AgentMessage, GitCommit, State } from "../types";
import { aggregateAgentMessages } from "./aggregateAgentMessages";
import "./sketch-charts";
import "./sketch-chat-input";
import "./sketch-container-status";
import "./sketch-diff-view";
import { SketchDiffView } from "./sketch-diff-view";
import "./sketch-network-status";
import "./sketch-call-status";
import "./sketch-terminal";
import "./sketch-timeline";
import "./sketch-view-mode-select";
import "./sketch-restart-modal";

import { createRef, ref } from "lit/directives/ref.js";

type ViewMode = "chat" | "diff" | "charts" | "terminal";

@customElement("sketch-app-shell")
export class SketchAppShell extends LitElement {
  // Current view mode (chat, diff, charts, terminal)
  @state()
  viewMode: "chat" | "diff" | "charts" | "terminal" = "chat";

  // Current commit hash for diff view
  @state()
  currentCommitHash: string = "";

  // Last commit information
  @state()
  lastCommit: { hash: string; pushedBranch?: string } | null = null;

  // See https://lit.dev/docs/components/styles/ for how lit-element handles CSS.
  // Note that these styles only apply to the scope of this web component's
  // shadow DOM node, so they won't leak out or collide with CSS declared in
  // other components or the containing web page (...unless you want it to do that).
  static styles = css`
    /* Last commit display styling */
    .last-commit {
      display: flex;
      align-items: center;
      padding: 3px 8px;
      background: #f0f7ff;
      border: 1px solid #c8e1ff;
      border-radius: 4px;
      font-family: monospace;
      font-size: 12px;
      color: #0366d6;
      cursor: pointer;
      position: relative;
      margin: 0 10px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 180px;
      transition: background-color 0.2s ease;
    }

    .last-commit:hover {
      background-color: #dbedff;
    }

    .last-commit::before {
      content: "Last Commit: ";
      color: #666;
      margin-right: 4px;
      font-family: system-ui, sans-serif;
      font-size: 11px;
    }

    .copied-indicator {
      position: absolute;
      top: -20px;
      left: 50%;
      transform: translateX(-50%);
      background: rgba(40, 167, 69, 0.9);
      color: white;
      padding: 2px 6px;
      border-radius: 3px;
      font-size: 10px;
      font-family: system-ui, sans-serif;
      animation: fadeInOut 2s ease;
      pointer-events: none;
    }

    @keyframes fadeInOut {
      0% {
        opacity: 0;
      }
      20% {
        opacity: 1;
      }
      80% {
        opacity: 1;
      }
      100% {
        opacity: 0;
      }
    }

    .commit-branch-indicator {
      color: #28a745;
    }

    .commit-hash-indicator {
      color: #0366d6;
    }
    :host {
      display: block;
      font-family:
        system-ui,
        -apple-system,
        BlinkMacSystemFont,
        "Segoe UI",
        Roboto,
        sans-serif;
      color: #333;
      line-height: 1.4;
      height: 100vh;
      width: 100%;
      position: relative;
      overflow-x: hidden;
      display: flex;
      flex-direction: column;
    }

    /* Top banner with combined elements */
    #top-banner {
      display: flex;
      align-self: stretch;
      justify-content: space-between;
      align-items: center;
      padding: 0 20px;
      margin-bottom: 0;
      border-bottom: 1px solid #eee;
      gap: 20px;
      background: white;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      width: 100%;
      height: 48px;
      padding-right: 30px; /* Extra padding on the right to prevent elements from hitting the edge */
    }

    /* View mode container styles - mirroring timeline.css structure */
    #view-container {
      align-self: stretch;
      overflow-y: auto;
      flex: 1;
    }

    #view-container-inner {
      max-width: 1200px;
      margin: 0 auto;
      position: relative;
      padding-bottom: 10px;
      padding-top: 10px;
    }

    #chat-input {
      align-self: flex-end;
      width: 100%;
      box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
    }

    .banner-title {
      font-size: 18px;
      font-weight: 600;
      margin: 0;
      min-width: 6em;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .chat-title {
      margin: 0;
      padding: 0;
      color: rgba(82, 82, 82, 0.85);
      font-size: 14px;
      font-weight: normal;
      font-style: italic;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    /* Allow the container to expand to full width in diff mode */
    #view-container-inner.diff-active {
      max-width: 100%;
      width: 100%;
    }

    /* Individual view styles */
    .chat-view,
    .diff-view,
    .chart-view,
    .terminal-view {
      display: none; /* Hidden by default */
      width: 100%;
    }

    /* Active view styles - these will be applied via JavaScript */
    .view-active {
      display: flex;
      flex-direction: column;
    }

    .title-container {
      display: flex;
      flex-direction: column;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 30%;
      padding: 6px 0;
    }

    .refresh-control {
      display: flex;
      align-items: center;
      margin-bottom: 0;
      flex-wrap: nowrap;
      white-space: nowrap;
      flex-shrink: 0;
      gap: 15px;
      padding-left: 15px;
      margin-right: 50px;
    }

    .restart-button {
      background: #2196f3;
      color: white;
      border: none;
      padding: 4px 10px;
      border-radius: 4px;
      cursor: pointer;
      font-size: 12px;
      margin-right: 5px;
    }

    .restart-button:hover {
      background-color: #0b7dda;
    }

    .restart-button:disabled {
      background-color: #ccc;
      cursor: not-allowed;
      opacity: 0.6;
    }

    .refresh-button {
      background: #4caf50;
      color: white;
      border: none;
      padding: 4px 10px;
      border-radius: 4px;
      cursor: pointer;
      font-size: 12px;
      margin-right: 5px;
    }

    .stop-button:hover {
      background-color: #c82333 !important;
    }

    .poll-updates,
    .notifications-toggle {
      display: flex;
      align-items: center;
      font-size: 12px;
      margin-right: 10px;
    }
  `;

  // Header bar: Network connection status details
  @property()
  connectionStatus: ConnectionStatus = "disconnected";

  // Track if the last commit info has been copied
  @state()
  lastCommitCopied: boolean = false;

  // Track notification preferences
  @state()
  notificationsEnabled: boolean = true;

  @property()
  connectionErrorMessage: string = "";

  @property()
  messageStatus: string = "";

  // Chat messages
  @property({ attribute: false })
  messages: AgentMessage[] = [];

  @property()
  set title(value: string) {
    const oldValue = this._title;
    this._title = value;
    this.requestUpdate("title", oldValue);
    // Update document title when title property changes
    this.updateDocumentTitle();
  }

  get title(): string {
    return this._title;
  }

  private _title: string = "";

  private dataManager = new DataManager();

  @property({ attribute: false })
  containerState: State = {
    title: "",
    os: "",
    message_count: 0,
    hostname: "",
    working_dir: "",
    initial_commit: "",
    outstanding_llm_calls: 0,
    outstanding_tool_calls: [],
    session_id: "",
    ssh_available: false,
    ssh_error: "",
    in_container: false,
    first_message_index: 0,
  };

  @state()
  private restartModalOpen = false;

  // Mutation observer to detect when new messages are added
  private mutationObserver: MutationObserver | null = null;

  constructor() {
    super();

    // Binding methods to this
    this._handleViewModeSelect = this._handleViewModeSelect.bind(this);
    this._handleShowCommitDiff = this._handleShowCommitDiff.bind(this);
    this._handlePopState = this._handlePopState.bind(this);
    this._handleStopClick = this._handleStopClick.bind(this);
    this._handleNotificationsToggle =
      this._handleNotificationsToggle.bind(this);

    // Load notification preference from localStorage
    try {
      const savedPref = localStorage.getItem("sketch-notifications-enabled");
      if (savedPref !== null) {
        this.notificationsEnabled = savedPref === "true";
      }
    } catch (error) {
      console.error("Error loading notification preference:", error);
    }
  }

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

    // Initialize client-side nav history.
    const url = new URL(window.location.href);
    const mode = url.searchParams.get("view") || "chat";
    window.history.replaceState({ mode }, "", url.toString());

    this.toggleViewMode(mode as ViewMode, false);
    // Add popstate event listener to handle browser back/forward navigation
    window.addEventListener("popstate", this._handlePopState);

    // Add event listeners
    window.addEventListener("view-mode-select", this._handleViewModeSelect);
    window.addEventListener("show-commit-diff", this._handleShowCommitDiff);

    // register event listeners
    this.dataManager.addEventListener(
      "dataChanged",
      this.handleDataChanged.bind(this),
    );
    this.dataManager.addEventListener(
      "connectionStatusChanged",
      this.handleConnectionStatusChanged.bind(this),
    );

    // Set initial document title
    this.updateDocumentTitle();

    // Initialize the data manager
    this.dataManager.initialize();

    // Process existing messages for commit info
    if (this.messages && this.messages.length > 0) {
      this.updateLastCommitInfo(this.messages);
    }
  }

  // See https://lit.dev/docs/components/lifecycle/
  disconnectedCallback() {
    super.disconnectedCallback();
    window.removeEventListener("popstate", this._handlePopState);

    // Remove event listeners
    window.removeEventListener("view-mode-select", this._handleViewModeSelect);
    window.removeEventListener("show-commit-diff", this._handleShowCommitDiff);

    // unregister data manager event listeners
    this.dataManager.removeEventListener(
      "dataChanged",
      this.handleDataChanged.bind(this),
    );
    this.dataManager.removeEventListener(
      "connectionStatusChanged",
      this.handleConnectionStatusChanged.bind(this),
    );

    // Disconnect mutation observer if it exists
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
      this.mutationObserver = null;
    }
  }

  updateUrlForViewMode(mode: "chat" | "diff" | "charts" | "terminal"): void {
    // Get the current URL without search parameters
    const url = new URL(window.location.href);

    // Clear existing parameters
    url.search = "";

    // Only add view parameter if not in default chat view
    if (mode !== "chat") {
      url.searchParams.set("view", mode);
      const diffView = this.shadowRoot?.querySelector(
        ".diff-view",
      ) as SketchDiffView;

      // If in diff view and there's a commit hash, include that too
      if (mode === "diff" && diffView.commitHash) {
        url.searchParams.set("commit", diffView.commitHash);
      }
    }

    // Update the browser history without reloading the page
    window.history.pushState({ mode }, "", url.toString());
  }

  private _handlePopState(event: PopStateEvent) {
    if (event.state && event.state.mode) {
      this.toggleViewMode(event.state.mode, false);
    } else {
      this.toggleViewMode("chat", false);
    }
  }

  /**
   * Handle view mode selection event
   */
  private _handleViewModeSelect(event: CustomEvent) {
    const mode = event.detail.mode as "chat" | "diff" | "charts" | "terminal";
    this.toggleViewMode(mode, true);
  }

  /**
   * Handle show commit diff event
   */
  private _handleShowCommitDiff(event: CustomEvent) {
    const { commitHash } = event.detail;
    if (commitHash) {
      this.showCommitDiff(commitHash);
    }
  }

  /**
   * Listen for commit diff event
   * @param commitHash The commit hash to show diff for
   */
  private showCommitDiff(commitHash: string): void {
    // Store the commit hash
    this.currentCommitHash = commitHash;

    // Switch to diff view
    this.toggleViewMode("diff", true);

    // Wait for DOM update to complete
    this.updateComplete.then(() => {
      // Get the diff view component
      const diffView = this.shadowRoot?.querySelector("sketch-diff-view");
      if (diffView) {
        // Call the showCommitDiff method
        (diffView as any).showCommitDiff(commitHash);
      }
    });
  }

  /**
   * Toggle between different view modes: chat, diff, charts, terminal
   */
  private toggleViewMode(mode: ViewMode, updateHistory: boolean): void {
    // Don't do anything if the mode is already active
    if (this.viewMode === mode) return;

    // Update the view mode
    this.viewMode = mode;

    if (updateHistory) {
      // Update URL with the current view mode
      this.updateUrlForViewMode(mode);
    }

    // Wait for DOM update to complete
    this.updateComplete.then(() => {
      // Update active view
      const viewContainerInner = this.shadowRoot?.querySelector(
        "#view-container-inner",
      );
      const chatView = this.shadowRoot?.querySelector(".chat-view");
      const diffView = this.shadowRoot?.querySelector(".diff-view");
      const chartView = this.shadowRoot?.querySelector(".chart-view");
      const terminalView = this.shadowRoot?.querySelector(".terminal-view");

      // Remove active class from all views
      chatView?.classList.remove("view-active");
      diffView?.classList.remove("view-active");
      chartView?.classList.remove("view-active");
      terminalView?.classList.remove("view-active");

      // Add/remove diff-active class on view container
      if (mode === "diff") {
        viewContainerInner?.classList.add("diff-active");
      } else {
        viewContainerInner?.classList.remove("diff-active");
      }

      // Add active class to the selected view
      switch (mode) {
        case "chat":
          chatView?.classList.add("view-active");
          break;
        case "diff":
          diffView?.classList.add("view-active");
          // Load diff content if we have a diff view
          const diffViewComp =
            this.shadowRoot?.querySelector("sketch-diff-view");
          if (diffViewComp && this.currentCommitHash) {
            (diffViewComp as any).showCommitDiff(this.currentCommitHash);
          } else if (diffViewComp) {
            (diffViewComp as any).loadDiffContent();
          }
          break;
        case "charts":
          chartView?.classList.add("view-active");
          break;
        case "terminal":
          terminalView?.classList.add("view-active");
          break;
      }

      // Update view mode buttons
      const viewModeSelect = this.shadowRoot?.querySelector(
        "sketch-view-mode-select",
      );
      if (viewModeSelect) {
        const event = new CustomEvent("update-active-mode", {
          detail: { mode },
          bubbles: true,
          composed: true,
        });
        viewModeSelect.dispatchEvent(event);
      }

      // FIXME: This is a hack to get vega chart in sketch-charts.ts to work properly
      // When the chart is in the background, its container has a width of 0, so vega
      // renders width 0 and only changes that width on a resize event.
      // See https://github.com/vega/react-vega/issues/85#issuecomment-1826421132
      window.dispatchEvent(new Event("resize"));
    });
  }

  /**
   * Updates the document title based on current title and connection status
   */
  private updateDocumentTitle(): void {
    let docTitle = `sk: ${this.title || "untitled"}`;

    // Add red circle emoji if disconnected
    if (this.connectionStatus === "disconnected") {
      docTitle += " 🔴";
    }

    document.title = docTitle;
  }

  // Check and request notification permission if needed
  private async checkNotificationPermission(): Promise<boolean> {
    // Check if the Notification API is supported
    if (!("Notification" in window)) {
      console.log("This browser does not support notifications");
      return false;
    }

    // Check if permission is already granted
    if (Notification.permission === "granted") {
      return true;
    }

    // If permission is not denied, request it
    if (Notification.permission !== "denied") {
      const permission = await Notification.requestPermission();
      return permission === "granted";
    }

    return false;
  }

  // Handle notifications toggle change
  private _handleNotificationsToggle(event: Event): void {
    const toggleCheckbox = event.target as HTMLInputElement;
    this.notificationsEnabled = toggleCheckbox.checked;

    // If enabling notifications, check permissions
    if (this.notificationsEnabled) {
      this.checkNotificationPermission();
    }

    // Save preference to localStorage
    try {
      localStorage.setItem(
        "sketch-notifications-enabled",
        String(this.notificationsEnabled),
      );
    } catch (error) {
      console.error("Error saving notification preference:", error);
    }
  }

  // Show notification for message with EndOfTurn=true
  private async showEndOfTurnNotification(
    message: AgentMessage,
  ): Promise<void> {
    // Don't show notifications if they're disabled
    if (!this.notificationsEnabled) return;

    // Check if we have permission to show notifications
    const hasPermission = await this.checkNotificationPermission();
    if (!hasPermission) return;

    // Only show notifications for agent messages with end_of_turn=true
    if (message.type !== "agent" || !message.end_of_turn) return;

    // Create a title that includes the sketch title
    const notificationTitle = `Sketch: ${this.title || "untitled"}`;

    // Extract the beginning of the message content (first 100 chars)
    const messagePreview = message.content
      ? message.content.substring(0, 100) +
        (message.content.length > 100 ? "..." : "")
      : "Agent has completed its turn";

    // Create and show the notification
    try {
      new Notification(notificationTitle, {
        body: messagePreview,
        icon: "/static/favicon.ico", // Use sketch favicon if available
      });
    } catch (error) {
      console.error("Error showing notification:", error);
    }
  }

  private handleDataChanged(eventData: {
    state: State;
    newMessages: AgentMessage[];
    isFirstFetch?: boolean;
  }): void {
    const { state, newMessages, isFirstFetch } = eventData;

    // Check if this is the first data fetch or if there are new messages
    if (isFirstFetch) {
      this.messageStatus = "Initial messages loaded";
    } else if (newMessages && newMessages.length > 0) {
      this.messageStatus = "Updated just now";
    } else {
      this.messageStatus = "No new messages";
    }

    // Update state if we received it
    if (state) {
      // Ensure we're using the latest call status to prevent indicators from being stuck
      if (
        state.outstanding_llm_calls === 0 &&
        state.outstanding_tool_calls.length === 0
      ) {
        // Force reset containerState calls when nothing is reported as in progress
        state.outstanding_llm_calls = 0;
        state.outstanding_tool_calls = [];
      }

      this.containerState = state;
      this.title = state.title;

      // Update document title when sketch title changes
      this.updateDocumentTitle();
    }

    // Update messages
    this.messages = aggregateAgentMessages(this.messages, newMessages);

    // Process new messages to find commit messages
    this.updateLastCommitInfo(newMessages);

    // Check for agent messages with end_of_turn=true and show notifications
    if (newMessages && newMessages.length > 0 && !isFirstFetch) {
      for (const message of newMessages) {
        if (message.type === "agent" && message.end_of_turn) {
          this.showEndOfTurnNotification(message);
          break; // Only show one notification per batch of messages
        }
      }
    }
  }

  private handleConnectionStatusChanged(
    status: ConnectionStatus,
    errorMessage?: string,
  ): void {
    this.connectionStatus = status;
    this.connectionErrorMessage = errorMessage || "";

    // Update document title when connection status changes
    this.updateDocumentTitle();
  }

  // Update last commit information when new messages arrive
  private updateLastCommitInfo(newMessages: AgentMessage[]): void {
    if (!newMessages || newMessages.length === 0) return;

    // Process messages in chronological order (latest last)
    for (const message of newMessages) {
      if (
        message.type === "commit" &&
        message.commits &&
        message.commits.length > 0
      ) {
        // Get the first commit from the list
        const commit = message.commits[0];
        if (commit) {
          this.lastCommit = {
            hash: commit.hash,
            pushedBranch: commit.pushed_branch,
          };
          this.lastCommitCopied = false;
        }
      }
    }
  }

  // Copy commit info to clipboard
  private copyCommitInfo(event: MouseEvent): void {
    event.preventDefault();
    event.stopPropagation();

    if (!this.lastCommit) return;

    const textToCopy =
      this.lastCommit.pushedBranch || this.lastCommit.hash.substring(0, 8);

    navigator.clipboard
      .writeText(textToCopy)
      .then(() => {
        this.lastCommitCopied = true;
        // Reset the copied state after 2 seconds
        setTimeout(() => {
          this.lastCommitCopied = false;
        }, 2000);
      })
      .catch((err) => {
        console.error("Failed to copy commit info:", err);
      });
  }

  private async _handleStopClick(): Promise<void> {
    try {
      const response = await fetch("cancel", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ reason: "user requested cancellation" }),
      });

      if (!response.ok) {
        const errorData = await response.text();
        throw new Error(
          `Failed to stop operation: ${response.status} - ${errorData}`,
        );
      }

      this.messageStatus = "Stop request sent";
    } catch (error) {
      console.error("Error stopping operation:", error);
      this.messageStatus = "Failed to stop operation";
    }
  }

  openRestartModal() {
    this.restartModalOpen = true;
  }

  handleRestartModalClose() {
    this.restartModalOpen = false;
  }

  async _sendChat(e: CustomEvent) {
    console.log("app shell: _sendChat", e);
    const message = e.detail.message?.trim();
    if (message == "") {
      return;
    }
    try {
      // Send the message to the server
      const response = await fetch("chat", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ message }),
      });

      if (!response.ok) {
        const errorData = await response.text();
        throw new Error(`Server error: ${response.status} - ${errorData}`);
      }

      // TOOD(philip): If the data manager is getting messages out of order, there's a bug?
      // Reset data manager state to force a full refresh after sending a message
      // This ensures we get all messages in the correct order
      // Use private API for now - TODO: add a resetState() method to DataManager
      (this.dataManager as any).nextFetchIndex = 0;
      (this.dataManager as any).currentFetchStartIndex = 0;

      // // If in diff view, switch to conversation view
      // if (this.viewMode === "diff") {
      //   await this.toggleViewMode("chat");
      // }

      // Refresh the timeline data to show the new message
      await this.dataManager.fetchData();
    } catch (error) {
      console.error("Error sending chat message:", error);
      const statusText = document.getElementById("statusText");
      if (statusText) {
        statusText.textContent = "Error sending message";
      }
    }
  }

  private scrollContainerRef = createRef<HTMLElement>();

  render() {
    return html`
      <div id="top-banner">
        <div class="title-container">
          <h1 class="banner-title">sketch</h1>
          <h2 id="chatTitle" class="chat-title">${this.title}</h2>
        </div>

        <!-- Views section with tabs -->
        <sketch-view-mode-select></sketch-view-mode-select>

        <!-- Container status info -->
        <sketch-container-status
          .state=${this.containerState}
        ></sketch-container-status>

        ${this.lastCommit
          ? html`
              <div
                class="last-commit"
                @click=${(e: MouseEvent) => this.copyCommitInfo(e)}
                title="Click to copy"
              >
                ${this.lastCommitCopied
                  ? html`<span class="copied-indicator">Copied!</span>`
                  : ""}
                ${this.lastCommit.pushedBranch
                  ? html`<span class="commit-branch-indicator"
                      >${this.lastCommit.pushedBranch}</span
                    >`
                  : html`<span class="commit-hash-indicator"
                      >${this.lastCommit.hash.substring(0, 8)}</span
                    >`}
              </div>
            `
          : ""}

        <div class="refresh-control">
          <button
            id="restartButton"
            class="restart-button"
            ?disabled=${this.containerState.message_count === 0}
            @click=${this.openRestartModal}
          >
            Restart
          </button>
          <button id="stopButton" class="refresh-button stop-button">
            Stop
          </button>

          <div class="poll-updates">
            <input type="checkbox" id="pollToggle" checked />
            <label for="pollToggle">Poll</label>
          </div>

          <div class="notifications-toggle">
            <input
              type="checkbox"
              id="notificationsToggle"
              ?checked=${this.notificationsEnabled}
              @change=${this._handleNotificationsToggle}
            />
            <label for="notificationsToggle">Notifications</label>
          </div>

          <sketch-network-status
            message=${this.messageStatus}
            connection=${this.connectionStatus}
            error=${this.connectionErrorMessage}
          ></sketch-network-status>

          <sketch-call-status
            .llmCalls=${this.containerState?.outstanding_llm_calls || 0}
            .toolCalls=${this.containerState?.outstanding_tool_calls || []}
          ></sketch-call-status>
        </div>
      </div>

      <div id="view-container" ${ref(this.scrollContainerRef)}>
        <div id="view-container-inner">
          <div
            class="chat-view ${this.viewMode === "chat" ? "view-active" : ""}"
          >
            <sketch-timeline
              .messages=${this.messages}
              .scrollContainer=${this.scrollContainerRef}
            ></sketch-timeline>
          </div>
          <div
            class="diff-view ${this.viewMode === "diff" ? "view-active" : ""}"
          >
            <sketch-diff-view
              .commitHash=${this.currentCommitHash}
            ></sketch-diff-view>
          </div>
          <div
            class="chart-view ${this.viewMode === "charts"
              ? "view-active"
              : ""}"
          >
            <sketch-charts .messages=${this.messages}></sketch-charts>
          </div>
          <div
            class="terminal-view ${this.viewMode === "terminal"
              ? "view-active"
              : ""}"
          >
            <sketch-terminal></sketch-terminal>
          </div>
        </div>
      </div>

      <div id="chat-input">
        <sketch-chat-input @send-chat="${this._sendChat}"></sketch-chat-input>
      </div>

      <sketch-restart-modal
        ?open=${this.restartModalOpen}
        @close=${this.handleRestartModalClose}
        .containerState=${this.containerState}
        .messages=${this.messages}
      ></sketch-restart-modal>
    `;
  }

  /**
   * Lifecycle callback when component is first connected to DOM
   */
  firstUpdated(): void {
    if (this.viewMode !== "chat") {
      return;
    }

    // Initial scroll to bottom when component is first rendered
    setTimeout(
      () => this.scrollTo({ top: this.scrollHeight, behavior: "smooth" }),
      50,
    );

    // Setup stop button
    const stopButton = this.renderRoot?.querySelector(
      "#stopButton",
    ) as HTMLButtonElement;
    stopButton?.addEventListener("click", async () => {
      try {
        const response = await fetch("/cancel", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ reason: "User clicked stop button" }),
        });
        if (!response.ok) {
          console.error("Failed to cancel:", await response.text());
        }
      } catch (error) {
        console.error("Error cancelling operation:", error);
      }
    });

    const pollToggleCheckbox = this.renderRoot?.querySelector(
      "#pollToggle",
    ) as HTMLInputElement;
    pollToggleCheckbox?.addEventListener("change", () => {
      this.dataManager.setPollingEnabled(pollToggleCheckbox.checked);
      if (!pollToggleCheckbox.checked) {
        this.connectionStatus = "disabled";
        this.messageStatus = "Polling stopped";
      } else {
        this.messageStatus = "Polling for updates...";
      }
    });

    // Process any existing messages to find commit information
    if (this.messages && this.messages.length > 0) {
      this.updateLastCommitInfo(this.messages);
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-app-shell": SketchAppShell;
  }
}
