import { Controller } from "@hotwired/stimulus";
import { loadStripe } from "@stripe/stripe-js";

export default class extends Controller {
  static targets = [
    "key",
    "submit",
    "firstname",
    "lastname",
    "email",
    "phone",
    "ticketType",
    "foodType",
    "note",
    "donation"
  ];

  stripe;

  async connect() {
    this.stripe = await loadStripe(this.keyTarget.textContent);
  }

  addEntry(event) {
    event.preventDefault();

    const template = this.element
      .querySelector(".forms")
      .firstElementChild.cloneNode(true);

    template.querySelectorAll("select, input").forEach((element) => {
      element.value = "";
      if (element.id) {
        element.id = `${element.id}_${Date.now()}`;
      }
    });

    template.querySelectorAll("label").forEach((label) => {
      const forAttribute = label.getAttribute("for");
      if (forAttribute) {
        label.setAttribute("for", `${forAttribute}_${Date.now()}`);
      }
    });

    template.classList.add("opacity-0");
    this.element.querySelector(".forms").appendChild(template);

    requestAnimationFrame(() => {
      template.classList.remove("opacity-0");
      template.classList.add("transition-all", "duration-300");
    });
  }

  removeEntry(event) {
    event.preventDefault();

    const forms = this.element.querySelector(".forms");
    if (forms.childElementCount <= 1) {
      return;
    }

    const ticketElement = event.currentTarget.closest(".bg-white\\/80");
    if (!ticketElement) return;

    ticketElement.classList.add("opacity-0", "transition-all", "duration-300");
    setTimeout(() => {
      ticketElement.remove();
    }, 300);
  }

  submit(event) {
    event.preventDefault();
    if (!this.validateForm()) {
      return;
    }

    this.submitTarget.querySelector("span").classList.add("hidden");
    this.submitTarget.querySelector("svg.arrow").classList.add("hidden");
    this.submitTarget.querySelector("svg.loader").classList.remove("hidden");

    const tickets = this.element.querySelectorAll(".forms > div");
    const personalData = this.getPersonalData();
    const ticketData = this.getTicketData(tickets);

    const formData = {
      personal: personalData,
      tickets: ticketData,
    };

    fetch("/ticket/submit", {
      method: "POST",
      body: JSON.stringify(formData),
      headers: {
        "Content-Type": "application/json",
      },
    }).then((response) => {
      if (!response.ok) {
        this.submitTarget.querySelector("svg.error").classList.add("hidden");
        this.submitTarget
          .querySelector("svg.loader")
          .classList.remove("hidden");
        this.submitTarget.querySelector("span").classList.remove("hidden");
        this.showError(
          "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",
        );
      } else {
        response.json().then((data) => {
          this.stripe.redirectToCheckout({
            sessionId: data.id,
          });
        });
      }
    });
  }

  validateForm() {
    let isValid = true;

    ["firstname", "lastname", "email"].forEach((field) => {
      const target = this[`${field}Target`];
      if (!target.value.trim()) {
        this.showFieldError(target);
        isValid = false;
      }
    });

    this.element.querySelectorAll(".forms > div").forEach((ticket) => {
      const selects = ticket.querySelectorAll("select[required]");
      selects.forEach((select) => {
        if (!select.value) {
          this.showFieldError(select);
          isValid = false;
        }
      });
    });

    return isValid;
  }

  showFieldError(element) {
    element.classList.add(
      "border-red-500",
      "focus:border-red-500",
      "focus:ring-red-200",
    );
    element.addEventListener(
      "input",
      () => {
        element.classList.remove(
          "border-red-500",
          "focus:border-red-500",
          "focus:ring-red-200",
        );
      },
      { once: true },
    );
  }

  showError(message) {
    const errorDiv = document.createElement("div");
    errorDiv.className =
      "fixed top-4 right-4 bg-red-50 border-l-4 border-red-500 p-4 rounded shadow-lg transform transition-all duration-500 opacity-0 translate-x-4";
    errorDiv.innerHTML = `
      <div class="flex items-center">
        <div class="flex-shrink-0">
          <twig:ux:icon name="mdi:alert-circle" class="w-5 h-5 text-red-400" />
        </div>
        <div class="ml-3">
          <p class="text-sm text-red-700">${message}</p>
        </div>
      </div>
    `;

    document.body.appendChild(errorDiv);
    requestAnimationFrame(() => {
      errorDiv.classList.remove("opacity-0", "translate-x-4");
    });

    setTimeout(() => {
      errorDiv.classList.add("opacity-0", "translate-x-4");
      setTimeout(() => errorDiv.remove(), 500);
    }, 5000);
  }

  getTicketData(tickets) {
    return Array.from(tickets).map((ticket) => this.extractTicketData(ticket));
  }

  getPersonalData() {
    return {
      firstname: this.firstnameTarget.value.trim(),
      lastname: this.lastnameTarget.value.trim(),
      email: this.emailTarget.value.trim(),
      phone: this.phoneTarget.value.trim(),
      donation: Number(this.donationTarget.value) ?? null
    };
  }

  extractTicketData(ticket) {
    return {
      ticket: parseInt(ticket.querySelector('select[name="ticket"]').value),
      food: parseInt(ticket.querySelector('select[name="food"]').value),
      note: ticket.querySelector('input[name="note"]').value.trim(),
    };
  }
}
