/* eslint-disable @typescript-eslint/no-explicit-any */
import { html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { AgentMessage } from "../types";
import { createRef, ref } from "lit/directives/ref.js";
import { marked, MarkedOptions, Renderer } from "marked";
import DOMPurify from "dompurify";
import { SketchTailwindElement } from "./sketch-tailwind-element";

@customElement("mobile-chat")
export class MobileChat extends SketchTailwindElement {
  @property({ type: Array })
  messages: AgentMessage[] = [];

  @property({ type: Boolean })
  isThinking = false;

  private scrollContainer = createRef<HTMLDivElement>();

  @state()
  private showJumpToBottom = false;

  connectedCallback() {
    super.connectedCallback();
    // Add animation styles to document head if not already present
    if (!document.getElementById("mobile-chat-animations")) {
      const style = document.createElement("style");
      style.id = "mobile-chat-animations";
      style.textContent = `
        @keyframes thinking {
          0%, 80%, 100% {
            transform: scale(0.8);
            opacity: 0.5;
          }
          40% {
            transform: scale(1);
            opacity: 1;
          }
        }
        .thinking-dot {
          animation: thinking 1.4s ease-in-out infinite both;
        }
        .thinking-dot:nth-child(1) { animation-delay: -0.32s; }
        .thinking-dot:nth-child(2) { animation-delay: -0.16s; }
        .thinking-dot:nth-child(3) { animation-delay: 0; }
      `;
      document.head.appendChild(style);
    }
  }

  updated(changedProperties: Map<string, any>) {
    super.updated(changedProperties);
    if (
      changedProperties.has("messages") ||
      changedProperties.has("isThinking")
    ) {
      this.scrollToBottom();
    }

    // Set up scroll listener if not already done
    if (this.scrollContainer.value && !this.scrollContainer.value.onscroll) {
      this.scrollContainer.value.addEventListener(
        "scroll",
        this.handleScroll.bind(this),
      );
    }
  }

  private scrollToBottom() {
    // Use requestAnimationFrame to ensure DOM is updated
    requestAnimationFrame(() => {
      if (this.scrollContainer.value) {
        this.scrollContainer.value.scrollTop =
          this.scrollContainer.value.scrollHeight;
      }
    });
  }

  private handleScroll() {
    if (!this.scrollContainer.value) return;

    const container = this.scrollContainer.value;
    const isAtBottom =
      container.scrollTop + container.clientHeight >=
      container.scrollHeight - 50; // 50px tolerance

    this.showJumpToBottom = !isAtBottom;
  }

  private jumpToBottom() {
    this.scrollToBottom();
  }

  private formatTime(timestamp: string): string {
    const date = new Date(timestamp);
    return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  }

  private getMessageRole(message: AgentMessage): string {
    if (message.type === "user") {
      return "user";
    }
    if (message.type === "error") {
      return "error";
    }
    return "assistant";
  }

  private getMessageText(message: AgentMessage): string {
    return message.content || "";
  }

  private shouldShowMessage(message: AgentMessage): boolean {
    // Filter out hidden messages (subconversations) like the regular UI does
    if (message.hide_output) {
      return false;
    }

    // Show user, agent, and error messages with content
    return (
      (message.type === "user" ||
        message.type === "agent" ||
        message.type === "error") &&
      message.content &&
      message.content.trim().length > 0
    );
  }

  private renderMarkdown(markdownContent: string): string {
    try {
      // Create a custom renderer for mobile-optimized rendering
      const renderer = new Renderer();

      // Override code renderer to simplify for mobile
      renderer.code = function ({
        text,
        lang,
      }: {
        text: string;
        lang?: string;
      }): string {
        const langClass = lang ? ` class="language-${lang}"` : "";
        return `<pre><code${langClass}>${text}</code></pre>`;
      };

      // Set markdown options for mobile
      const markedOptions: MarkedOptions = {
        gfm: true, // GitHub Flavored Markdown
        breaks: true, // Convert newlines to <br>
        async: false,
        renderer: renderer,
      };

      // Parse markdown and sanitize the output HTML
      const htmlOutput = marked.parse(markdownContent, markedOptions) as string;
      return DOMPurify.sanitize(htmlOutput, {
        ALLOWED_TAGS: [
          "p",
          "br",
          "strong",
          "em",
          "b",
          "i",
          "u",
          "s",
          "code",
          "pre",
          "h1",
          "h2",
          "h3",
          "h4",
          "h5",
          "h6",
          "ul",
          "ol",
          "li",
          "blockquote",
          "a",
        ],
        ALLOWED_ATTR: ["href", "title", "target", "rel", "class"],
        KEEP_CONTENT: true,
      });
    } catch (error) {
      console.error("Error rendering markdown:", error);
      // Fallback to sanitized plain text if markdown parsing fails
      return DOMPurify.sanitize(markdownContent);
    }
  }

  private renderToolCalls(message: AgentMessage) {
    if (!message.tool_calls || message.tool_calls.length === 0) {
      return "";
    }

    return html`
      <div class="mt-3 flex flex-col gap-1.5">
        ${message.tool_calls.map((toolCall) => {
          const summary = this.getToolSummary(toolCall);

          return html`
            <div
              class="bg-black/[0.04] rounded-lg px-2 py-1.5 text-xs font-mono leading-snug flex items-center gap-1.5 ${toolCall.name}"
            >
              <span class="font-bold text-gray-800 flex-shrink-0 mr-0.5"
                >${toolCall.name}</span
              >
              <span
                class="text-gray-600 flex-grow overflow-hidden text-ellipsis whitespace-nowrap"
                >${summary}</span
              >
            </div>
          `;
        })}
      </div>
    `;
  }

  private getToolStatusIcon(_toolCall: any): string {
    // Don't show status icons for mobile
    return "";
  }

  private getToolSummary(toolCall: any): string {
    try {
      const input = JSON.parse(toolCall.input || "{}");

      /* eslint-disable no-case-declarations */
      switch (toolCall.name) {
        case "bash":
          const command = input.command || "";
          const isBackground = input.background === true;
          const bgPrefix = isBackground ? "[bg] " : "";
          return (
            bgPrefix +
            (command.length > 40 ? command.substring(0, 40) + "..." : command)
          );

        case "patch":
          const path = input.path || "unknown";
          const patchCount = (input.patches || []).length;
          return `${path}: ${patchCount} edit${patchCount > 1 ? "s" : ""}`;

        case "think":
          const thoughts = input.thoughts || "";
          const firstLine = thoughts.split("\n")[0] || "";
          return firstLine.length > 50
            ? firstLine.substring(0, 50) + "..."
            : firstLine;

        case "keyword_search":
          const query = input.query || "";
          return query.length > 50 ? query.substring(0, 50) + "..." : query;

        case "browser_navigate":
          return input.url || "";

        case "browser_take_screenshot":
          return "Taking screenshot";

        case "browser_click":
          return `Click: ${input.selector || ""}`;

        case "browser_type":
          const text = input.text || "";
          return `Type: ${text.length > 30 ? text.substring(0, 30) + "..." : text}`;

        case "todo_write":
          const tasks = input.tasks || [];
          return `${tasks.length} task${tasks.length > 1 ? "s" : ""}`;

        case "todo_read":
          return "Read todo list";

        case "multiplechoice":
          const question = input.question || "Multiple choice question";
          const options = input.responseOptions || [];
          if (options.length > 0) {
            const optionsList = options.map((opt) => opt.caption).join(", ");
            return `${question} [${optionsList}]`;
          }
          return question;

        case "done":
          return "Task completion checklist";

        default:
          // For unknown tools, show first part of input
          const inputStr = JSON.stringify(input);
          return inputStr.length > 50
            ? inputStr.substring(0, 50) + "..."
            : inputStr;
      }
      /* eslint-enable no-case-declarations */
    } catch {
      return "Tool call";
    }
  }

  private getToolDuration(_toolCall: any): string {
    // Don't show duration for mobile
    return "";
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    if (this.scrollContainer.value) {
      this.scrollContainer.value.removeEventListener(
        "scroll",
        this.handleScroll.bind(this),
      );
    }
  }

  render() {
    const displayMessages = this.messages.filter((msg) =>
      this.shouldShowMessage(msg),
    );

    return html`
      <div class="block h-full overflow-hidden">
        <div
          class="h-full overflow-y-auto p-4 flex flex-col gap-4 scroll-smooth"
          style="-webkit-overflow-scrolling: touch;"
          ${ref(this.scrollContainer)}
        >
          ${displayMessages.length === 0
            ? html`
                <div
                  class="empty-state flex-1 flex items-center justify-center text-gray-500 italic text-center p-8"
                >
                  Start a conversation with Sketch...
                </div>
              `
            : displayMessages.map((message) => {
                const role = this.getMessageRole(message);
                const text = this.getMessageText(message);
                // const timestamp = message.timestamp; // Unused for mobile layout

                return html`
                  <div
                    class="message ${role} flex flex-col max-w-[85%] break-words ${role ===
                    "user"
                      ? "self-end items-end"
                      : "self-start items-start"}"
                  >
                    <div
                      class="message-bubble px-3 py-2 rounded-[18px] text-base leading-relaxed ${role ===
                      "user"
                        ? "bg-blue-500 text-white rounded-br-[6px]"
                        : role === "error"
                          ? "bg-red-50 text-red-700"
                          : "bg-gray-100 text-gray-800 rounded-bl-[6px]"}"
                    >
                      ${role === "assistant"
                        ? html`<div class="leading-6 break-words">
                            <style>
                              .markdown-content p {
                                margin: 0.3em 0;
                              }
                              .markdown-content p:first-child {
                                margin-top: 0;
                              }
                              .markdown-content p:last-child {
                                margin-bottom: 0;
                              }
                              .markdown-content h1,
                              .markdown-content h2,
                              .markdown-content h3,
                              .markdown-content h4,
                              .markdown-content h5,
                              .markdown-content h6 {
                                margin: 0.5em 0 0.3em 0;
                                font-weight: bold;
                              }
                              .markdown-content h1 {
                                font-size: 1.2em;
                              }
                              .markdown-content h2 {
                                font-size: 1.15em;
                              }
                              .markdown-content h3 {
                                font-size: 1.1em;
                              }
                              .markdown-content h4,
                              .markdown-content h5,
                              .markdown-content h6 {
                                font-size: 1.05em;
                              }
                              .markdown-content code {
                                background-color: rgba(0, 0, 0, 0.08);
                                padding: 2px 4px;
                                border-radius: 3px;
                                font-family:
                                  Monaco, Menlo, "Ubuntu Mono", monospace;
                                font-size: 0.9em;
                              }
                              .markdown-content pre {
                                background-color: rgba(0, 0, 0, 0.08);
                                padding: 8px;
                                border-radius: 6px;
                                margin: 0.5em 0;
                                overflow-x: auto;
                                font-size: 0.9em;
                              }
                              .markdown-content pre code {
                                background: none;
                                padding: 0;
                              }
                              .markdown-content ul,
                              .markdown-content ol {
                                margin: 0.5em 0;
                                padding-left: 1.2em;
                              }
                              .markdown-content li {
                                margin: 0.2em 0;
                              }
                              .markdown-content blockquote {
                                border-left: 3px solid rgba(0, 0, 0, 0.2);
                                margin: 0.5em 0;
                                padding-left: 0.8em;
                                font-style: italic;
                              }
                              .markdown-content a {
                                color: inherit;
                                text-decoration: underline;
                              }
                              .markdown-content strong,
                              .markdown-content b {
                                font-weight: bold;
                              }
                              .markdown-content em,
                              .markdown-content i {
                                font-style: italic;
                              }
                            </style>
                            <div class="markdown-content">
                              ${unsafeHTML(this.renderMarkdown(text))}
                            </div>
                          </div>`
                        : text}
                      ${this.renderToolCalls(message)}
                    </div>
                  </div>
                `;
              })}
          ${this.isThinking
            ? html`
                <div
                  class="thinking-message flex flex-col max-w-[85%] break-words self-start items-start"
                >
                  <div
                    class="bg-gray-100 p-4 rounded-[18px] rounded-bl-[6px] flex items-center gap-2"
                  >
                    <span class="thinking-text text-gray-500 italic"
                      >Sketch is thinking</span
                    >
                    <div class="thinking-dots flex gap-1">
                      <div
                        class="w-1.5 h-1.5 rounded-full bg-gray-500 thinking-dot"
                      ></div>
                      <div
                        class="w-1.5 h-1.5 rounded-full bg-gray-500 thinking-dot"
                      ></div>
                      <div
                        class="w-1.5 h-1.5 rounded-full bg-gray-500 thinking-dot"
                      ></div>
                    </div>
                  </div>
                </div>
              `
            : ""}
        </div>
      </div>

      ${this.showJumpToBottom
        ? html`
            <button
              class="fixed bottom-[70px] left-1/2 transform -translate-x-1/2 bg-black/60 text-white border-none rounded-xl px-2 py-1 text-xs font-normal cursor-pointer shadow-sm z-[1100] transition-all duration-150 flex items-center gap-1 opacity-80 hover:bg-black/80 hover:-translate-y-px hover:opacity-100 hover:shadow-md active:translate-y-0"
              @click=${this.jumpToBottom}
              aria-label="Jump to bottom"
            >
              ↓ Jump to bottom
            </button>
          `
        : ""}
    `;
  }
}
