import { State, AgentMessage, Usage, Port } from "../types";
import { html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { formatNumber } from "../utils";
import { SketchTailwindElement } from "./sketch-tailwind-element";

@customElement("sketch-container-status")
export class SketchContainerStatus extends SketchTailwindElement {
  // Header bar: Container status details

  @property()
  state: State;

  @state()
  showDetails: boolean = false;

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

  @state()
  lastCommitCopied: boolean = false;

  @state()
  latestUsage: Usage | null = null;

  @state()
  showPortsPopup: boolean = false;

  @state()
  previousPorts: Port[] = [];

  @state()
  highlightedPorts: Set<number> = new Set();

  // CSS animations that can't be easily replaced with Tailwind
  connectedCallback() {
    super.connectedCallback();
    // Add custom CSS animations to the document head if not already present
    if (!document.querySelector("#container-status-animations")) {
      const style = document.createElement("style");
      style.id = "container-status-animations";
      style.textContent = `
        @keyframes pulse-custom {
          0% { transform: scale(1); opacity: 1; }
          50% { transform: scale(1.05); opacity: 0.8; }
          100% { transform: scale(1); opacity: 1; }
        }
        .pulse-custom {
          animation: pulse-custom 1.5s ease-in-out;
          background-color: rgba(38, 132, 255, 0.1);
          border-radius: 3px;
        }
      `;
      document.head.appendChild(style);
    }
  }

  constructor() {
    super();
    this._toggleInfoDetails = this._toggleInfoDetails.bind(this);

    // Close the info panel when clicking outside of it
    document.addEventListener("click", (event) => {
      if (this.showDetails && !this.contains(event.target as Node)) {
        this.showDetails = false;
        this.requestUpdate();
      }
      // Close the ports popup when clicking outside of it
      if (this.showPortsPopup && !this.contains(event.target as Node)) {
        this.showPortsPopup = false;
        this.requestUpdate();
      }
    });
  }

  /**
   * Toggle the display of detailed information
   */
  private _toggleInfoDetails(event: Event) {
    event.stopPropagation();
    this.showDetails = !this.showDetails;
    this.requestUpdate();
  }

  /**
   * Update the last commit information based on messages
   */
  public 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) {
          // Check if the commit hash has changed
          const hasChanged =
            !this.lastCommit || this.lastCommit.hash !== commit.hash;

          this.lastCommit = {
            hash: commit.hash,
            pushedBranch: commit.pushed_branch,
          };
          this.lastCommitCopied = false;

          // Add pulse animation if the commit changed
          if (hasChanged) {
            // Find the last commit element
            setTimeout(() => {
              const lastCommitEl = this.querySelector(".last-commit-main");
              if (lastCommitEl) {
                // Add the pulse class
                lastCommitEl.classList.add("pulse-custom");

                // Remove the pulse class after animation completes
                setTimeout(() => {
                  lastCommitEl.classList.remove("pulse-custom");
                }, 1500);
              }
            }, 0);
          }
        }
      }
    }
  }

  /**
   * Copy commit info to clipboard when clicked
   */
  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 1.5 seconds
        setTimeout(() => {
          this.lastCommitCopied = false;
        }, 1500);
      })
      .catch((err) => {
        console.error("Failed to copy commit info:", err);
      });
  }

  formatHostname() {
    // Only display outside hostname
    const outsideHostname = this.state?.outside_hostname;

    if (!outsideHostname) {
      return this.state?.hostname;
    }

    return outsideHostname;
  }

  formatWorkingDir() {
    // Only display outside working directory
    const outsideWorkingDir = this.state?.outside_working_dir;

    if (!outsideWorkingDir) {
      return this.state?.working_dir;
    }

    return outsideWorkingDir;
  }

  getHostnameTooltip() {
    const outsideHostname = this.state?.outside_hostname;
    const insideHostname = this.state?.inside_hostname;

    if (
      !outsideHostname ||
      !insideHostname ||
      outsideHostname === insideHostname
    ) {
      return "";
    }

    return `Outside: ${outsideHostname}, Inside: ${insideHostname}`;
  }

  getWorkingDirTooltip() {
    const outsideWorkingDir = this.state?.outside_working_dir;
    const insideWorkingDir = this.state?.inside_working_dir;

    if (
      !outsideWorkingDir ||
      !insideWorkingDir ||
      outsideWorkingDir === insideWorkingDir
    ) {
      return "";
    }

    return `Outside: ${outsideWorkingDir}, Inside: ${insideWorkingDir}`;
  }

  copyToClipboard(text: string) {
    navigator.clipboard
      .writeText(text)
      .then(() => {
        // Could add a temporary success indicator here
      })
      .catch((err) => {
        console.error("Could not copy text: ", err);
      });
  }

  getSSHHostname() {
    // Use the ssh_connection_string from the state if available, otherwise fall back to generating it
    return (
      this.state?.ssh_connection_string || `sketch-${this.state?.session_id}`
    );
  }

  getSSHConnectionString() {
    // Return the connection string for VS Code remote SSH
    const connectionString =
      this.state?.ssh_connection_string || `sketch-${this.state?.session_id}`;
    // If the connection string already contains user@, use it as-is
    // Otherwise prepend root@ for VS Code remote SSH
    if (connectionString.includes("@")) {
      return connectionString;
    } else {
      return `root@${connectionString}`;
    }
  }

  /**
   * Get sorted ports (by port number) from state, filtering out ports < 1024
   */
  getSortedPorts(): Port[] {
    if (!this.state?.open_ports) {
      return [];
    }
    return [...this.state.open_ports]
      .filter((port) => port.port >= 1024)
      .sort((a, b) => a.port - b.port);
  }

  /**
   * Generate URL for a port based on skaband_addr or localhost
   */
  getPortUrl(port: number): string {
    if (this.state?.skaband_addr) {
      // Use skaband proxy pattern: skabandaddr/proxy/<sessionId>/<port>
      return `${this.state.skaband_addr}/proxy/${this.state.session_id}/${port}`;
    } else {
      // Use localhost pattern: http://p{port}.localhost:{sketch_port}
      // We need to extract the port from the current URL
      const currentPort = window.location.port || "80";
      return `http://p${port}.localhost:${currentPort}`;
    }
  }

  /**
   * Handle port link clicks
   *
   * TODO: Whereas Chrome resolves *.localhost as localhost,
   * Safari does not. Ideally, if skaband_addr is empty, we
   * could do a quick "fetch(p${port}.localhost)", and, if it
   * doesn't work at all, we could show the user a modal explaining
   * to use /etc/hosts. But, anyway, this would be nice but isn't done.
   */
  onPortClick(port: number, event: MouseEvent): void {
    event.preventDefault();
    event.stopPropagation();
    const url = this.getPortUrl(port);
    window.open(url, "_blank");
  }

  /**
   * Show more ports popup
   */
  private _showMorePorts(event: MouseEvent): void {
    event.preventDefault();
    event.stopPropagation();
    this.showPortsPopup = !this.showPortsPopup;
    this.requestUpdate();
  }

  /**
   * Update port tracking and highlight newly opened ports
   */
  public updatePortInfo(newPorts: Port[]): void {
    const currentPorts = newPorts.filter((port) => port.port >= 1024);
    const previousPortNumbers = new Set(this.previousPorts.map((p) => p.port));

    // Find newly opened ports
    const newlyOpenedPorts = currentPorts.filter(
      (port) => !previousPortNumbers.has(port.port),
    );

    if (newlyOpenedPorts.length > 0) {
      // Add newly opened ports to highlighted set
      newlyOpenedPorts.forEach((port) => {
        this.highlightedPorts.add(port.port);
      });

      // Remove highlights after animation completes
      setTimeout(() => {
        newlyOpenedPorts.forEach((port) => {
          this.highlightedPorts.delete(port.port);
        });
        this.requestUpdate();
      }, 1500);
    }

    this.previousPorts = [...currentPorts];
    this.requestUpdate();
  }

  // Format GitHub repository URL to org/repo format
  formatGitHubRepo(url) {
    if (!url) return null;

    // Common GitHub URL patterns
    const patterns = [
      // HTTPS URLs
      /https:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/,
      // SSH URLs
      /git@github\.com:([^/]+)\/([^/\s]+?)(?:\.git)?$/,
      // Git protocol
      /git:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/,
    ];

    for (const pattern of patterns) {
      const match = url.match(pattern);
      if (match) {
        return {
          formatted: `${match[1]}/${match[2]}`,
          url: `https://github.com/${match[1]}/${match[2]}`,
          owner: match[1],
          repo: match[2],
        };
      }
    }

    return null;
  }

  // Generate GitHub branch URL if linking is enabled
  getGitHubBranchLink(branchName) {
    if (!this.state?.link_to_github || !branchName) {
      return null;
    }

    const github = this.formatGitHubRepo(this.state?.git_origin);
    if (!github) {
      return null;
    }

    return `https://github.com/${github.owner}/${github.repo}/tree/${branchName}`;
  }

  renderSSHSection() {
    // Only show SSH section if we're in a Docker container and have session ID
    if (!this.state?.session_id) {
      return html``;
    }

    const _sshHost = this.getSSHHostname();
    const sshConnectionString = this.getSSHConnectionString();
    const sshCommand = `ssh ${sshConnectionString}`;
    const vscodeCommand = `code --remote ssh-remote+${sshConnectionString} /app -n`;
    const vscodeURL = `vscode://vscode-remote/ssh-remote+${sshConnectionString}/app?windowId=_blank`;

    if (!this.state?.ssh_available) {
      return html`
        <div class="mt-2.5 pt-2.5 border-t border-gray-300">
          <h3>Connect to Container</h3>
          <div
            class="bg-orange-50 border-l-4 border-orange-500 p-3 mt-2 text-xs text-orange-800"
          >
            SSH connections are not available:
            ${this.state?.ssh_error || "SSH configuration is missing"}
          </div>
        </div>
      `;
    }

    return html`
      <div class="mt-2.5 pt-2.5 border-t border-gray-300">
        <h3>Connect to Container</h3>
        <div class="flex items-center mb-2 gap-2.5">
          <div
            class="font-mono text-xs bg-gray-100 px-2 py-1 rounded border border-gray-300 flex-grow"
          >
            ${sshCommand}
          </div>
          <button
            class="bg-gray-100 border border-gray-300 rounded px-1.5 py-0.5 text-xs cursor-pointer transition-colors hover:bg-gray-200"
            @click=${() => this.copyToClipboard(sshCommand)}
          >
            Copy
          </button>
        </div>
        <div class="flex items-center mb-2 gap-2.5">
          <div
            class="font-mono text-xs bg-gray-100 px-2 py-1 rounded border border-gray-300 flex-grow"
          >
            ${vscodeCommand}
          </div>
          <button
            class="bg-gray-100 border border-gray-300 rounded px-1.5 py-0.5 text-xs cursor-pointer transition-colors hover:bg-gray-200"
            @click=${() => this.copyToClipboard(vscodeCommand)}
          >
            Copy
          </button>
        </div>
        <div class="flex items-center mb-2 gap-2.5">
          <a
            href="${vscodeURL}"
            class="text-white no-underline bg-blue-500 px-2 py-1 rounded flex items-center gap-1.5 text-xs transition-colors hover:bg-blue-800"
            title="${vscodeURL}"
          >
            <svg
              class="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="white"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path
                d="M16.5 9.4 7.55 4.24a.35.35 0 0 0-.41.01l-1.23.93a.35.35 0 0 0-.14.29v13.04c0 .12.07.23.17.29l1.24.93c.13.1.31.09.43-.01L16.5 14.6l-6.39 4.82c-.16.12-.38.12-.55.01l-1.33-1.01a.35.35 0 0 1-.14-.28V5.88c0-.12.07-.23.18-.29l1.23-.93c.14-.1.32-.1.46 0l6.54 4.92-6.54 4.92c-.14.1-.32.1-.46 0l-1.23-.93a.35.35 0 0 1-.18-.29V5.88c0-.12.07-.23.17-.29l1.33-1.01c.16-.12.39-.11.55.01l6.39 4.81z"
              />
            </svg>
            <span>Open in VSCode</span>
          </a>
        </div>
      </div>
    `;
  }

  render() {
    return html`
      <div class="flex items-center relative">
        <!-- Main visible info in two columns - github/hostname/dir and last commit -->
        <div class="flex flex-wrap gap-2 px-2.5 py-1 flex-1">
          <div class="flex gap-2.5 w-full">
            <!-- First column: GitHub repo (or hostname) and working dir -->
            <div class="flex flex-col gap-0.5">
              <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
                ${(() => {
                  const github = this.formatGitHubRepo(this.state?.git_origin);
                  if (github) {
                    return html`
                      <a
                        href="${github.url}"
                        target="_blank"
                        rel="noopener noreferrer"
                        class="github-link text-blue-600 no-underline hover:underline"
                        title="${this.state?.git_origin}"
                      >
                        ${github.formatted}
                      </a>
                    `;
                  } else {
                    return html`
                      <span
                        id="hostname"
                        class="text-xs font-semibold break-all cursor-default"
                        title="${this.getHostnameTooltip()}"
                      >
                        ${this.formatHostname()}
                      </span>
                    `;
                  }
                })()}
              </div>
              <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
                <span
                  id="workingDir"
                  class="text-xs font-semibold break-all cursor-default"
                  title="${this.getWorkingDirTooltip()}"
                >
                  ${this.formatWorkingDir()}
                </span>
              </div>
            </div>

            <!-- Second column: Last Commit -->
            <div class="flex flex-col gap-0.5 justify-start">
              <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
                <span class="text-xs text-gray-600 font-medium"
                  >Last Commit</span
                >
              </div>
              <div
                class="flex items-center whitespace-nowrap mr-2.5 text-xs cursor-pointer relative pt-0 last-commit-main hover:text-blue-600"
                @click=${(e: MouseEvent) => this.copyCommitInfo(e)}
                title="Click to copy"
              >
                ${this.lastCommit
                  ? this.lastCommit.pushedBranch
                    ? (() => {
                        const githubLink = this.getGitHubBranchLink(
                          this.lastCommit.pushedBranch,
                        );
                        return html`
                          <div class="flex items-center gap-1.5">
                            <span
                              class="text-green-600 font-mono text-xs whitespace-nowrap overflow-hidden text-ellipsis"
                              title="Click to copy: ${this.lastCommit
                                .pushedBranch}"
                              @click=${(e) => this.copyCommitInfo(e)}
                              >${this.lastCommit.pushedBranch}</span
                            >
                            <span
                              class="ml-1 opacity-70 flex items-center hover:opacity-100"
                            >
                              ${this.lastCommitCopied
                                ? html`<svg
                                    xmlns="http://www.w3.org/2000/svg"
                                    width="16"
                                    height="16"
                                    viewBox="0 0 24 24"
                                    fill="none"
                                    stroke="currentColor"
                                    stroke-width="2"
                                    stroke-linecap="round"
                                    stroke-linejoin="round"
                                    class="align-middle"
                                  >
                                    <path d="M20 6L9 17l-5-5"></path>
                                  </svg>`
                                : html`<svg
                                    xmlns="http://www.w3.org/2000/svg"
                                    width="16"
                                    height="16"
                                    viewBox="0 0 24 24"
                                    fill="none"
                                    stroke="currentColor"
                                    stroke-width="2"
                                    stroke-linecap="round"
                                    stroke-linejoin="round"
                                    class="align-middle"
                                  >
                                    <rect
                                      x="9"
                                      y="9"
                                      width="13"
                                      height="13"
                                      rx="2"
                                      ry="2"
                                    ></rect>
                                    <path
                                      d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
                                    ></path>
                                  </svg>`}
                            </span>
                            ${githubLink
                              ? html`<a
                                  href="${githubLink}"
                                  target="_blank"
                                  rel="noopener noreferrer"
                                  class="text-gray-600 no-underline flex items-center transition-colors hover:text-blue-600"
                                  title="Open ${this.lastCommit
                                    .pushedBranch} on GitHub"
                                  @click=${(e) => e.stopPropagation()}
                                >
                                  <svg
                                    class="w-4 h-4"
                                    viewBox="0 0 16 16"
                                    width="16"
                                    height="16"
                                  >
                                    <path
                                      fill="currentColor"
                                      d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
                                    />
                                  </svg>
                                </a>`
                              : ""}
                          </div>
                        `;
                      })()
                    : html`<span
                        class="text-gray-600 font-mono text-xs whitespace-nowrap overflow-hidden text-ellipsis"
                        >${this.lastCommit.hash.substring(0, 8)}</span
                      >`
                  : html`<span class="text-gray-500 italic text-xs">N/A</span>`}
              </div>
            </div>
          </div>
        </div>

        <!-- Ports section -->
        ${(() => {
          const ports = this.getSortedPorts();
          if (ports.length === 0) {
            return html``;
          }
          const displayPorts = ports.slice(0, 2);
          const remainingPorts = ports.slice(2);
          return html`
            <div class="flex items-center gap-1 ml-2">
              ${displayPorts.map(
                (port) => html`
                  <button
                    class="text-xs bg-gray-100 hover:bg-gray-200 px-1.5 py-0.5 rounded border border-gray-300 cursor-pointer transition-colors flex items-center gap-1 ${this.highlightedPorts.has(
                      port.port,
                    )
                      ? "pulse-custom"
                      : ""}"
                    @click=${(e: MouseEvent) => this.onPortClick(port.port, e)}
                    title="Open ${port.process} on port ${port.port}"
                  >
                    <span>${port.process}(${port.port})</span>
                    <span>🔗</span>
                  </button>
                `,
              )}
              ${remainingPorts.length > 0
                ? html`
                    <button
                      class="text-xs bg-gray-100 hover:bg-gray-200 px-1.5 py-0.5 rounded border border-gray-300 cursor-pointer transition-colors ${remainingPorts.some(
                        (port) => this.highlightedPorts.has(port.port),
                      )
                        ? "pulse-custom"
                        : ""}"
                      @click=${(e: MouseEvent) => this._showMorePorts(e)}
                      title="Show ${remainingPorts.length} more ports"
                    >
                      +${remainingPorts.length}
                    </button>
                  `
                : html``}
            </div>
          `;
        })()}

        <!-- Info toggle button -->
        <button
          class="info-toggle ml-2 w-6 h-6 rounded-full flex items-center justify-center ${this
            .showDetails
            ? "bg-blue-500 text-white border-blue-600"
            : "bg-gray-100 text-gray-600 border-gray-300"} border cursor-pointer font-bold italic transition-all hover:${this
            .showDetails
            ? "bg-blue-600"
            : "bg-gray-200"}"
          @click=${this._toggleInfoDetails}
          title="Show/hide details"
        >
          i
        </button>

        <!-- Expanded info panel -->
        <div
          class="${this.showDetails
            ? "block"
            : "hidden"} absolute min-w-max top-full z-100 bg-white rounded-lg p-4 shadow-lg mt-1.5"
        >
          <!-- Last Commit section moved to main grid -->

          <div
            class="grid gap-2 mt-2.5"
            style="grid-template-columns: auto auto"
          >
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Commit:</span
              >
              <span id="initialCommit" class="text-xs font-semibold break-all"
                >${this.state?.initial_commit?.substring(0, 8)}</span
              >
            </div>
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium">Msgs:</span>
              <span id="messageCount" class="text-xs font-semibold break-all"
                >${this.state?.message_count}</span
              >
            </div>
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Session ID:</span
              >
              <span id="sessionId" class="text-xs font-semibold break-all"
                >${this.state?.session_id || "N/A"}</span
              >
            </div>
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Hostname:</span
              >
              <span
                id="hostnameDetail"
                class="text-xs font-semibold break-all cursor-default"
                title="${this.getHostnameTooltip()}"
              >
                ${this.formatHostname()}
              </span>
            </div>
            ${this.state?.agent_state
              ? html`
                  <div
                    class="flex items-center whitespace-nowrap mr-2.5 text-xs"
                  >
                    <span class="text-xs text-gray-600 mr-1 font-medium"
                      >Agent State:</span
                    >
                    <span
                      id="agentState"
                      class="text-xs font-semibold break-all"
                      >${this.state?.agent_state}</span
                    >
                  </div>
                `
              : ""}
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Input tokens:</span
              >
              <span id="inputTokens" class="text-xs font-semibold break-all"
                >${formatNumber(
                  (this.state?.total_usage?.input_tokens || 0) +
                    (this.state?.total_usage?.cache_read_input_tokens || 0) +
                    (this.state?.total_usage?.cache_creation_input_tokens || 0),
                )}</span
              >
            </div>
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Context size:</span
              >
              <span id="contextWindow" class="text-xs font-semibold break-all"
                >${formatNumber(
                  (this.latestUsage?.input_tokens || 0) +
                    (this.latestUsage?.cache_read_input_tokens || 0) +
                    (this.latestUsage?.cache_creation_input_tokens || 0),
                )}</span
              >
            </div>
            <div class="flex items-center whitespace-nowrap mr-2.5 text-xs">
              <span class="text-xs text-gray-600 mr-1 font-medium"
                >Output tokens:</span
              >
              <span id="outputTokens" class="text-xs font-semibold break-all"
                >${formatNumber(this.state?.total_usage?.output_tokens)}</span
              >
            </div>
            ${(this.state?.total_usage?.total_cost_usd || 0) > 0
              ? html`
                  <div
                    class="flex items-center whitespace-nowrap mr-2.5 text-xs"
                  >
                    <span class="text-xs text-gray-600 mr-1 font-medium"
                      >Total cost:</span
                    >
                    <span id="totalCost" class="text-xs font-semibold break-all"
                      >$${(
                        this.state?.total_usage?.total_cost_usd ?? 0
                      ).toFixed(2)}</span
                    >
                  </div>
                `
              : ""}
            <div
              class="flex items-center whitespace-nowrap mr-2.5 text-xs col-span-full mt-1.5 border-t border-gray-300 pt-1.5"
            >
              <a href="logs" class="text-blue-600">Logs</a> (<a
                href="download"
                class="text-blue-600"
                >Download</a
              >)
            </div>
          </div>

          <!-- SSH Connection Information -->
          ${this.renderSSHSection()}
        </div>

        <!-- Ports popup -->
        <div
          class="${this.showPortsPopup
            ? "block"
            : "hidden"} absolute min-w-max top-full right-0 z-20 bg-white rounded-lg p-3 shadow-lg mt-1.5 border border-gray-200"
        >
          <h3 class="text-sm font-semibold mb-2">Open Ports</h3>
          <div class="flex flex-col gap-1">
            ${this.getSortedPorts().map(
              (port) => html`
                <button
                  class="text-xs bg-gray-100 hover:bg-gray-200 px-2 py-1 rounded border border-gray-300 cursor-pointer transition-colors flex items-center gap-2 justify-between"
                  @click=${(e: MouseEvent) => this.onPortClick(port.port, e)}
                  title="Open ${port.process} on port ${port.port}"
                >
                  <span>${port.process}(${port.port})</span>
                  <span>🔗</span>
                </button>
              `,
            )}
          </div>
        </div>
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "sketch-container-status": SketchContainerStatus;
  }
}
