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-10 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;
  }
}
