"use client";

import * as React from "react";
import { CheckCircle2, Loader2 } from "lucide-react";

type FormField = {
  id: string;
  key: string;
  label: string;
  type: string;
  section: string;
  required: boolean;
  sortOrder: number;
  options: unknown;
  placeholder: string | null;
  helpText: string | null;
  isCore: boolean;
};

type SurveyFormProps = {
  formTemplateId: string;
  organizationId: string;
  fields: FormField[];
  branding: { primaryColor?: string; logoUrl?: string } | null;
  prefill: Record<string, string>;
};

export function SurveyForm({
  formTemplateId,
  organizationId,
  fields,
  branding,
  prefill,
}: SurveyFormProps) {
  const [values, setValues] = React.useState<Record<string, string>>(() => {
    const init: Record<string, string> = {};
    for (const field of fields) {
      init[field.key] = prefill[field.key] ?? "";
    }
    init.firstName = prefill.firstName ?? "";
    init.lastName = prefill.lastName ?? "";
    return init;
  });

  const [submitting, setSubmitting] = React.useState(false);
  const [submitted, setSubmitted] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  const primaryColor = branding?.primaryColor || undefined;

  const handleChange = (key: string, value: string) => {
    setValues((prev) => ({ ...prev, [key]: value }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError(null);

    if (!values.firstName?.trim() || !values.lastName?.trim()) {
      setError("First name and last name are required.");
      return;
    }

    setSubmitting(true);
    try {
      const { firstName, lastName, ...rest } = values;
      const res = await fetch("/api/survey/submit", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          formTemplateId,
          organizationId,
          firstName: firstName.trim(),
          lastName: lastName.trim(),
          fieldData: rest,
        }),
      });

      if (!res.ok) {
        const data = await res.json().catch(() => null);
        throw new Error(data?.error || "Submission failed");
      }

      setSubmitted(true);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Something went wrong");
    } finally {
      setSubmitting(false);
    }
  };

  if (submitted) {
    return (
      <div className="glass-card flex flex-col items-center gap-4 rounded-2xl p-10 text-center">
        <div
          className={`flex size-14 items-center justify-center rounded-full ${
            primaryColor ? "" : "bg-green-100 dark:bg-green-900/30"
          }`}
          style={primaryColor ? { backgroundColor: `${primaryColor}20` } : undefined}
        >
          <CheckCircle2
            className={`size-7 ${primaryColor ? "" : "text-green-600 dark:text-green-400"}`}
            style={primaryColor ? { color: primaryColor } : undefined}
          />
        </div>
        <div>
          <h2 className="text-xl font-semibold">Thank you!</h2>
          <p className="mt-1 text-sm text-muted-foreground">
            Your response has been submitted successfully.
          </p>
        </div>
      </div>
    );
  }

  const nonCoreFields = fields.filter(
    (f) => f.key !== "firstName" && f.key !== "lastName"
  );

  return (
    <form onSubmit={handleSubmit} className="glass-card space-y-6 rounded-2xl p-6 sm:p-8">
      <div className="grid gap-4 sm:grid-cols-2">
        <FieldInput
          label="First Name"
          value={values.firstName}
          onChange={(v) => handleChange("firstName", v)}
          required
          placeholder="First name"
          primaryColor={primaryColor}
        />
        <FieldInput
          label="Last Name"
          value={values.lastName}
          onChange={(v) => handleChange("lastName", v)}
          required
          placeholder="Last name"
          primaryColor={primaryColor}
        />
      </div>

      <div className="grid gap-4 sm:grid-cols-2">
        {nonCoreFields.map((field) => (
          <div
            key={field.id}
            className={
              field.type === "textarea" || field.type === "multiline"
                ? "sm:col-span-2"
                : ""
            }
          >
            <FieldRenderer
              field={field}
              value={values[field.key] ?? ""}
              onChange={(v) => handleChange(field.key, v)}
              primaryColor={primaryColor}
            />
          </div>
        ))}
      </div>

      {error && (
        <p className="rounded-lg bg-red-50 px-4 py-2 text-sm text-red-600 dark:bg-red-900/20 dark:text-red-400">
          {error}
        </p>
      )}

      <button
        type="submit"
        disabled={submitting}
        className="flex w-full items-center justify-center gap-2 rounded-xl px-6 py-3 text-sm font-semibold text-white transition-opacity disabled:opacity-50"
        style={{ backgroundColor: primaryColor || "oklch(0.20 0.005 90)" }}
      >
        {submitting && <Loader2 className="size-4 animate-spin" />}
        {submitting ? "Submitting..." : "Submit"}
      </button>
    </form>
  );
}

function FieldInput({
  label,
  value,
  onChange,
  required,
  placeholder,
  type = "text",
  primaryColor,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  required?: boolean;
  placeholder?: string;
  type?: string;
  primaryColor?: string;
}) {
  return (
    <div className="space-y-1.5">
      <label className="block text-sm font-medium text-foreground">
        {label}
        {required && <span className="ml-0.5 text-red-500">*</span>}
      </label>
      <input
        type={type}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        required={required}
        placeholder={placeholder || undefined}
        className="glass-input w-full rounded-lg px-3 py-2 text-sm outline-none transition-shadow focus:ring-2"
        style={primaryColor ? { "--tw-ring-color": primaryColor } as React.CSSProperties : undefined}
      />
    </div>
  );
}

function FieldRenderer({
  field,
  value,
  onChange,
  primaryColor,
}: {
  field: FormField;
  value: string;
  onChange: (v: string) => void;
  primaryColor?: string;
}) {
  const options = Array.isArray(field.options) ? field.options as string[] : [];

  switch (field.type) {
    case "select":
    case "dropdown":
      return (
        <div className="space-y-1.5">
          <label className="block text-sm font-medium text-foreground">
            {field.label}
            {field.required && <span className="ml-0.5 text-red-500">*</span>}
          </label>
          {field.helpText && (
            <p className="text-xs text-muted-foreground">{field.helpText}</p>
          )}
          <select
            value={value}
            onChange={(e) => onChange(e.target.value)}
            required={field.required}
            className="glass-input w-full rounded-lg px-3 py-2 text-sm outline-none transition-shadow focus:ring-2"
            style={primaryColor ? { "--tw-ring-color": primaryColor } as React.CSSProperties : undefined}
          >
            <option value="">{field.placeholder || "Select..."}</option>
            {options.map((opt) => (
              <option key={opt} value={opt}>
                {opt}
              </option>
            ))}
          </select>
        </div>
      );

    case "checkbox":
    case "multi-select":
      return (
        <div className="space-y-1.5">
          <label className="block text-sm font-medium text-foreground">
            {field.label}
            {field.required && <span className="ml-0.5 text-red-500">*</span>}
          </label>
          {field.helpText && (
            <p className="text-xs text-muted-foreground">{field.helpText}</p>
          )}
          <div className="flex flex-wrap gap-2">
            {options.map((opt) => {
              const selected = value
                .split(",")
                .map((s) => s.trim())
                .includes(opt);
              return (
                <button
                  key={opt}
                  type="button"
                  onClick={() => {
                    const current = value
                      ? value.split(",").map((s) => s.trim())
                      : [];
                    const next = selected
                      ? current.filter((v) => v !== opt)
                      : [...current, opt];
                    onChange(next.join(","));
                  }}
                  className={`rounded-lg border px-3 py-1.5 text-sm transition-colors ${
                    selected
                      ? "border-transparent text-white"
                      : "border-border bg-background text-foreground hover:bg-muted"
                  }`}
                  style={
                    selected
                      ? { backgroundColor: primaryColor || "oklch(0.20 0.005 90)" }
                      : undefined
                  }
                >
                  {opt}
                </button>
              );
            })}
          </div>
        </div>
      );

    case "textarea":
    case "multiline":
      return (
        <div className="space-y-1.5">
          <label className="block text-sm font-medium text-foreground">
            {field.label}
            {field.required && <span className="ml-0.5 text-red-500">*</span>}
          </label>
          {field.helpText && (
            <p className="text-xs text-muted-foreground">{field.helpText}</p>
          )}
          <textarea
            value={value}
            onChange={(e) => onChange(e.target.value)}
            required={field.required}
            placeholder={field.placeholder || undefined}
            rows={3}
            className="glass-input w-full rounded-lg px-3 py-2 text-sm outline-none transition-shadow focus:ring-2"
            style={primaryColor ? { "--tw-ring-color": primaryColor } as React.CSSProperties : undefined}
          />
        </div>
      );

    case "boolean":
    case "toggle":
      return (
        <div className="flex items-center gap-3 pt-5">
          <button
            type="button"
            role="switch"
            aria-checked={value === "true"}
            onClick={() => onChange(value === "true" ? "false" : "true")}
            className={`relative h-6 w-11 shrink-0 rounded-full transition-colors ${
              value === "true" ? "" : "bg-muted"
            }`}
            style={
              value === "true"
                ? { backgroundColor: primaryColor || "oklch(0.20 0.005 90)" }
                : undefined
            }
          >
            <span
              className={`absolute left-0.5 top-0.5 size-5 rounded-full bg-white shadow-sm transition-transform ${
                value === "true" ? "translate-x-5" : "translate-x-0"
              }`}
            />
          </button>
          <label className="text-sm font-medium text-foreground">
            {field.label}
          </label>
        </div>
      );

    default:
      return (
        <FieldInput
          label={field.label}
          value={value}
          onChange={onChange}
          required={field.required}
          placeholder={field.placeholder || undefined}
          type={field.type === "email" ? "email" : field.type === "phone" || field.type === "tel" ? "tel" : "text"}
          primaryColor={primaryColor}
        />
      );
  }
}
