import type { ListedPost } from "@halo-dev/api-client";
import i18next from "i18next";
import { Modal, Notice, Setting, requestUrl } from "obsidian";
import type HaloPlugin from "../main";
import type { HaloSite } from "../settings";
import { exportPostAsMarkdown, exportPostAsJson } from "../commands/export-post";

export function openSearchModal(plugin: HaloPlugin, site: HaloSite): void {
  const modal = new SearchModal(plugin, site);
  modal.open();
}

class SearchModal extends Modal {
  private posts: ListedPost[] = [];
  private filteredPosts: ListedPost[] = [];
  private searchKeyword = "";
  private filter: "all" | "published" | "draft" = "all";

  constructor(
    private readonly plugin: HaloPlugin,
    private readonly site: HaloSite,
  ) {
    super(app);
  }

  async onOpen() {
    const { contentEl } = this;
    contentEl.empty();

    contentEl.createEl("h2", {
      text: i18next.t("search_modal.title"),
    });

    const searchInput = new Setting(contentEl)
      .setName(i18next.t("search_modal.search_placeholder"))
      .addText((text) => {
        text.setPlaceholder(i18next.t("search_modal.search_placeholder"))
          .onChange((value) => {
            this.searchKeyword = value;
            this.filterPosts();
            this.renderResults();
          });
      });

    const filterEl = contentEl.createDiv("search-filter");
    
    const allButton = filterEl.createEl("button", {
      text: i18next.t("post_selection_modal.filter_all"),
      cls: this.filter === "all" ? "active" : "",
    });
    allButton.addEventListener("click", async () => {
      this.filter = "all";
      await this.loadPosts();
      this.renderResults();
    });

    const publishedButton = filterEl.createEl("button", {
      text: i18next.t("post_selection_modal.filter_published"),
      cls: this.filter === "published" ? "active" : "",
    });
    publishedButton.addEventListener("click", async () => {
      this.filter = "published";
      await this.loadPosts();
      this.renderResults();
    });

    const draftButton = filterEl.createEl("button", {
      text: i18next.t("post_selection_modal.filter_draft"),
      cls: this.filter === "draft" ? "active" : "",
    });
    draftButton.addEventListener("click", async () => {
      this.filter = "draft";
      await this.loadPosts();
      this.renderResults();
    });

    const resultsEl = contentEl.createDiv("search-results");
    resultsEl.createEl("p", { text: i18next.t("search_modal.loading") });

    await this.loadPosts();
    this.renderResults();
  }

  private async loadPosts() {
    try {
      let labelSelector = "content.halo.run/deleted=false";
      
      if (this.filter === "published") {
        labelSelector = "content.halo.run/deleted=false,content.halo.run/published=true";
      } else if (this.filter === "draft") {
        labelSelector = "content.halo.run/deleted=false,content.halo.run/published=false";
      }

      const response = await requestUrl({
        url: `${this.site.url}/apis/uc.api.content.halo.run/v1alpha1/posts?labelSelector=${encodeURIComponent(labelSelector)}&size=100`,
        headers: {
          Authorization: `Bearer ${this.site.token}`,
        },
      });

      this.posts = response.json.items || [];
      this.filterPosts();
    } catch (error) {
      new Notice(i18next.t("common.error_connection_failed"));
    }
  }

  private filterPosts() {
    if (!this.searchKeyword) {
      this.filteredPosts = this.posts;
      return;
    }

    const keyword = this.searchKeyword.toLowerCase();
    this.filteredPosts = this.posts.filter((post) => {
      const title = (post.post.spec.title || "").toLowerCase();
      const slug = (post.post.spec.slug || "").toLowerCase();
      return title.includes(keyword) || slug.includes(keyword);
    });
  }

  private renderResults() {
    const { contentEl } = this;
    const resultsEl = contentEl.querySelector(".search-results") as HTMLElement;
    
    if (!resultsEl) return;
    
    resultsEl.empty();

    if (this.filteredPosts.length === 0) {
      resultsEl.createEl("p", { text: i18next.t("search_modal.no_results") });
      return;
    }

    resultsEl.createEl("p", { 
      text: i18next.t("search_modal.result_count", { count: this.filteredPosts.length }),
      cls: "result-count"
    });

    for (const post of this.filteredPosts) {
      this.renderPostItem(post, resultsEl);
    }
  }

  private renderPostItem(post: ListedPost, container: HTMLElement) {
    const postEl = container.createDiv("search-result-item");
    
    const headerEl = postEl.createDiv("result-header");
    
    const titleEl = headerEl.createEl("h3", {
      text: post.post.spec.title || i18next.t("post_selection_modal.untitled"),
    });

    const statusEl = headerEl.createSpan({
      text: post.post.spec.publish ? i18next.t("post_selection_modal.status_published") : i18next.t("post_selection_modal.status_draft"),
      cls: post.post.spec.publish ? "status-published" : "status-draft",
    });

    const metaEl = postEl.createDiv("result-meta");
    metaEl.createEl("span", { text: `Slug: ${post.post.spec.slug}` });
    metaEl.createEl("span", { text: ` | ${new Date(post.post.metadata.creationTimestamp).toLocaleDateString()}` });

    const actionsEl = postEl.createDiv("result-actions");
    
    actionsEl.createEl("button", {
      text: i18next.t("search_modal.button_view"),
    }).addEventListener("click", () => {
      window.open(`${this.site.url}/archives/${post.post.spec.slug}`, "_blank");
    });

    actionsEl.createEl("button", {
      text: i18next.t("search_modal.button_export_md"),
    }).addEventListener("click", async () => {
      await exportPostAsMarkdown(this.plugin, post.post.metadata.name, post.post.spec.title);
    });

    actionsEl.createEl("button", {
      text: i18next.t("search_modal.button_export_json"),
    }).addEventListener("click", async () => {
      await exportPostAsJson(this.plugin, post.post.metadata.name, post.post.spec.title);
    });
  }

  onClose() {
    const { contentEl } = this;
    contentEl.empty();
  }
}