"use client";

import { useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import type { TicketPhase, TicketType } from "@/types/event";
import { formatCurrency, formatDate } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input, Select } from "@/components/ui/input";
import { useConfirmDialog } from "@/components/ui/confirm-dialog";
import { useToast } from "@/components/ui/toast";
import { cardClasses } from "@/components/ui/styles";
import { cn } from "@/lib/utils";
import { clientFetch } from "@/lib/api/client";

function toDatetimeLocal(value: string | null | undefined) {
  if (!value) return "";
  const date = new Date(value);
  const pad = (n: number) => String(n).padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

interface CategoryFormState {
  name: string;
  /** Package ticket (e.g. "Picnic") — 1 unit purchased needs 2 people's holder data, still 1 QR. */
  is_package: boolean;
}

const EMPTY_CATEGORY_FORM: CategoryFormState = { name: "", is_package: false };

interface PhaseFormState {
  name: string;
  price: string;
  quota: string;
  unlimited: boolean;
  sale_start_date: string;
  sale_end_date: string;
  purchase_limit: string;
  purchase_limit_unset: boolean;
  status: TicketPhase["status"];
}

const EMPTY_PHASE_FORM: PhaseFormState = {
  name: "",
  price: "",
  quota: "",
  unlimited: false,
  sale_start_date: "",
  sale_end_date: "",
  purchase_limit: "3",
  purchase_limit_unset: false,
  status: "available",
};

const PHASE_STATUS_LABEL: Record<TicketPhase["status"], string> = {
  available: "Ready",
  coming_soon: "Coming Soon",
  sold_out: "Sold Out",
  closed: "Closed",
};

const PHASE_STATUS_BADGE_CLASSES: Record<TicketPhase["status"], string> = {
  available: "",
  coming_soon: "bg-yellow-400 text-yellow-950",
  sold_out: "bg-red-600 text-white",
  closed: "bg-kolabora-neutral-dark/40 text-white",
};

function CategoryFields({ form, setForm }: { form: CategoryFormState; setForm: (form: CategoryFormState) => void }) {
  return (
    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
      <label className="flex flex-col gap-1 text-sm font-medium">
        Ticket Type Name (Category)
        <Input
          required
          placeholder="Picnic, Festival, ..."
          value={form.name}
          onChange={(e) => setForm({ ...form, name: e.target.value })}
        />
      </label>
      <label className="flex items-center gap-2 text-sm font-medium">
        <input
          type="checkbox"
          checked={form.is_package}
          onChange={(e) => setForm({ ...form, is_package: e.target.checked })}
        />
        Package ticket (2 people per ticket — 1 QR shared by both)
      </label>
    </div>
  );
}

function PhaseFields({
  form,
  setForm,
  showStatus = false,
}: {
  form: PhaseFormState;
  setForm: (form: PhaseFormState) => void;
  /** Only meaningful when editing an existing phase — new phases always start Ready (backend forces this on create). */
  showStatus?: boolean;
}) {
  return (
    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
      <label className="flex flex-col gap-1 text-sm font-medium">
        Phase Name
        <Input
          required
          placeholder="Early Bird, Presale 1, Regular Sale, ..."
          value={form.name}
          onChange={(e) => setForm({ ...form, name: e.target.value })}
        />
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Price (Rp)
        <Input
          type="number"
          min={0}
          required
          value={form.price}
          onChange={(e) => setForm({ ...form, price: e.target.value })}
        />
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Quota
        <Input
          type="number"
          min={1}
          disabled={form.unlimited}
          value={form.quota}
          onChange={(e) => setForm({ ...form, quota: e.target.value })}
        />
        <label className="mt-1 flex items-center gap-2 text-xs font-normal text-kolabora-neutral-dark/70">
          <input
            type="checkbox"
            checked={form.unlimited}
            onChange={(e) => setForm({ ...form, unlimited: e.target.checked })}
          />
          Unlimited
        </label>
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Max. Purchases/Account
        <Input
          type="number"
          min={1}
          max={3}
          required={!form.purchase_limit_unset}
          disabled={form.purchase_limit_unset}
          value={form.purchase_limit}
          onChange={(e) => setForm({ ...form, purchase_limit: e.target.value })}
        />
        <label className="mt-1 flex items-center gap-2 text-xs font-normal text-kolabora-neutral-dark/70">
          <input
            type="checkbox"
            checked={form.purchase_limit_unset}
            onChange={(e) => setForm({ ...form, purchase_limit_unset: e.target.checked })}
          />
          Not set
        </label>
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Sale Starts
        <Input
          type="datetime-local"
          required
          value={form.sale_start_date}
          onChange={(e) => setForm({ ...form, sale_start_date: e.target.value })}
        />
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Sale Ends
        <Input
          type="datetime-local"
          required
          value={form.sale_end_date}
          onChange={(e) => setForm({ ...form, sale_end_date: e.target.value })}
        />
      </label>
      {showStatus && (
        <label className="flex flex-col gap-1 text-sm font-medium">
          Status
          <Select
            value={form.status}
            onChange={(e) => setForm({ ...form, status: e.target.value as PhaseFormState["status"] })}
          >
            <option value="available">Ready</option>
            <option value="coming_soon">Coming Soon</option>
            <option value="sold_out">Sold Out</option>
          </Select>
        </label>
      )}
    </div>
  );
}

function categoryPayload(form: CategoryFormState) {
  return { name: form.name, people_per_ticket: form.is_package ? 2 : 1 };
}

function phasePayload(form: PhaseFormState) {
  return {
    name: form.name,
    price: Number(form.price),
    quota: form.unlimited ? null : Number(form.quota),
    sale_start_date: form.sale_start_date ? new Date(form.sale_start_date).toISOString() : null,
    sale_end_date: form.sale_end_date ? new Date(form.sale_end_date).toISOString() : null,
    purchase_limit: form.purchase_limit_unset ? null : Number(form.purchase_limit),
    status: form.status,
  };
}

/** Manages one category's phases (Early Bird/Presale/Regular Sale). */
function PhaseManager({ eventId, ticketType }: { eventId: number; ticketType: TicketType }) {
  const router = useRouter();
  const [showCreate, setShowCreate] = useState(false);
  const [createForm, setCreateForm] = useState<PhaseFormState>(EMPTY_PHASE_FORM);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editForm, setEditForm] = useState<PhaseFormState>(EMPTY_PHASE_FORM);
  const [error, setError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [deletingId, setDeletingId] = useState<number | null>(null);
  const { confirm, dialog } = useConfirmDialog();
  const { toast } = useToast();

  const basePath = `/api/admin/events/${eventId}/ticket-types/${ticketType.id}/phases`;

  async function handleCreate(formEvent: FormEvent<HTMLFormElement>) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch(basePath, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(phasePayload(createForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to create phase.";
      setError(message);
      toast(message, "error");
      return;
    }

    setShowCreate(false);
    setCreateForm(EMPTY_PHASE_FORM);
    toast("Phase created successfully.", "success");
    router.refresh();
  }

  function startEdit(phase: TicketPhase) {
    setEditingId(phase.id);
    setEditForm({
      name: phase.name,
      price: String(phase.price),
      quota: phase.quota ? String(phase.quota) : "",
      unlimited: phase.quota === null,
      sale_start_date: toDatetimeLocal(phase.sale_start_date),
      sale_end_date: toDatetimeLocal(phase.sale_end_date),
      purchase_limit: phase.purchase_limit ? String(phase.purchase_limit) : "3",
      purchase_limit_unset: phase.purchase_limit === null,
      status: phase.status,
    });
  }

  async function handleUpdate(formEvent: FormEvent<HTMLFormElement>, phaseId: number) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch(`${basePath}/${phaseId}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(phasePayload(editForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to update phase.";
      setError(message);
      toast(message, "error");
      return;
    }

    setEditingId(null);
    toast("Phase updated successfully.", "success");
    router.refresh();
  }

  async function handleDelete(phaseId: number) {
    if (!(await confirm("Delete this phase?"))) return;

    setError(null);
    setDeletingId(phaseId);
    const res = await clientFetch(`${basePath}/${phaseId}`, { method: "DELETE" });
    setDeletingId(null);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to delete phase (it may already have orders).";
      setError(message);
      toast(message, "error");
      return;
    }
    toast("Phase deleted successfully.", "success");
    router.refresh();
  }

  const phases = ticketType.phases ?? [];

  return (
    <div className="border-t border-kolabora-neutral-dark/10 bg-kolabora-neutral-dark/[0.02] p-4">
      {dialog}
      {error && <p className="mb-3 text-sm text-red-600">{error}</p>}

      <div className={cn("flex flex-col divide-y divide-kolabora-neutral-dark/10", cardClasses("bg-white"))}>
        {phases.length === 0 && (
          <p className="px-4 py-4 text-center text-sm text-kolabora-neutral-dark/70">No sale phases yet.</p>
        )}
        {phases.map((phase) =>
          editingId === phase.id ? (
            <form key={phase.id} onSubmit={(e) => handleUpdate(e, phase.id)} className="p-4">
              <PhaseFields form={editForm} setForm={setEditForm} showStatus />
              <div className="mt-3 flex gap-2">
                <Button type="submit" loading={isSubmitting} size="sm">
                  Save
                </Button>
                <Button
                  type="button"
                  variant="secondary"
                  size="sm"
                  onClick={() => setEditingId(null)}
                  disabled={isSubmitting}
                >
                  Cancel
                </Button>
              </div>
            </form>
          ) : (
            <div key={phase.id} className="flex flex-wrap items-center justify-between gap-4 px-4 py-3">
              <div className="min-w-0">
                <p className="flex items-center gap-2 font-medium">
                  {phase.name}
                  {phase.status !== "available" && (
                    <span
                      className={cn(
                        "rounded-full px-2 py-0.5 text-xs font-medium",
                        PHASE_STATUS_BADGE_CLASSES[phase.status],
                      )}
                    >
                      {PHASE_STATUS_LABEL[phase.status]}
                    </span>
                  )}
                </p>
                <p className="text-sm text-kolabora-neutral-dark/70">
                  {formatCurrency(phase.price)} &middot; quota {phase.quota ?? "Unlimited"} &middot; max{" "}
                  {phase.purchase_limit ?? "Not set"}
                  {phase.purchase_limit !== null && "/account"}
                </p>
                <p className="text-xs text-kolabora-neutral-dark/70">
                  On sale {formatDate(phase.sale_start_date)} &ndash; {formatDate(phase.sale_end_date)}
                </p>
              </div>
              <div className="flex shrink-0 gap-2">
                <Button type="button" variant="secondary" size="sm" onClick={() => startEdit(phase)}>
                  Edit
                </Button>
                <Button
                  type="button"
                  variant="danger"
                  size="sm"
                  onClick={() => handleDelete(phase.id)}
                  loading={deletingId === phase.id}
                >
                  Delete
                </Button>
              </div>
            </div>
          ),
        )}
      </div>

      {showCreate ? (
        <form onSubmit={handleCreate} className={cn("mt-3", cardClasses("bg-white p-4"))}>
          <PhaseFields form={createForm} setForm={setCreateForm} />
          <div className="mt-3 flex gap-2">
            <Button type="submit" loading={isSubmitting} size="sm">
              Save Phase
            </Button>
            <Button
              type="button"
              variant="secondary"
              size="sm"
              onClick={() => setShowCreate(false)}
              disabled={isSubmitting}
            >
              Cancel
            </Button>
          </div>
        </form>
      ) : (
        <Button type="button" size="sm" onClick={() => setShowCreate(true)} className="mt-3">
          + Add Phase
        </Button>
      )}
    </div>
  );
}

export function TicketTypeManager({ eventId, ticketTypes }: { eventId: number; ticketTypes: TicketType[] }) {
  const router = useRouter();
  const [showCreate, setShowCreate] = useState(false);
  const [createForm, setCreateForm] = useState<CategoryFormState>(EMPTY_CATEGORY_FORM);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editForm, setEditForm] = useState<CategoryFormState>(EMPTY_CATEGORY_FORM);
  const [expandedId, setExpandedId] = useState<number | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [deletingId, setDeletingId] = useState<number | null>(null);
  const { confirm, dialog } = useConfirmDialog();
  const { toast } = useToast();

  async function handleCreate(formEvent: FormEvent<HTMLFormElement>) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch(`/api/admin/events/${eventId}/ticket-types`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(categoryPayload(createForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to create ticket type.";
      setError(message);
      toast(message, "error");
      return;
    }

    setShowCreate(false);
    setCreateForm(EMPTY_CATEGORY_FORM);
    toast("Ticket type created successfully.", "success");
    router.refresh();
  }

  function startEdit(tt: TicketType) {
    setEditingId(tt.id);
    setEditForm({ name: tt.name, is_package: tt.people_per_ticket === 2 });
  }

  async function handleUpdate(formEvent: FormEvent<HTMLFormElement>, ticketTypeId: number) {
    formEvent.preventDefault();
    setError(null);
    setIsSubmitting(true);

    const res = await clientFetch(`/api/admin/events/${eventId}/ticket-types/${ticketTypeId}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(categoryPayload(editForm)),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to update ticket type.";
      setError(message);
      toast(message, "error");
      return;
    }

    setEditingId(null);
    toast("Ticket type updated successfully.", "success");
    router.refresh();
  }

  async function handleDelete(ticketTypeId: number) {
    if (!(await confirm("Delete this ticket type? It can only be deleted if it has no phases."))) return;

    setError(null);
    setDeletingId(ticketTypeId);
    const res = await clientFetch(`/api/admin/events/${eventId}/ticket-types/${ticketTypeId}`, {
      method: "DELETE",
    });
    setDeletingId(null);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to delete ticket type.";
      setError(message);
      toast(message, "error");
      return;
    }
    toast("Ticket type deleted successfully.", "success");
    router.refresh();
  }

  return (
    <div>
      {dialog}
      {error && <p className="mb-3 text-sm text-red-600">{error}</p>}

      <div className={cn("flex flex-col divide-y divide-kolabora-neutral-dark/10", cardClasses())}>
        {ticketTypes.length === 0 && (
          <p className="px-4 py-6 text-center text-sm text-kolabora-neutral-dark/70">No ticket types yet.</p>
        )}
        {ticketTypes.map((tt) => (
          <div key={tt.id}>
            {editingId === tt.id ? (
              <form onSubmit={(e) => handleUpdate(e, tt.id)} className="p-4">
                <CategoryFields form={editForm} setForm={setEditForm} />
                <div className="mt-3 flex gap-2">
                  <Button type="submit" loading={isSubmitting}>
                    Save
                  </Button>
                  <Button type="button" variant="secondary" onClick={() => setEditingId(null)} disabled={isSubmitting}>
                    Cancel
                  </Button>
                </div>
              </form>
            ) : (
              <div className="flex flex-wrap items-center justify-between gap-4 px-4 py-3">
                <div className="min-w-0">
                  <p className="font-medium">
                    {tt.name}
                    {tt.people_per_ticket === 2 && (
                      <span className="ml-2 rounded-full bg-kolabora-primary/10 px-2 py-0.5 text-xs font-medium text-kolabora-primary">
                        2-person package
                      </span>
                    )}
                  </p>
                  <p className="text-sm text-kolabora-neutral-dark/70">
                    {tt.phases?.length ?? 0} sale phase{(tt.phases?.length ?? 0) === 1 ? "" : "s"}
                  </p>
                </div>
                <div className="flex shrink-0 gap-2">
                  <Button
                    type="button"
                    variant="secondary"
                    size="sm"
                    onClick={() => setExpandedId(expandedId === tt.id ? null : tt.id)}
                  >
                    {expandedId === tt.id ? "Close Phases" : "Manage Phases"}
                  </Button>
                  <Button type="button" variant="secondary" size="sm" onClick={() => startEdit(tt)}>
                    Edit
                  </Button>
                  <Button
                    type="button"
                    variant="danger"
                    size="sm"
                    onClick={() => handleDelete(tt.id)}
                    loading={deletingId === tt.id}
                  >
                    Delete
                  </Button>
                </div>
              </div>
            )}
            {expandedId === tt.id && <PhaseManager eventId={eventId} ticketType={tt} />}
          </div>
        ))}
      </div>

      {showCreate ? (
        <form onSubmit={handleCreate} className={cn("mt-4", cardClasses("p-4"))}>
          <CategoryFields form={createForm} setForm={setCreateForm} />
          <div className="mt-3 flex gap-2">
            <Button type="submit" loading={isSubmitting}>
              Save Ticket Type
            </Button>
            <Button type="button" variant="secondary" onClick={() => setShowCreate(false)} disabled={isSubmitting}>
              Cancel
            </Button>
          </div>
        </form>
      ) : (
        <Button type="button" onClick={() => setShowCreate(true)} className="mt-4">
          + Add Ticket Type
        </Button>
      )}
    </div>
  );
}
