"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Plus, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { Select } from "@/components/ui/Select";
import { Toggle } from "@/components/ui/Toggle";
import { Card, CardHeader, CardTitle, Field, Label } from "@/components/ui/Card";
import {
  createDomesticQuestion,
  saveDomesticQuestionContent,
} from "@/lib/actions/admin-domestic";
import { DOMESTIC_TYPE_LABELS, isChoiceType } from "@/lib/domestic/rules";
import {
  DOMESTIC_QUESTION_TYPES,
  DOMESTIC_SENSITIVITIES,
} from "@/lib/validation/domestic";
import { swalToast } from "@/lib/utils/swal";
import type { DomesticQuestionType, DomesticSensitivity } from "@/types/participant";
import {
  contentValuesFrom,
  type DomesticContentValues,
} from "@/lib/domestic/content-values";
import type { DomesticQuestionStatus } from "@/types/participant";

function toPayload(v: DomesticContentValues) {
  const num = (s: string) => (s.trim() === "" ? null : Number(s));
  return {
    type: v.type,
    prompt: v.prompt,
    helpText: v.helpText,
    purpose: v.purpose,
    options: isChoiceType(v.type)
      ? v.options.filter((o) => o.label.trim())
      : undefined,
    min: v.type === "rating" || v.type === "number" ? num(v.min) : null,
    max: v.type === "rating" || v.type === "number" ? num(v.max) : null,
    minLabel: v.type === "rating" ? v.minLabel : undefined,
    maxLabel: v.type === "rating" ? v.maxLabel : undefined,
  };
}

interface CreateProps {
  mode: "create";
  categories: Array<{ id: string; name: string }>;
}

interface EditProps {
  mode: "edit";
  questionId: string;
  initial: DomesticContentValues;
  published: boolean;
  versionNumber: number;
  disabled?: boolean;
  statusLabel?: DomesticQuestionStatus;
}

export function DomesticQuestionForm(props: CreateProps | EditProps) {
  const router = useRouter();
  const [values, setValues] = useState<DomesticContentValues>(
    props.mode === "edit" ? props.initial : contentValuesFrom(null)
  );
  const [code, setCode] = useState("");
  const [categoryId, setCategoryId] = useState(
    props.mode === "create" ? (props.categories[0]?.id ?? "") : ""
  );
  const [sensitivity, setSensitivity] = useState<DomesticSensitivity>("standard");
  const [isEntry, setIsEntry] = useState(true);
  const [rotationWeight, setRotationWeight] = useState("100");
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const set = <K extends keyof DomesticContentValues>(
    key: K,
    value: DomesticContentValues[K]
  ) => setValues((prev) => ({ ...prev, [key]: value }));

  function updateOption(i: number, label: string) {
    set(
      "options",
      values.options.map((o, idx) => (idx === i ? { ...o, label } : o))
    );
  }

  async function handleSubmit() {
    setSaving(true);
    setError(null);

    if (props.mode === "create") {
      const result = await createDomesticQuestion({
        code: code.trim() || undefined,
        meta: {
          categoryId,
          sensitivity,
          isEntry,
          rotationWeight: Number(rotationWeight) || 0,
        },
        content: toPayload(values),
      });
      if (!result.success) {
        setError(result.error);
        setSaving(false);
        return;
      }
      const newId = result.data?.id;
      if (!newId) {
        setError("Question was created but the id was missing");
        setSaving(false);
        return;
      }
      router.push(`/admin/domestic/questions/${newId}`);
      return;
    }

    const result = await saveDomesticQuestionContent(
      props.questionId,
      toPayload(values)
    );
    setSaving(false);
    if (!result.success) {
      setError(result.error);
      return;
    }
    void swalToast.fire({
      icon: "success",
      title: result.data?.newVersion
        ? `Saved as version ${result.data.versionNumber}`
        : "Saved",
    });
    router.refresh();
  }

  const disabled = props.mode === "edit" && props.disabled;

  return (
    <Card>
      <CardHeader>
        <CardTitle>
          {props.mode === "create" ? "New domestic question" : "Question content"}
        </CardTitle>
        {props.mode === "edit" && (
          <span className="text-[11.5px] font-semibold text-muted">
            {props.statusLabel && (
              <span className="mr-2 capitalize">{props.statusLabel}</span>
            )}
            {props.versionNumber > 0 ? `v${props.versionNumber}` : "No version yet"}
            {props.published
              ? " · published (edits create a new version)"
              : " · unpublished (edits update this version)"}
          </span>
        )}
      </CardHeader>

      <div className="p-5">
        {props.mode === "create" && (
          <div className="grid grid-cols-1 gap-x-4 sm:grid-cols-2">
            <Field>
              <Label htmlFor="code">Code (optional)</Label>
              <Input
                id="code"
                placeholder="Auto, e.g. DOM-0180"
                value={code}
                onChange={(e) => setCode(e.target.value)}
              />
            </Field>
            <Field>
              <Label htmlFor="categoryId">Category</Label>
              <Select
                id="categoryId"
                value={categoryId}
                onChange={(e) => setCategoryId(e.target.value)}
              >
                {props.categories.length === 0 && (
                  <option value="">Create a category first</option>
                )}
                {props.categories.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.name}
                  </option>
                ))}
              </Select>
            </Field>
            <Field>
              <Label htmlFor="sensitivity">Sensitivity</Label>
              <Select
                id="sensitivity"
                value={sensitivity}
                onChange={(e) => setSensitivity(e.target.value as DomesticSensitivity)}
              >
                {DOMESTIC_SENSITIVITIES.map((s) => (
                  <option key={s} value={s}>
                    {s[0].toUpperCase() + s.slice(1)}
                  </option>
                ))}
              </Select>
            </Field>
            <Field>
              <Label htmlFor="rotationWeight">Rotation priority (0–1000)</Label>
              <Input
                id="rotationWeight"
                type="number"
                min={0}
                max={1000}
                value={rotationWeight}
                onChange={(e) => setRotationWeight(e.target.value)}
              />
            </Field>
            <div className="mb-4 flex items-center justify-between gap-3 rounded-sm border border-border px-3 py-2.5 sm:col-span-2">
              <div>
                <div className="text-[13px] font-semibold">Entry question</div>
                <div className="text-[12px] text-muted">
                  On: can appear in anyone&apos;s feed. Off: only reachable through
                  a branch rule (follow-up question).
                </div>
              </div>
              <Toggle checked={isEntry} onChange={setIsEntry} />
            </div>
          </div>
        )}

        <Field>
          <Label htmlFor="type">Answer type</Label>
          <Select
            id="type"
            value={values.type}
            disabled={disabled}
            onChange={(e) => set("type", e.target.value as DomesticQuestionType)}
          >
            {DOMESTIC_QUESTION_TYPES.map((t) => (
              <option key={t} value={t}>
                {DOMESTIC_TYPE_LABELS[t]}
              </option>
            ))}
          </Select>
        </Field>

        <Field>
          <Label htmlFor="prompt">Question</Label>
          <Input
            id="prompt"
            placeholder="e.g. Do you own a car?"
            value={values.prompt}
            disabled={disabled}
            onChange={(e) => set("prompt", e.target.value)}
          />
        </Field>

        <Field>
          <Label htmlFor="helpText">Help text (optional)</Label>
          <Input
            id="helpText"
            value={values.helpText}
            disabled={disabled}
            onChange={(e) => set("helpText", e.target.value)}
          />
        </Field>

        {isChoiceType(values.type) && (
          <Field>
            <Label>Options</Label>
            <div className="space-y-2">
              {values.options.map((o, i) => (
                <div key={i} className="flex items-center gap-2">
                  <Input
                    placeholder={`Option ${i + 1}`}
                    value={o.label}
                    disabled={disabled}
                    onChange={(e) => updateOption(i, e.target.value)}
                  />
                  {o.value && (
                    <span className="hidden shrink-0 font-mono text-[11px] text-muted sm:inline">
                      {o.value}
                    </span>
                  )}
                  <Button
                    type="button"
                    variant="icon"
                    size="icon"
                    disabled={disabled || values.options.length <= 2}
                    onClick={() =>
                      set(
                        "options",
                        values.options.filter((_, idx) => idx !== i)
                      )
                    }
                    aria-label="Remove option"
                  >
                    <Trash2 className="h-3.5 w-3.5" />
                  </Button>
                </div>
              ))}
              <Button
                type="button"
                variant="outline"
                size="sm"
                disabled={disabled || values.options.length >= 30}
                onClick={() => set("options", [...values.options, { label: "" }])}
              >
                <Plus className="h-3.5 w-3.5" />
                Add option
              </Button>
            </div>
          </Field>
        )}

        {(values.type === "rating" || values.type === "number") && (
          <div className="grid grid-cols-2 gap-x-4">
            <Field>
              <Label htmlFor="min">Minimum</Label>
              <Input
                id="min"
                type="number"
                placeholder={values.type === "rating" ? "1" : "None"}
                value={values.min}
                disabled={disabled}
                onChange={(e) => set("min", e.target.value)}
              />
            </Field>
            <Field>
              <Label htmlFor="max">Maximum</Label>
              <Input
                id="max"
                type="number"
                placeholder={values.type === "rating" ? "5" : "None"}
                value={values.max}
                disabled={disabled}
                onChange={(e) => set("max", e.target.value)}
              />
            </Field>
            {values.type === "rating" && (
              <>
                <Field>
                  <Label htmlFor="minLabel">Low label</Label>
                  <Input
                    id="minLabel"
                    placeholder="e.g. Not at all"
                    value={values.minLabel}
                    disabled={disabled}
                    onChange={(e) => set("minLabel", e.target.value)}
                  />
                </Field>
                <Field>
                  <Label htmlFor="maxLabel">High label</Label>
                  <Input
                    id="maxLabel"
                    placeholder="e.g. Very much"
                    value={values.maxLabel}
                    disabled={disabled}
                    onChange={(e) => set("maxLabel", e.target.value)}
                  />
                </Field>
              </>
            )}
          </div>
        )}

        <Field>
          <Label htmlFor="purpose">Purpose (required for sensitive questions)</Label>
          <Input
            id="purpose"
            placeholder="Why we ask this — shown in audits"
            value={values.purpose}
            disabled={disabled}
            onChange={(e) => set("purpose", e.target.value)}
          />
        </Field>

        {error && <p className="mb-3 text-sm text-danger">{error}</p>}

        <Button
          type="button"
          loading={saving}
          disabled={disabled || (props.mode === "create" && !categoryId)}
          onClick={handleSubmit}
        >
          {props.mode === "create" ? "Create draft" : "Save content"}
        </Button>
      </div>
    </Card>
  );
}
