import i18next from "i18next";
import { Modal, Notice, Setting } from "obsidian";
import type HaloPlugin from "../main";
import type { HaloSite } from "../settings";
import HaloService from "../service";

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

interface TagFormData {
  name: string;
  slug: string;
  color: string;
}

class TagFormModal extends Modal {
  private tag: { metadata: { name: string }; spec: { displayName: string; slug: string; color: string } } | null = null;
  private isEdit = false;
  private onSubmit: (data: TagFormData) => void;

  constructor(
    private plugin: HaloPlugin,
    private site: HaloSite,
    tag: TagFormModal["tag"],
    private onSubmitFn: (data: TagFormData) => void
  ) {
    super(app);
    this.tag = tag;
    this.isEdit = !!tag;
    this.onSubmit = onSubmitFn;
  }

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

    const modalEl = contentEl.createDiv("halo-modal");
    modalEl.style.cssText = `
      position: fixed; inset: 0; z-index: 1000;
      display: flex; align-items: center; justify-content: center;
      background: rgba(0,0,0,0.5); -webkit-backdrop-filter: blur(4px);
    `;

    const content = modalEl.createDiv("halo-card");
    content.style.cssText = `
      width: 100%; max-width: 440px; max-height: 90vh; overflow-y: auto;
      padding: var(--space-6);
    `;

    const header = content.createDiv("halo-modal-header");
    header.style.cssText = "margin-bottom: var(--space-4);";

    const title = header.createEl("h3");
    title.textContent = this.isEdit
      ? i18next.t("tag_manager_modal.title_edit")
      : i18next.t("tag_manager_modal.title_create");
    title.style.cssText = "font-size: 18px; font-weight: 600; margin: 0;";

    const closeBtn = header.createEl("button", { text: "✕" });
    closeBtn.className = "halo-modal-close";
    closeBtn.style.cssText = `
      display: flex; align-items: center; justify-content: center;
      width: 32px; height: 32px; background: transparent; border: none;
      border-radius: 8px; color: var(--text-muted); cursor: pointer; font-size: 16px;
    `;
    closeBtn.addEventListener("click", () => this.close());

    const form = content.createDiv("halo-modal-body");

    // Name field
    const nameGroup = form.createDiv("halo-form-group");
    const nameLabel = nameGroup.createEl("label", { text: i18next.t("tag_manager_modal.column_name") });
    nameLabel.className = "halo-form-label";
    const nameInput = nameGroup.createEl("input", { type: "text" }) as HTMLInputElement;
    nameInput.className = "halo-input";
    nameInput.style.cssText = "width: 100%;";
    nameInput.value = this.tag?.spec.displayName || "";
    nameInput.placeholder = i18next.t("tag_manager_modal.prompt_name");

    // Slug field
    const slugGroup = form.createDiv("halo-form-group");
    const slugLabel = slugGroup.createEl("label", { text: i18next.t("tag_manager_modal.column_slug") });
    slugLabel.className = "halo-form-label";
    const slugInput = slugGroup.createEl("input", { type: "text" }) as HTMLInputElement;
    slugInput.className = "halo-input";
    slugInput.style.cssText = "width: 100%;";
    slugInput.value = this.tag?.spec.slug || "";
    slugInput.placeholder = i18next.t("tag_manager_modal.prompt_slug");

    // Color field
    const colorGroup = form.createDiv("halo-form-group");
    const colorLabel = colorGroup.createEl("label", { text: i18next.t("tag_manager_modal.column_color") });
    colorLabel.className = "halo-form-label";

    const colorPicker = colorGroup.createDiv("halo-color-picker");
    colorPicker.style.cssText = "display: flex; align-items: center; gap: var(--space-3);";

    const colorPreview = colorPicker.createEl("input", { type: "color" }) as HTMLInputElement;
    colorPreview.style.cssText = `
      width: 40px; height: 36px; padding: 2px; border: 1px solid var(--border-color);
      border-radius: var(--radius-md); cursor: pointer; background: transparent;
    `;
    colorPreview.value = this.tag?.spec.color || "#4A90E2";

    const colorInput = colorPicker.createEl("input", { type: "text" }) as HTMLInputElement;
    colorInput.className = "halo-input halo-color-input";
    colorInput.style.cssText = "flex: 1; font-family: monospace;";
    colorInput.value = this.tag?.spec.color || "#4A90E2";

    // Color preview update
    colorPreview.addEventListener("input", () => {
      colorInput.value = colorPreview.value;
    });
    colorInput.addEventListener("input", () => {
      if (/^#[0-9A-Fa-f]{6}$/.test(colorInput.value)) {
        colorPreview.value = colorInput.value;
      }
    });

    // Preset colors
    const presets = colorGroup.createDiv("halo-color-presets");
    presets.style.cssText = "display: flex; gap: var(--space-2); margin-top: var(--space-2); flex-wrap: wrap;";
    const presetColors = ["#4A90E2", "#67C23A", "#E6A23C", "#F56C6C", "#909399", "#8E44AD", "#3498DB", "#1ABC9C"];

    for (const color of presetColors) {
      const preset = presets.createEl("button");
      preset.style.cssText = `
        width: 24px; height: 24px; border-radius: var(--radius-sm);
        background: ${color}; border: 2px solid transparent;
        cursor: pointer; transition: all var(--transition-fast);
      `;
      preset.addEventListener("click", () => {
        colorPreview.value = color;
        colorInput.value = color;
      });
      preset.addEventListener("mouseenter", () => {
        preset.style.transform = "scale(1.15)";
        preset.style.borderColor = "var(--interactive-accent)";
      });
      preset.addEventListener("mouseleave", () => {
        preset.style.transform = "scale(1)";
        preset.style.borderColor = "transparent";
      });
    }

    // Footer buttons
    const footer = content.createDiv("halo-modal-footer");
    footer.style.cssText = "margin-top: var(--space-4);";

    const cancelBtn = footer.createEl("button", { text: i18next.t("common.button_cancel") });
    cancelBtn.className = "halo-btn halo-btn-secondary";
    cancelBtn.addEventListener("click", () => this.close());

    const submitBtn = footer.createEl("button", { text: this.isEdit ? i18next.t("common.button_save") : i18next.t("tag_manager_modal.button_create") });
    submitBtn.className = "halo-btn halo-btn-primary";

    submitBtn.addEventListener("click", () => {
      const name = nameInput.value.trim();
      const slug = slugInput.value.trim() || this.generateSlug(name);
      const color = colorInput.value.trim() || "#4A90E2";

      if (!name) {
        nameInput.classList.add("error");
        return;
      }

      this.onSubmit({ name, slug, color });
      this.close();
    });

    // Auto-generate slug on name change
    nameInput.addEventListener("input", () => {
      if (!this.isEdit || !this.tag) {
        slugInput.value = this.generateSlug(nameInput.value);
      }
    });

    modalEl.addEventListener("click", (e) => {
      if (e.target === modalEl) this.close();
    });

    nameInput.focus();
  }

  private generateSlug(name: string): string {
    return name
      .toLowerCase()
      .replace(/[^a-z0-9一-龥]+/g, "-")
      .replace(/^-|-$/g, "");
  }
}

class TagManagerModal extends Modal {
  private tags: Array<{ metadata: { name: string }; spec: { displayName: string; slug: string; color: string } }> = [];
  private loading = true;

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

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

    contentEl.createEl("h2", {
      text: i18next.t("tag_manager_modal.title"),
      cls: "modal-title"
    });

    const actionsEl = contentEl.createDiv("tag-manager-actions");
    actionsEl.style.cssText = "display: flex; justify-content: space-between; align-items: center; padding: var(--space-4);";

    const createBtn = actionsEl.createEl("button", {
      text: i18next.t("tag_manager_modal.button_create"),
      cls: "halo-btn halo-btn-primary"
    });
    createBtn.addEventListener("click", () => this.showCreateTagForm());

    const closeBtn = actionsEl.createEl("button", {
      text: i18next.t("common.button_close"),
      cls: "halo-btn halo-btn-secondary"
    });
    closeBtn.addEventListener("click", () => this.close());

    const listEl = contentEl.createDiv("tag-list");
    listEl.style.cssText = "padding: 0 var(--space-4) var(--space-4);";

    const loadingEl = listEl.createDiv("halo-empty");
    loadingEl.style.cssText = "padding: var(--space-6);";
    loadingEl.innerHTML = `<div class="halo-spinner"></div><p style="margin-top: var(--space-3); color: var(--text-muted);">${i18next.t("tag_manager_modal.loading")}</p>`;

    try {
      const service = new HaloService(this.plugin.app, this.plugin.settings, this.site);
      this.tags = await service.getTags();
      this.loading = false;
      this.renderTagList();
    } catch {
      new Notice(i18next.t("common.error_connection_failed"));
      this.close();
    }
  }

  private renderTagList() {
    const { contentEl } = this;
    const listEl = contentEl.querySelector(".tag-list") as HTMLElement;

    if (!listEl) return;

    listEl.empty();

    if (this.tags.length === 0) {
      const emptyEl = listEl.createDiv("halo-empty");
      emptyEl.innerHTML = `
        <div style="font-size: 48px; opacity: 0.5;">🏷️</div>
        <p style="margin-top: var(--space-3); font-weight: 500;">${i18next.t("tag_manager_modal.empty")}</p>
      `;
      return;
    }

    const table = listEl.createEl("table", { cls: "halo-table" });
    const header = table.createEl("thead").createEl("tr");
    header.createEl("th", { text: i18next.t("tag_manager_modal.column_name") });
    header.createEl("th", { text: i18next.t("tag_manager_modal.column_slug") });
    header.createEl("th", { text: i18next.t("tag_manager_modal.column_color") });
    header.createEl("th", { text: i18next.t("tag_manager_modal.column_actions"), cls: "text-right" });

    const tbody = table.createEl("tbody");

    for (const tag of this.tags) {
      const row = tbody.createEl("tr");

      const nameCell = row.createEl("td");
      nameCell.style.cssText = "font-weight: 500;";
      nameCell.textContent = tag.spec.displayName;

      row.createEl("td", { text: tag.spec.slug });

      const colorCell = row.createEl("td");
      const colorBadge = colorCell.createEl("span", { text: " " });
      colorBadge.style.cssText = `
        display: inline-block; width: 16px; height: 16px;
        background: ${tag.spec.color || "#ffffff"}; border-radius: var(--radius-sm);
        border: 1px solid var(--border-color); vertical-align: middle;
      `;
      colorCell.createSpan({ text: ` ${tag.spec.color || "#ffffff"}` });

      const actionsCell = row.createEl("td");
      actionsCell.style.cssText = "text-align: right;";

      const editBtn = actionsCell.createEl("button", {
        text: i18next.t("tag_manager_modal.button_edit"),
        cls: "halo-btn halo-btn-sm halo-btn-ghost"
      });
      editBtn.addEventListener("click", () => this.showEditTagForm(tag));

      const deleteBtn = actionsCell.createEl("button", {
        text: i18next.t("tag_manager_modal.button_delete"),
        cls: "halo-btn halo-btn-sm halo-btn-ghost"
      });
      deleteBtn.style.cssText += "color: var(--halo-danger);";
      deleteBtn.addEventListener("click", () => this.showDeleteTagDialog(tag));
    }
  }

  private showCreateTagForm() {
    new TagFormModal(this.plugin, this.site, null, async (data) => {
      try {
        const service = new HaloService(this.plugin.app, this.plugin.settings, this.site);
        await service.createTag(data.name, data.slug, data.color);
        new Notice(i18next.t("tag_manager_modal.notice_create_success"));
        this.tags = await service.getTags();
        this.renderTagList();
      } catch {
        new Notice(i18next.t("tag_manager_modal.error_create_failed"));
      }
    });
  }

  private showEditTagForm(tag: typeof this.tags[0]) {
    new TagFormModal(this.plugin, this.site, tag, async (data) => {
      try {
        const service = new HaloService(this.plugin.app, this.plugin.settings, this.site);
        await service.updateTag(tag.metadata.name, data.name, data.slug, data.color);
        new Notice(i18next.t("tag_manager_modal.notice_update_success"));
        this.tags = await service.getTags();
        this.renderTagList();
      } catch {
        new Notice(i18next.t("tag_manager_modal.error_update_failed"));
      }
    });
  }

  private showDeleteTagDialog(tag: typeof this.tags[0]) {
    const modalEl = document.createElement("div");
    modalEl.style.cssText = `
      position: fixed; inset: 0; z-index: 1000;
      display: flex; align-items: center; justify-content: center;
      background: rgba(0,0,0,0.5); -webkit-backdrop-filter: blur(4px);
    `;

    const content = modalEl.createDiv("halo-card");
    content.style.cssText = "width: 100%; max-width: 400px; padding: var(--space-6);";

    const title = content.createEl("h3", {
      text: i18next.t("tag_manager_modal.confirm_delete", { name: tag.spec.displayName })
    });
    title.style.cssText = "font-size: 16px; font-weight: 600; margin: 0 0 var(--space-4) 0;";

    const actions = content.createDiv("halo-modal-footer");
    actions.style.cssText = "margin-top: var(--space-4);";

    const cancelBtn = actions.createEl("button", {
      text: i18next.t("common.button_cancel"),
      cls: "halo-btn halo-btn-secondary"
    });
    cancelBtn.addEventListener("click", () => modalEl.remove());

    const deleteBtn = actions.createEl("button", {
      text: i18next.t("common.button_delete"),
      cls: "halo-btn halo-btn-danger"
    });
    deleteBtn.addEventListener("click", async () => {
      modalEl.remove();
      try {
        const service = new HaloService(this.plugin.app, this.plugin.settings, this.site);
        await service.deleteTag(tag.metadata.name);
        new Notice(i18next.t("tag_manager_modal.notice_delete_success"));
        this.tags = await service.getTags();
        this.renderTagList();
      } catch {
        new Notice(i18next.t("tag_manager_modal.error_delete_failed"));
      }
    });

    modalEl.addEventListener("click", (e) => {
      if (e.target === modalEl) modalEl.remove();
    });

    document.body.appendChild(modalEl);
  }

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