"use client";

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

type PlanId = "starter" | "pro" | "network";
type Edition = "java" | "bedrock" | "modded";
type ModLoader = "paper" | "spigot" | "velocity" | "forge" | "fabric" | "";
type Region = "eu-nl" | "eu-de" | "us-east" | "us-west";

// ✅ Allow readonly arrays for safe assignment from const literals
type Plan = {
  id: PlanId;
  name: string;
  price: string;
  specs: string;
  typical: string;
  features: readonly string[];
};

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

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

  const [form, setForm] = useState<{
    plan: PlanId | "";
    edition: Edition | "";
    modLoader: ModLoader;
    version: string;
    region: Region | "";
    serverName: string;
    subdomain: string;
    email: string;
    acceptEula: boolean;
    notes: string;
  }>({
    plan: "",
    edition: "",
    modLoader: "",
    version: "latest",
    region: "",
    serverName: "",
    subdomain: "",
    email: "",
    acceptEula: false,
    notes: "",
  });

  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=(starter|pro|network)/.exec(hash || "")?.[1] as PlanId | undefined;
    const initial = qp || fromHash;
    if (initial) set("plan", initial);
  }

  const canContinue1 = !!form.plan;
  const canContinue2 =
    !!form.edition &&
    !!form.region &&
    !!form.version &&
    (form.edition !== "modded" || !!form.modLoader);
  const canSubmit =
    canContinue2 &&
    !!form.serverName &&
    !!form.email &&
    !!form.subdomain &&
    form.acceptEula;

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

    try {
      const res = await fetch("/api/minecraft/create-server", {
        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("Server provisioning started! Check your email for details.");
      router.push("/minecraft/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="mc-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. Network 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.typical}
                  </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="mc-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">
              {/* Edition */}
              <div>
                <label className="block text-sm font-medium mb-1">Edition</label>
                <select
                  value={form.edition}
                  onChange={(e) => set("edition", e.target.value as Edition)}
                  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 one</option>
                  <option value="java">Java (Paper/Spigot)</option>
                  <option value="bedrock">Bedrock (Geyser supported)</option>
                  <option value="modded">Modded (Forge/Fabric)</option>
                </select>
              </div>

              {/* Mod loader */}
              <div>
                <label className="block text-sm font-medium mb-1">Mod Loader</label>
                <select
                  value={form.modLoader}
                  onChange={(e) => set("modLoader", e.target.value as ModLoader)}
                  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"
                  disabled={form.edition === "bedrock"}
                >
                  <option value="">None / Default</option>
                  <option value="paper">Paper</option>
                  <option value="spigot">Spigot</option>
                  <option value="velocity">Velocity (proxy)</option>
                  <option value="forge">Forge</option>
                  <option value="fabric">Fabric</option>
                </select>
                <p className="mt-1 text-xs text-neutral-500">
                  Velocity is recommended for multi-server networks.
                </p>
              </div>

              {/* Version */}
              <div>
                <label className="block text-sm font-medium mb-1">Version</label>
                <input
                  type="text"
                  value={form.version}
                  onChange={(e) => set("version", e.target.value)}
                  placeholder="latest or e.g. 1.20.6"
                  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>

              {/* 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>
            </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="mc-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) Details & Provision
            </h3>
            <div className="mt-4 grid gap-4">
              <div className="grid gap-4 sm:grid-cols-2">
                <div>
                  <label className="block text-sm font-medium mb-1">Server Name</label>
                  <input
                    type="text"
                    value={form.serverName}
                    onChange={(e) => set("serverName", e.target.value)}
                    placeholder="My Community Server"
                    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">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>

              <div className="grid gap-4 sm:grid-cols-2">
                <div>
                  <label className="block text-sm font-medium mb-1">Subdomain</label>
                  <div className="flex items-center gap-2">
                    <input
                      type="text"
                      value={form.subdomain}
                      onChange={(e) =>
                        set(
                          "subdomain",
                          e.target.value.replace(/[^a-z0-9-]/gi, "").toLowerCase()
                        )
                      }
                      placeholder="myserver"
                      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"
                    />
                    <span className="text-sm text-neutral-600 dark:text-neutral-400">
                      .{siteHostname}
                    </span>
                  </div>
                  <p className="mt-1 text-xs text-neutral-500">
                    We’ll map this to your server on provision.
                  </p>
                </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="Plugins to preinstall, SFTP user, 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.acceptEula}
                  onChange={(e) => set("acceptEula", e.target.checked)}
                  className="h-4 w-4"
                />
                I accept the{" "}
                <a
                  href="https://www.minecraft.net/en-us/eula"
                  target="_blank"
                  rel="noreferrer"
                  className="underline"
                >
                  Minecraft EULA
                </a>
                .
              </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 Server"}
              </button>
            </div>

            <p className="mt-3 text-xs text-neutral-600 dark:text-neutral-400">
              We’ll send panel access and SFTP credentials to your email. All plans include
              backups and monitoring. Modpacks & networks depend on resources and may
              require custom sizing.
            </p>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
