import { Alpine } from "./alpine";
import { getSelectedLibrary } from "./storage";
import { showToast } from "./toast";

// ============================================================
// Collection Rules Page - Auto-Assign Rule Management
// ============================================================

let collectionId = "";

function initCollectionRules(id: string): void {
  collectionId = id;
  loadRules();
  setupEventDelegation();
}

function setupEventDelegation(): void {
  const container = document.getElementById("rules-container");
  if (!container) return;

  container.addEventListener("click", (e) => {
    const target = e.target as HTMLElement;
    const button = target.closest("button") as HTMLButtonElement;

    if (!button) return;

    const action = button.dataset.action;
    const ruleId = button.dataset.ruleId;

    if (action === "toggle" && ruleId) {
      const enabled = button.dataset.enabled === "true";
      toggleRule(ruleId, enabled);
    } else if (action === "delete" && ruleId) {
      deleteRule(ruleId);
    }
  });
}

function backToCollection(): void {
  if (!collectionId) return;
  const libraryId = getSelectedLibrary();
  const url = libraryId
    ? `/collections/${collectionId}?library_id=${libraryId}`
    : `/collections/${collectionId}`;
  window.location.href = url;
}

function getFieldLabel(field: string): string {
  const labels: Record<string, string> = {
    genre: "Genre",
    series: "Series",
    author: "Author",
    language: "Language",
    publisher: "Publisher",
    copyright_year: "Copyright Year",
    tags: "Tags",
  };
  return labels[field] || field;
}

function getOperatorLabel(operator: string): string {
  const labels: Record<string, string> = {
    equals: "equals",
    not_equals: "does not equal",
    contains: "contains",
    not_contains: "does not contain",
    starts_with: "starts with",
    ends_with: "ends with",
    greater_than: "greater than",
    less_than: "less than",
  };
  return labels[operator] || operator;
}

async function loadRules(): Promise<void> {
  const token = localStorage.getItem("token");
  if (!token || !collectionId) return;

  try {
    const response = await fetch(`/api/collections/${collectionId}`, {
      headers: { Authorization: `Bearer ${token}` },
    });

    if (response.ok) {
      const data = await response.json();
      renderRules(data.auto_assign_rules || []);
    }
  } catch (error) {
    console.error("Failed to load rules", error);
  }
}

function renderRules(rules: CollectionRule[]): void {
  const container = document.getElementById("rules-container");
  const noRulesDiv = document.getElementById("no-rules");
  if (!container || !noRulesDiv) return;

  if (rules && rules.length > 0) {
    noRulesDiv.classList.add("hidden");

    container.innerHTML = rules
      .map(
        (rule) => `
        <div class="card p-4 rounded-lg border" style="background-color: var(--bg-secondary); border-color: var(--border);">
          <div class="flex justify-between items-start">
            <div class="flex-1">
              <div class="flex items-center gap-3 mb-2">
                <span class="font-semibold" style="color: var(--text-primary)">
                  ${getFieldLabel(rule.field)}
                </span>
                <span class="px-2 py-1 text-xs rounded" style="background-color: ${rule.enabled ? "var(--accent)" : "var(--text-secondary)"}; color: var(--bg-primary);">
                  ${rule.enabled ? "Enabled" : "Disabled"}
                </span>
                <span class="px-2 py-1 text-xs rounded" style="background-color: var(--bg-secondary); color: var(--text-primary);">
                  Priority ${rule.priority}
                </span>
              </div>
              <code class="block text-sm" style="color: var(--text-secondary);">
                ${getOperatorLabel(rule.operator)} "${rule.value}"
              </code>
            </div>
            <div class="flex space-x-2">
              <button data-action="toggle" data-rule-id="${rule.id}" data-enabled="${!rule.enabled}"
                      class="p-2 hover:opacity-80 rounded" style="color: var(--text-secondary); background-color: var(--bg-primary);">
                ${rule.enabled ? "⏸️" : "▶️"}
              </button>
              <button data-action="delete" data-rule-id="${rule.id}"
                      class="p-2 hover:opacity-80 rounded" style="color: var(--text-secondary); background-color: var(--bg-primary);">
                🗑️
              </button>
            </div>
          </div>
        </div>
      `,
      )
      .join("");
  } else {
    noRulesDiv.classList.remove("hidden");
  }
}

async function handleCreateRule(event: Event): Promise<void> {
  event.preventDefault();

  const token = localStorage.getItem("token");
  if (!token || !collectionId) return;

  const fieldInput = document.getElementById("rule-field") as HTMLSelectElement;
  const operatorInput = document.getElementById(
    "rule-operator",
  ) as HTMLSelectElement;
  const valueInput = document.getElementById("rule-value") as HTMLInputElement;
  const enabledInput = document.getElementById(
    "rule-enabled",
  ) as HTMLInputElement;
  const priorityInput = document.querySelector(
    'input[name="priority"]:checked',
  ) as HTMLInputElement;

  if (
    !fieldInput ||
    !operatorInput ||
    !valueInput ||
    !enabledInput ||
    !priorityInput
  ) {
    showToast("Missing form fields", "error");
    return;
  }

  const data = {
    field: fieldInput.value,
    operator: operatorInput.value,
    value: valueInput.value,
    enabled: enabledInput.checked,
    priority: parseInt(priorityInput.value, 10),
  };

  try {
    const response = await fetch(`/api/collections/${collectionId}/rules`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify(data),
    });

    if (response.ok) {
      showToast("Rule created successfully", "success");
      clearForm();
      loadRules();
    } else {
      showToast("Failed to create rule", "error");
    }
  } catch (error) {
    console.error("Failed to create rule", error);
    showToast("Failed to create rule", "error");
  }
}

async function testRule(): Promise<void> {
  const token = localStorage.getItem("token");
  if (!token) return;

  const fieldInput = document.getElementById("rule-field") as HTMLSelectElement;
  const operatorInput = document.getElementById(
    "rule-operator",
  ) as HTMLSelectElement;
  const valueInput = document.getElementById("rule-value") as HTMLInputElement;

  if (!fieldInput || !operatorInput || !valueInput) {
    showToast("Missing form fields", "error");
    return;
  }

  const field = fieldInput.value;
  const operator = operatorInput.value;
  const value = valueInput.value;

  if (!field || !operator || !value) {
    showToast("Please fill in all rule fields", "error");
    return;
  }

  const testResultsDiv = document.getElementById("test-results");
  const resultsList = document.getElementById("test-results-list");
  if (!testResultsDiv || !resultsList) return;

  testResultsDiv.classList.remove("hidden");
  resultsList.innerHTML =
    '<p class="text-sm" style="color: var(--text-secondary)">Testing rule...</p>';

  const rules = [
    {
      field: field,
      operator: operator,
      value: value,
    },
  ];

  try {
    const response = await fetch("/api/collections/test-rules", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({ rules: rules }),
    });

    if (response.ok) {
      const result = await response.json();
      if (result.matches && result.matches.length > 0) {
        let html =
          '<p style="color: var(--text-secondary); font-size: 0.875rem;">Found ' +
          result.matches.length +
          " matching books:</p>";
        html +=
          '<div style="display: flex; flex-direction: column; gap: 0.5rem;">';

        result.matches.slice(0, 20).forEach((book: TestRuleMatch) => {
          html +=
            '<div style="display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem; border-radius: 0.25rem; background-color: var(--bg-secondary);">';
          html +=
            '<img src="' +
            (book.cover_image_path || "/static/placeholder-book.svg") +
            '" alt="Cover" style="width: 2rem; height: 3rem; object-fit: cover; border-radius: 0.25rem;">';
          html += '<div style="flex: 1;">';
          html +=
            '<div style="font-size: 0.875rem; font-weight: 500; color: var(--text-primary);">' +
            book.title +
            "</div>";
          if (book.author) {
            html +=
              '<div style="font-size: 0.75rem; color: var(--text-secondary);">' +
              book.author +
              "</div>";
          }
          if (book.match_reason) {
            html +=
              '<div style="font-size: 0.75rem; color: var(--accent);">' +
              book.match_reason +
              "</div>";
          }
          html += "</div>";
          html += "</div>";
        });

        if (result.matches.length > 20) {
          html +=
            '<p style="color: var(--text-secondary); font-size: 0.875rem;">...and ' +
            (result.matches.length - 20) +
            " more</p>";
        }

        html += "</div>";
        resultsList.innerHTML = html;
      } else {
        resultsList.innerHTML =
          '<p style="color: var(--text-secondary); font-size: 0.875rem;">No books match this rule</p>';
      }
    } else {
      resultsList.innerHTML =
        '<p class="text-sm" style="color: var(--error)">Failed to test rule</p>';
    }
  } catch (error) {
    console.error("Failed to test rule", error);
    resultsList.innerHTML =
      '<p class="text-sm" style="color: var(--error)">Failed to test rule</p>';
  }
}

async function toggleRule(ruleId: string, enabled: boolean): Promise<void> {
  const token = localStorage.getItem("token");
  if (!token || !collectionId) return;

  try {
    const response = await fetch(
      `/api/collections/${collectionId}/rules/${ruleId}`,
      {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({ enabled }),
      },
    );

    if (response.ok) {
      showToast("Rule updated", "success");
      loadRules();
    } else {
      showToast("Failed to update rule", "error");
    }
  } catch (error) {
    console.error("Failed to update rule", error);
    showToast("Failed to update rule", "error");
  }
}

async function deleteRule(ruleId: string): Promise<void> {
  if (!confirm("Are you sure you want to delete this rule?")) return;

  const token = localStorage.getItem("token");
  if (!token || !collectionId) return;

  try {
    const response = await fetch(
      `/api/collections/${collectionId}/rules/${ruleId}`,
      {
        method: "DELETE",
        headers: { Authorization: `Bearer ${token}` },
      },
    );

    if (response.ok) {
      showToast("Rule deleted", "success");
      loadRules();
    } else {
      showToast("Failed to delete rule", "error");
    }
  } catch (error) {
    console.error("Failed to delete rule", error);
    showToast("Failed to delete rule", "error");
  }
}

function clearForm(): void {
  const fieldInput = document.getElementById("rule-field") as HTMLSelectElement;
  const operatorInput = document.getElementById(
    "rule-operator",
  ) as HTMLSelectElement;
  const valueInput = document.getElementById("rule-value") as HTMLInputElement;
  const enabledInput = document.getElementById(
    "rule-enabled",
  ) as HTMLInputElement;
  const priorityInput = document.querySelector(
    'input[name="priority"][value="2"]',
  ) as HTMLInputElement;
  const testResultsDiv = document.getElementById("test-results");

  if (fieldInput) fieldInput.value = "";
  if (operatorInput) operatorInput.value = "";
  if (valueInput) valueInput.value = "";
  if (enabledInput) enabledInput.checked = true;
  if (priorityInput) priorityInput.checked = true;
  if (testResultsDiv) testResultsDiv.classList.add("hidden");
}

function logout(): void {
  localStorage.removeItem("token");
  window.location.href = "/login";
}

// ============================================================
// Exports
// ============================================================

export {
  backToCollection,
  clearForm,
  deleteRule,
  getFieldLabel,
  getOperatorLabel,
  handleCreateRule,
  initCollectionRules,
  loadRules,
  logout,
  renderRules,
  setupEventDelegation,
  testRule,
  toggleRule,
};

Alpine.data("collectionRules", () => ({
  backToCollection,
  clearForm,
  deleteRule,
  getFieldLabel,
  getOperatorLabel,
  handleCreateRule,
  initCollectionRules,
  loadRules,
  logout,
  renderRules,
  setupEventDelegation,
  testRule,
  toggleRule,
}));
