"use client";

import { useState, type FormEvent } from "react";
import { useSearchParams } from "next/navigation";
import { Check, CreditCard, Globe, Smartphone } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Field, SelectField } from "@/components/shared/field";
import { DetailList, Panel, PreviewNotice } from "@/components/shared/page";
import { PreviewLink } from "@/components/layout/preview-context";
import {
  gatewayFixtures,
  onboardingStepLabels,
  onboardingSteps,
  parseFeatures,
  paymentSetupError,
  websiteSetupError,
  type GatewayAccount,
  type FeatureSet,
} from "./model";
export function OnboardingWizard() {
  const params = useSearchParams();
  const features = parseFeatures(params.get("features"));
  return <Wizard key={features} features={features} />;
}
function Wizard({ features }: { features: FeatureSet }) {
  const steps = onboardingSteps(features);
  const [index, setIndex] = useState(0);
  const [completed, setCompleted] = useState<number[]>([]);
  const [accounts, setAccounts] = useState<GatewayAccount[]>([]);
  const [skipped, setSkipped] = useState(false);
  const [appName, setAppName] = useState("");
  const [websiteName, setWebsiteName] = useState("");
  const [websiteUrl, setWebsiteUrl] = useState("");
  const [error, setError] = useState("");
  const [confirm, setConfirm] = useState(false);
  const [skipConfirm, setSkipConfirm] = useState(false);
  const [finished, setFinished] = useState(false);
  const step = steps[index];
  function validate() {
    if (step === "payment") return paymentSetupError(accounts, skipped);
    if (step === "mobile" && !appName.trim()) return "Enter a mobile app name.";
    if (step === "website") return websiteSetupError(websiteName, websiteUrl);
  }
  function advance(event?: FormEvent<HTMLFormElement>) {
    event?.preventDefault();
    const error = validate();
    setError(error ?? "");
    if (error) return;
    setCompleted([...new Set([...completed, index])]);
    if (index === steps.length - 1) setConfirm(true);
    else setIndex(index + 1);
  }
  function toggleGateway(id: string) {
    setSkipped(false);
    setError("");
    const gateway = gatewayFixtures.find((item) => item.id === id);
    if (!gateway) return;
    setAccounts(
      accounts.some((item) => item.gatewayId === id)
        ? accounts.filter((item) => item.gatewayId !== id)
        : [
            ...accounts,
            {
              gatewayId: id,
              currency: gateway.currency,
              channels: [],
            },
          ],
    );
  }
  function toggleChannel(gatewayId: string, channel: string, checked: boolean) {
    setAccounts(
      accounts.map((account) =>
        account.gatewayId === gatewayId
          ? {
              ...account,
              channels: checked
                ? [...account.channels, channel]
                : account.channels.filter((item) => item !== channel),
            }
          : account,
      ),
    );
    setError("");
  }
  if (finished)
    return (
      <div className="mx-auto max-w-2xl space-y-6 py-12">
        <Panel title="Onboarding preview completed">
          <div className="space-y-6 p-6">
            <span className="inline-flex rounded-full bg-success/10 p-3 text-success">
              <Check size={32} />
            </span>
            <PreviewNotice>
              Your setup was reviewed locally. No gateway account, mobile app,
              website, or organization was provisioned.
            </PreviewNotice>
            <DetailList
              items={{
                "Payment gateways": skipped
                  ? "Skipped"
                  : accounts
                      .map(
                        (account) =>
                          gatewayFixtures.find(
                            (item) => item.id === account.gatewayId,
                          )?.name,
                      )
                      .join(", "),
                "Mobile app": steps.includes("mobile")
                  ? appName
                  : "Not in this feature set",
                Website: steps.includes("website")
                  ? websiteName || websiteUrl
                  : "Not in this feature set",
              }}
            />
            <Button asChild>
              <PreviewLink href="/">Open dashboard preview</PreviewLink>
            </Button>
            <Button
              variant="outline"
              className="ml-3"
              onClick={() => {
                setFinished(false);
                setIndex(0);
              }}
            >
              Review setup again
            </Button>
          </div>
        </Panel>
      </div>
    );
  return (
    <div className="space-y-6">
      <PreviewNotice>
        Onboarding preview · Indonesia · Sample organization. All settings stay
        on this page. No credentials are accepted or transmitted.
      </PreviewNotice>
      <div className="grid items-start gap-7 lg:grid-cols-[300px_minmax(0,1fr)]">
        <aside>
          <h1 className="mb-6 text-2xl font-semibold">Onboarding Setup</h1>
          <ol className="space-y-3">
            {steps.map((value, i) => (
              <li key={value}>
                <button
                  className={`flex w-full items-center gap-3 rounded-xl border p-4 text-left text-sm ${index === i ? "border-primary bg-primary/5" : "bg-card"} disabled:opacity-45`}
                  disabled={i > index}
                  onClick={() => {
                    setIndex(i);
                    setCompleted(completed.filter((item) => item < i));
                    setError("");
                  }}
                  aria-current={index === i ? "step" : undefined}
                >
                  <span
                    className={`flex size-8 shrink-0 items-center justify-center rounded-full ${completed.includes(i) ? "bg-primary text-primary-foreground" : index === i ? "bg-primary/15 text-primary" : "bg-muted text-muted-foreground"}`}
                  >
                    {completed.includes(i) ? <Check size={16} /> : i + 1}
                  </span>
                  {onboardingStepLabels[value]}
                </button>
              </li>
            ))}
          </ol>
          <div className="mt-5 rounded-xl border p-4 text-xs leading-5 text-muted-foreground">
            Optional steps depend on the sample feature set.
            <div className="mt-2 flex flex-wrap gap-x-3 gap-y-1">
              {(["all", "mobile", "website", "none"] as const).map((value) => (
                <PreviewLink
                  key={value}
                  className={
                    features === value
                      ? "font-semibold text-primary"
                      : "underline"
                  }
                  href={"/onboarding?features=" + value}
                >
                  {value === "all"
                    ? "All features"
                    : value === "none"
                      ? "Payment only"
                      : value === "mobile"
                        ? "Mobile only"
                        : "Website only"}
                </PreviewLink>
              ))}
            </div>
          </div>
        </aside>
        <Panel>
          <form onSubmit={advance} noValidate>
            <div className="space-y-6 p-5 sm:p-7">
              <div className="flex items-center gap-3 text-primary">
                {step === "payment" ? (
                  <CreditCard size={24} />
                ) : step === "mobile" ? (
                  <Smartphone size={24} />
                ) : (
                  <Globe size={24} />
                )}
                <h2 className="text-2xl font-semibold text-foreground">
                  {step === "payment"
                    ? "Payment Gateway Setup"
                    : onboardingStepLabels[step]}
                </h2>
              </div>
              {step === "payment" && (
                <>
                  <p className="text-sm leading-6 text-muted-foreground">
                    Select up to two payment gateway accounts and choose the
                    channels your customers can use. The merchant credential is
                    a read-only fixture.
                  </p>
                  {gatewayFixtures.map((gateway) => {
                    const account = accounts.find(
                      (item) => item.gatewayId === gateway.id,
                    );
                    return (
                      <section className="rounded-xl border" key={gateway.id}>
                        <div className="flex items-center justify-between gap-4 p-4">
                          <div>
                            <h3 className="font-semibold">{gateway.name}</h3>
                            <p className="mt-1 text-xs leading-5 text-muted-foreground">
                              {gateway.description}
                            </p>
                          </div>
                          <Button
                            type="button"
                            variant={account ? "outline" : "default"}
                            onClick={() => toggleGateway(gateway.id)}
                          >
                            {account ? "Remove" : "Add Account"}
                          </Button>
                        </div>
                        {account && (
                          <div className="space-y-5 border-t p-4">
                            <div className="grid gap-4 sm:grid-cols-2">
                              <Field
                                label="Merchant secret (preview fixture)"
                                type="password"
                                readOnly
                                value="preview-fixture-only"
                                autoComplete="off"
                              />
                              <SelectField
                                label="Currency"
                                value={account.currency}
                                options={[
                                  "IDR",
                                  "MYR",
                                  "PHP",
                                  "THB",
                                  "SGD",
                                  "USD",
                                  "VND",
                                ]}
                                onChange={(event) =>
                                  setAccounts(
                                    accounts.map((item) =>
                                      item.gatewayId === gateway.id
                                        ? {
                                            ...item,
                                            currency: event.target.value,
                                          }
                                        : item,
                                    ),
                                  )
                                }
                              />
                            </div>
                            <fieldset>
                              <legend className="field-label">
                                Payment channels *
                              </legend>
                              <div className="flex flex-wrap gap-3">
                                {gateway.channels.map((channel) => (
                                  <label
                                    className="flex items-center gap-2 rounded-lg border px-3 py-2 text-sm"
                                    key={channel}
                                  >
                                    <input
                                      className="accent-primary"
                                      type="checkbox"
                                      checked={account.channels.includes(
                                        channel,
                                      )}
                                      onChange={(event) =>
                                        toggleChannel(
                                          gateway.id,
                                          channel,
                                          event.target.checked,
                                        )
                                      }
                                    />
                                    {channel}
                                  </label>
                                ))}
                              </div>
                            </fieldset>
                          </div>
                        )}
                      </section>
                    );
                  })}
                  <Button
                    type="button"
                    variant="link"
                    onClick={() => setSkipConfirm(true)}
                  >
                    Skip payment setup for now
                  </Button>
                  {skipped && (
                    <p className="text-sm text-muted-foreground">
                      Payment setup skipped in this preview.
                    </p>
                  )}
                </>
              )}
              {step === "mobile" && (
                <>
                  <p className="text-sm text-muted-foreground">
                    Configure the name displayed in the mobile payment
                    interface.
                  </p>
                  <Field
                    label="Mobile App Name"
                    value={appName}
                    onChange={(event) => setAppName(event.target.value)}
                    placeholder="TIAR Charging"
                    required
                  />
                  <PreviewNotice>
                    SDK integration, app generation, and delivery are outside
                    this preview.
                  </PreviewNotice>
                </>
              )}
              {step === "website" && (
                <>
                  <p className="text-sm text-muted-foreground">
                    Configure your website settings for payment integration.
                  </p>
                  <Field
                    label="Website Name"
                    value={websiteName}
                    onChange={(event) => setWebsiteName(event.target.value)}
                    placeholder="TIAR Charging"
                  />
                  <Field
                    label="Website URL"
                    type="url"
                    value={websiteUrl}
                    onChange={(event) => setWebsiteUrl(event.target.value)}
                    placeholder="https://charging.example"
                  />
                  <p className="text-xs text-muted-foreground">
                    Provide a website name or a valid URL.
                  </p>
                  <PreviewNotice>
                    Domain verification and payment callbacks are not configured
                    in this preview.
                  </PreviewNotice>
                </>
              )}
              {error && (
                <p role="alert" className="text-sm text-destructive">
                  {error}
                </p>
              )}
            </div>
            <div className="flex justify-between gap-3 border-t p-5">
              <Button
                type="button"
                variant="outline"
                disabled={index === 0}
                onClick={() => {
                  setIndex(index - 1);
                  setCompleted(completed.filter((item) => item < index - 1));
                  setError("");
                }}
              >
                Back
              </Button>
              <Button type="submit">
                {index === steps.length - 1 ? "Review Setup" : "Next"}
              </Button>
            </div>
          </form>
        </Panel>
      </div>
      <Dialog open={skipConfirm} onOpenChange={setSkipConfirm}>
        <DialogContent>
          <DialogTitle>Skip payment setup?</DialogTitle>
          <DialogDescription>
            You can explore the remaining configuration steps without a gateway
            account. No real payment settings are affected.
          </DialogDescription>
          <DialogFooter>
            <Button variant="outline" onClick={() => setSkipConfirm(false)}>
              Keep configuring
            </Button>
            <Button
              onClick={() => {
                setAccounts([]);
                setSkipped(true);
                setError("");
                setSkipConfirm(false);
                setCompleted([...new Set([...completed, index])]);
                if (index === steps.length - 1) setConfirm(true);
                else setIndex(index + 1);
              }}
            >
              Skip for now
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <Dialog open={confirm} onOpenChange={setConfirm}>
        <DialogContent>
          <DialogTitle>Confirm Onboarding Setup</DialogTitle>
          <DialogDescription>
            Review these local settings before completing the demonstration.
          </DialogDescription>
          <DetailList
            items={{
              "Payment accounts": skipped
                ? "Skipped"
                : accounts
                    .map(
                      (account) =>
                        `${account.gatewayId}: ${account.channels.join(", ")}`,
                    )
                    .join(" · "),
              "Mobile App": steps.includes("mobile") ? appName : "Not selected",
              Website: steps.includes("website")
                ? websiteName || websiteUrl
                : "Not selected",
            }}
          />
          <PreviewNotice>
            Completing this step does not save settings to a server or provision
            any service.
          </PreviewNotice>
          <DialogFooter>
            <Button variant="outline" onClick={() => setConfirm(false)}>
              Back to setup
            </Button>
            <Button
              onClick={() => {
                setConfirm(false);
                setFinished(true);
              }}
            >
              Complete preview
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
