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";

export function openPostSelectionModal(plugin: HaloPlugin, site: HaloSite): Promise<ListedPost> {
  return new Promise<ListedPost>((resolve, reject) => {
    const modal = new PostSelectionModal(plugin, site, (post) => {
      resolve(post);
    });
    modal.open();
  });
}

class PostSelectionModal extends Modal {
  private currentPage = 1;
  private pageSize = 20;
  private totalItems = 0;
  private posts: ListedPost[] = [];
  private filter: "all" | "published" | "draft" = "all";

  constructor(
    private readonly plugin: HaloPlugin,
    private readonly site: HaloSite,
    private readonly onSelect: (post: ListedPost) => void,
  ) {
    super(app);
  }

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

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

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

  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)}&page=${this.currentPage}&size=${this.pageSize}`,
        headers: {
          Authorization: `Bearer ${this.site.token}`,
        },
      });

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

  private render() {
    const { contentEl } = this;
    contentEl.empty();

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

    this.renderFilter();

    if (this.posts.length === 0) {
      contentEl.createEl("p", {
        text: i18next.t("post_selection_modal.empty"),
      });
    } else {
      for (const post of this.posts) {
        this.renderPostItem(post);
      }
    }

    this.renderPagination();
  }

  private renderFilter() {
    const filterEl = this.contentEl.createDiv("post-list-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";
      this.currentPage = 1;
      await this.loadPosts();
      this.render();
    });

    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";
      this.currentPage = 1;
      await this.loadPosts();
      this.render();
    });

    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";
      this.currentPage = 1;
      await this.loadPosts();
      this.render();
    });
  }

  private renderPostItem(post: ListedPost) {
    const postEl = this.contentEl.createDiv("post-item");
    
    const headerEl = postEl.createDiv("post-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("post-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("post-actions");
    
    actionsEl.createEl("button", {
      text: i18next.t("post_selection_modal.button_pull"),
      cls: "mod-cta",
    }).addEventListener("click", () => {
      this.onSelect(post);
      this.close();
    });

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

  private renderPagination() {
    const paginationEl = this.contentEl.createDiv("pagination");
    
    const totalPages = Math.ceil(this.totalItems / this.pageSize);
    
    if (this.currentPage > 1) {
      paginationEl.createEl("button", {
        text: i18next.t("post_selection_modal.button_prev"),
      }).addEventListener("click", async () => {
        this.currentPage--;
        await this.loadPosts();
        this.render();
      });
    }

    paginationEl.createEl("span", {
      text: `${this.currentPage} / ${totalPages} (${this.totalItems} ${i18next.t("post_selection_modal.total_items")})`,
    });

    if (this.currentPage < totalPages) {
      paginationEl.createEl("button", {
        text: i18next.t("post_selection_modal.button_next"),
      }).addEventListener("click", async () => {
        this.currentPage++;
        await this.loadPosts();
        this.render();
      });
    }

    new Setting(paginationEl).addButton((button) =>
      button.setButtonText(i18next.t("common.button_close")).onClick(() => this.close()),
    );
  }

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