"use client";

import { useRouter } from "next/navigation";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { toast } from "sonner";

type PlanId = "solo" | "team" | "dedicated";
type Region = "eu-nl" | "eu-de" | "us-east" | "us-west";
type OSImage = "ubuntu-24-04" | "ubuntu-22-04" | "debian-12";
type OwnershipMode = "managed" | "owned";

type Plan = {
  id: PlanId;
  name: string;
  price: string;
  specs: string;
  bestFor: string;
  features: readonly string[];
};

type RegionOpt = { id: Region; label: string };
type OSOpt = { id: OSImage; label: string };

export default function VPSDeployWizard({
  plans,
  regions,
  osImages,
  siteHostname,
}: {
  plans: readonly Plan[];
  regions: readonly RegionOpt[];
  osImages: readonly OSOpt[];
  siteHostname: string;
}) {
  const router = useRouter();
  const [step, setStep] = useState<number>(1);
  const [loading, setLoading] = useState<boolean>(false);

  const [form, setForm] = useState<{
    plan: PlanId | "";
    region: Region | "";
    osImage: OSImage | "";
    hostname: string;
    fqdn: string;
    sshPublicKey: string;
    ownership: OwnershipMode;
    provider: "" | "hetzner" | "digitalocean" | "vultr";
    email: string;
    notes: string;
    acceptTerms: boolean;
    enableBackups: boolean;
  }>({
    plan: "",
    region: "",
    osImage: "ubuntu-24-04",
    hostname: "",
    fqdn: "",
    sshPublicKey: "",
    ownership: "managed",
    provider: "",
    email: "",
    notes: "",
    acceptTerms: false,
    enableBackups: true,
  });

  const set = <K extends keyof typeof form>(key: K, value: (typeof form)[K]) =>
    setForm((f) => ({ ...f, [key]: value }));

  // Preselect plan from hash/query if present
  if (typeof window !== "undefined" && !form.plan) {
    const hash = window.location.hash;
    const url = new URL(window.location.href);
    const qp = url.searchParams.get("plan") as PlanId | null;
    const fromHash = /plan=(solo|team|dedicated)/.exec(hash || "")?.[1] as PlanId | undefined;
    const initial = qp || fromHash;
    if (initial) set("plan", initial);
  }

  const canContinue1 = !!form.plan;
  const canContinue2 = !!form.region && !!form.osImage;
  const canSubmit =
    canContinue2 &&
    !!form.hostname &&
    !!form.email &&
    form.acceptTerms &&
    (form.ownership === "managed" || (form.ownership === "owned" && !!form.provider));

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setLoading(true);

    try {
      const res = await fetch("/api/vps/create", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-secret-token": process.env.NEXT_PUBLIC_FORM_SECRET || "",
        },
        body: JSON.stringify(form),
      });

      if (!res.ok) throw new Error("Provisioning failed");

      toast.success(
        form.ownership === "owned"
          ? "Owned VPS request received! Check your email to securely connect your provider."
          : "VPS provisioning started! Check your email for access details."
      );
      router.push("/vps/success");
    } catch (err) {
      console.error(err);
      toast.error("Something went wrong. Please try again.");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="mt-8 rounded-2xl border border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900 shadow-sm p-6">
      <AnimatePresence mode="wait">
        {step === 1 && (
          <motion.div
            key="vps-step1"
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -20 }}
            transition={{ duration: 0.25 }}
          >
            <h3 className="text-xl font-semibold text-neutral-900 dark:text-white">1) Choose a Plan</h3>
            <p className="mt-1 text-sm text-neutral-600 dark:text-neutral-400">
              You can change plans later. Dedicated is custom—contact us for sizing.
            </p>

            <div className="mt-5 grid gap-4 sm:grid-cols-3">
              {plans.map((p) => (
                <button
                  key={p.id}
                  onClick={() => set("plan", p.id)}
                  className={`text-left rounded-xl border p-4 transition ${
                    form.plan === p.id
                      ? "border-blue-600 bg-blue-50/50 dark:bg-blue-950/30"
                      : "border-neutral-200 dark:border-neutral-800 bg-white/60 dark:bg-neutral-900/60"
                  }`}
                >
                  <div className="flex items-baseline justify-between">
                    <div className="font-semibold">{p.name}</div>
                    <div className="text-sm font-bold">{p.price}</div>
                  </div>
                  <div className="mt-1 text-xs text-neutral-600 dark:text-neutral-400">{p.specs}</div>
                  <div className="mt-1 text-xs text-neutral-500 dark:text-neutral-400">{p.bestFor}</div>
                </button>
              ))}
            </div>

            <div className="mt-6 flex justify-end">
              <button
                disabled={!canContinue1}
                onClick={() => setStep(2)}
                className="rounded-lg bg-gradient-to-r from-blue-600 via-purple-600 to-blue-600 text-white font-medium px-5 py-2 disabled:opacity-50"
              >
                Continue →
              </button>
            </div>
          </motion.div>
        )}

        {step === 2 && (
          <motion.div
            key="vps-step2"
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -20 }}
            transition={{ duration: 0.25 }}
          >
            <h3 className="text-xl font-semibold text-neutral-900 dark:text-white">2) Configure</h3>
            <div className="mt-4 grid gap-4 sm:grid-cols-2">
              {/* Region */}
              <div>
                <label className="block text-sm font-medium mb-1">Region</label>
                <select
                  value={form.region}
                  onChange={(e) => set("region", e.target.value as Region)}
                  className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                >
                  <option value="">Select region</option>
                  {regions.map((r) => (
                    <option key={r.id} value={r.id}>
                      {r.label}
                    </option>
                  ))}
                </select>
              </div>

              {/* OS */}
              <div>
                <label className="block text-sm font-medium mb-1">Operating System</label>
                <select
                  value={form.osImage}
                  onChange={(e) => set("osImage", e.target.value as OSImage)}
                  className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                >
                  {osImages.map((o) => (
                    <option key={o.id} value={o.id}>
                      {o.label}
                    </option>
                  ))}
                </select>
              </div>

              {/* Hostname */}
              <div>
                <label className="block text-sm font-medium mb-1">Hostname</label>
                <input
                  type="text"
                  value={form.hostname}
                  onChange={(e) => set("hostname", e.target.value.replace(/[^a-z0-9-.]/gi, "").toLowerCase())}
                  placeholder="app-1"
                  className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                />
              </div>

              {/* FQDN */}
              <div>
                <label className="block text-sm font-medium mb-1">FQDN (optional)</label>
                <div className="flex items-center gap-2">
                  <input
                    type="text"
                    value={form.fqdn}
                    onChange={(e) => set("fqdn", e.target.value.toLowerCase())}
                    placeholder={`app.${siteHostname}`}
                    className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                  />
                </div>
                <p className="mt-1 text-xs text-neutral-500">
                  We can map a subdomain like <code>app</code>.{siteHostname}.
                </p>
              </div>

              {/* SSH Public Key */}
              <div className="sm:col-span-2">
                <label className="block text-sm font-medium mb-1">SSH Public Key (recommended)</label>
                <textarea
                  value={form.sshPublicKey}
                  onChange={(e) => set("sshPublicKey", e.target.value)}
                  rows={3}
                  placeholder="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5.... your_email@example.com"
                  className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                />
                <label className="mt-2 inline-flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={form.enableBackups}
                    onChange={(e) => set("enableBackups", e.target.checked)}
                    className="h-4 w-4"
                  />
                  Enable backups (recommended)
                </label>
              </div>
            </div>

            <div className="mt-6 flex justify-between">
              <button
                onClick={() => setStep(1)}
                className="text-sm text-neutral-600 dark:text-neutral-400 hover:underline"
              >
                ← Back
              </button>
              <button
                disabled={!canContinue2}
                onClick={() => setStep(3)}
                className="rounded-lg bg-gradient-to-r from-blue-600 via-purple-600 to-blue-600 text-white font-medium px-5 py-2 disabled:opacity-50"
              >
                Continue →
              </button>
            </div>
          </motion.div>
        )}

        {step === 3 && (
          <motion.div
            key="vps-step3"
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -20 }}
            transition={{ duration: 0.25 }}
          >
            <h3 className="text-xl font-semibold text-neutral-900 dark:text-white">3) Ownership & Provision</h3>

            <div className="mt-4 grid gap-4">
              {/* Ownership Mode */}
              <div>
                <label className="block text-sm font-medium mb-1">Management Mode</label>
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                  <button
                    onClick={() => set("ownership", "managed")}
                    type="button"
                    className={`rounded-lg border p-3 text-left ${
                      form.ownership === "managed"
                        ? "border-blue-600 bg-blue-50/50 dark:bg-blue-950/30"
                        : "border-neutral-300 dark:border-neutral-700"
                    }`}
                  >
                    <div className="font-semibold">Managed (default)</div>
                    <div className="text-xs text-neutral-600 dark:text-neutral-400">
                      We host & bill the VPS; you still get access. Backups & monitoring included.
                    </div>
                  </button>

                  <button
                    onClick={() => set("ownership", "owned")}
                    type="button"
                    className={`rounded-lg border p-3 text-left ${
                      form.ownership === "owned"
                        ? "border-blue-600 bg-blue-50/50 dark:bg-blue-950/30"
                        : "border-neutral-300 dark:border-neutral-700"
                    }`}
                  >
                    <div className="font-semibold">Owned (your account)</div>
                    <div className="text-xs text-neutral-600 dark:text-neutral-400">
                      We provision into your cloud account via a secure connect. You keep full ownership.
                    </div>
                  </button>
                </div>
              </div>

              {/* Provider (only for Owned) */}
              {form.ownership === "owned" && (
                <div>
                  <label className="block text-sm font-medium mb-1">Cloud Provider</label>
                  <select
                    value={form.provider}
                    onChange={(e) =>
                      set("provider", e.target.value as "hetzner" | "digitalocean" | "vultr" | "")
                    }
                    className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                  >
                    <option value="">Select provider</option>
                    <option value="hetzner">Hetzner</option>
                    <option value="digitalocean">DigitalOcean</option>
                    <option value="vultr">Vultr</option>
                  </select>
                  <p className="mt-1 text-xs text-neutral-500">
                    After submission, we’ll email a secure link to connect your provider—no API keys here.
                  </p>
                </div>
              )}

              {/* Contact + Notes */}
              <div className="grid gap-4 sm:grid-cols-2">
                <div>
                  <label className="block text-sm font-medium mb-1">Contact Email</label>
                  <input
                    type="email"
                    value={form.email}
                    onChange={(e) => set("email", e.target.value)}
                    placeholder="you@example.com"
                    className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium mb-1">Notes (optional)</label>
                  <input
                    type="text"
                    value={form.notes}
                    onChange={(e) => set("notes", e.target.value)}
                    placeholder="Apps to deploy, access prefs, etc."
                    className="w-full rounded-lg border border-neutral-300 dark:border-neutral-700 bg-white/80 dark:bg-neutral-900/80 px-3 py-2"
                  />
                </div>
              </div>

              <label className="mt-2 inline-flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={form.acceptTerms}
                  onChange={(e) => set("acceptTerms", e.target.checked)}
                  className="h-4 w-4"
                />
                I accept the service terms and understand provisioning involves infrastructure costs.
              </label>
            </div>

            <div className="mt-6 flex justify-between items-center">
              <button
                onClick={() => setStep(2)}
                className="text-sm text-neutral-600 dark:text-neutral-400 hover:underline"
              >
                ← Back
              </button>
              <button
                onClick={handleSubmit}
                disabled={!canSubmit || loading}
                className="rounded-lg bg-gradient-to-r from-blue-600 via-purple-600 to-blue-600 text-white font-medium px-6 py-2 disabled:opacity-50"
              >
                {loading ? "Provisioning..." : "Provision VPS"}
              </button>
            </div>

            <p className="mt-3 text-xs text-neutral-600 dark:text-neutral-400">
              We’ll send access details by email. Managed mode includes monitoring and backups. Owned mode will
              prompt a secure provider connect after submission.
            </p>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
