"use client";

import { useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import type { Voucher } from "@/types/promo-voucher";
import type { TicketType } from "@/types/event";
import { formatDate, formatCurrency } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input } 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 FormState {
  code: string;
  ticket_type_id: string;
  ticket_phase_id: string;
  discount_amount: string;
  quota: string;
  unlimited: boolean;
  start_date: string;
  end_date: string;
  is_active: boolean;
}

const EMPTY_FORM: FormState = {
  code: "",
  ticket_type_id: "",
  ticket_phase_id: "",
  discount_amount: "",
  quota: "",
  unlimited: false,
  start_date: "",
  end_date: "",
  is_active: true,
};

function VoucherFields({
  form,
  setForm,
  ticketTypes,
}: {
  form: FormState;
  setForm: (form: FormState) => void;
  ticketTypes: TicketType[];
}) {
  return (
    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
      <label className="flex flex-col gap-1 text-sm font-medium">
        Voucher Code
        <Input required value={form.code} onChange={(e) => setForm({ ...form, code: e.target.value.toUpperCase() })} />
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Applies to Ticket Type
        <select
          value={form.ticket_type_id}
          onChange={(e) => setForm({ ...form, ticket_type_id: e.target.value, ticket_phase_id: "" })}
          className="h-10 rounded-lg border border-kolabora-neutral-dark/20 px-3 text-sm"
        >
          <option value="">All ticket types</option>
          {ticketTypes.map((tt) => (
            <option key={tt.id} value={tt.id}>
              {tt.name}
            </option>
          ))}
        </select>
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Applies to Phase (optional)
        <select
          value={form.ticket_phase_id}
          disabled={!form.ticket_type_id}
          onChange={(e) => setForm({ ...form, ticket_phase_id: e.target.value })}
          className="h-10 rounded-lg border border-kolabora-neutral-dark/20 px-3 text-sm disabled:opacity-50"
        >
          <option value="">
            {form.ticket_type_id ? "All phases of this type" : "Choose a ticket type first"}
          </option>
          {ticketTypes
            .find((tt) => String(tt.id) === form.ticket_type_id)
            ?.phases?.map((phase) => (
              <option key={phase.id} value={phase.id}>
                {phase.name}
              </option>
            ))}
        </select>
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Discount (Rp)
        <Input
          type="number"
          min={0}
          required
          value={form.discount_amount}
          onChange={(e) => setForm({ ...form, discount_amount: 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 items-center gap-2 text-sm font-medium">
        <input
          type="checkbox"
          checked={form.is_active}
          onChange={(e) => setForm({ ...form, is_active: e.target.checked })}
        />
        Active
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Starts
        <Input
          type="datetime-local"
          required
          value={form.start_date}
          onChange={(e) => setForm({ ...form, start_date: e.target.value })}
        />
      </label>
      <label className="flex flex-col gap-1 text-sm font-medium">
        Ends
        <Input
          type="datetime-local"
          required
          value={form.end_date}
          onChange={(e) => setForm({ ...form, end_date: e.target.value })}
        />
      </label>
    </div>
  );
}

function toPayload(form: FormState) {
  return {
    code: form.code,
    ticket_type_id: form.ticket_type_id ? Number(form.ticket_type_id) : null,
    ticket_phase_id: form.ticket_phase_id ? Number(form.ticket_phase_id) : null,
    discount_amount: Number(form.discount_amount),
    quota: form.unlimited ? null : Number(form.quota),
    start_date: form.start_date ? new Date(form.start_date).toISOString() : null,
    end_date: form.end_date ? new Date(form.end_date).toISOString() : null,
    is_active: form.is_active,
  };
}

export function VoucherManager({
  eventId,
  vouchers,
  ticketTypes,
}: {
  eventId: number;
  vouchers: Voucher[];
  ticketTypes: TicketType[];
}) {
  const router = useRouter();
  const [showCreate, setShowCreate] = useState(false);
  const [createForm, setCreateForm] = useState<FormState>(EMPTY_FORM);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editForm, setEditForm] = useState<FormState>(EMPTY_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();

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

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

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

    if (!res.ok) {
      const message = body?.errors?.code?.[0] ?? body?.message ?? "Failed to create voucher.";
      setError(message);
      toast(message, "error");
      return;
    }

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

  function startEdit(voucher: Voucher) {
    setEditingId(voucher.id);
    setEditForm({
      code: voucher.code,
      ticket_type_id: voucher.ticket_type_id !== null ? String(voucher.ticket_type_id) : "",
      ticket_phase_id: voucher.ticket_phase_id !== null ? String(voucher.ticket_phase_id) : "",
      discount_amount: String(voucher.discount_amount),
      quota: voucher.quota ? String(voucher.quota) : "",
      unlimited: voucher.quota === null,
      start_date: toDatetimeLocal(voucher.start_date),
      end_date: toDatetimeLocal(voucher.end_date),
      is_active: voucher.is_active,
    });
  }

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

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

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

    if (!res.ok) {
      const message = body?.errors?.code?.[0] ?? body?.message ?? "Failed to update voucher.";
      setError(message);
      toast(message, "error");
      return;
    }

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

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

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

    if (!res.ok) {
      const message = body?.message ?? "Failed to delete voucher.";
      setError(message);
      toast(message, "error");
      return;
    }
    toast("Voucher 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())}>
        {vouchers.length === 0 && (
          <p className="px-4 py-6 text-center text-sm text-kolabora-neutral-dark/70">
            No voucher codes yet.
          </p>
        )}
        {vouchers.map((voucher) =>
          editingId === voucher.id ? (
            <form key={voucher.id} onSubmit={(e) => handleUpdate(e, voucher.id)} className="p-4">
              <VoucherFields form={editForm} setForm={setEditForm} ticketTypes={ticketTypes} />
              <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 key={voucher.id} className="flex flex-wrap items-center justify-between gap-4 px-4 py-3">
              <div className="min-w-0">
                <p className="font-mono font-medium">{voucher.code}</p>
                <p className="text-sm text-kolabora-neutral-dark/70">
                  {formatCurrency(voucher.discount_amount)} off &middot;{" "}
                  {voucher.ticket_phase_id !== null
                    ? (() => {
                        const tt = ticketTypes.find((t) => t.phases?.some((p) => p.id === voucher.ticket_phase_id));
                        const phase = tt?.phases?.find((p) => p.id === voucher.ticket_phase_id);
                        return tt && phase ? `${tt.name} - ${phase.name}` : "Phase deleted";
                      })()
                    : voucher.ticket_type_id !== null
                      ? (ticketTypes.find((tt) => tt.id === voucher.ticket_type_id)?.name ?? "Ticket type deleted")
                      : "All ticket types"}{" "}
                  &middot; quota {voucher.quota ?? "Unlimited"}
                  {voucher.used !== undefined ? ` (${voucher.used} used)` : ""} &middot;{" "}
                  {voucher.is_active ? "Active" : "Inactive"}
                </p>
                <p className="text-xs text-kolabora-neutral-dark/70">
                  Valid {formatDate(voucher.start_date)} &ndash; {formatDate(voucher.end_date)}
                </p>
              </div>
              <div className="flex shrink-0 gap-2">
                <Button type="button" variant="secondary" size="sm" onClick={() => startEdit(voucher)}>
                  Edit
                </Button>
                <Button
                  type="button"
                  variant="danger"
                  size="sm"
                  onClick={() => handleDelete(voucher.id)}
                  loading={deletingId === voucher.id}
                >
                  Delete
                </Button>
              </div>
            </div>
          ),
        )}
      </div>

      {showCreate ? (
        <form onSubmit={handleCreate} className={cn("mt-4", cardClasses("p-4"))}>
          <VoucherFields form={createForm} setForm={setCreateForm} ticketTypes={ticketTypes} />
          <div className="mt-3 flex gap-2">
            <Button type="submit" loading={isSubmitting}>
              Save Voucher
            </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 Voucher
        </Button>
      )}
    </div>
  );
}
