"use client";

import { Plus, Trash2 } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";

import { FormMappingPicker } from "./form-mapping-picker";

type FormField = {
  id: string;
  label: string;
  type: string;
  required: boolean;
  placeholder?: string;
  helpText?: string;
  options?: { label: string; value: string }[];
  defaultValue?: unknown;
  mappedProperty: string | null;
  validation?: {
    min?: number;
    max?: number;
    pattern?: string;
    maxLength?: number;
  };
  conditionals?: {
    fieldId: string;
    operator: string;
    value: unknown;
    action: string;
  }[];
};

const OPERATORS = ["eq", "neq", "contains", "isEmpty"] as const;
const ACTIONS = ["show", "hide"] as const;

const CHOICE_TYPES = new Set([
  "select",
  "multi_select",
  "radio",
]);

export function FormFieldConfig({
  field,
  allFields,
  workspaceId,
  onChange,
}: {
  field: FormField;
  allFields: FormField[];
  workspaceId: string;
  onChange: (patch: Partial<FormField>) => void;
}) {
  const otherFields = allFields.filter((f) => f.id !== field.id);
  const v = field.validation ?? {};

  const conditionals = field.conditionals ?? [];

  const updateOption = (
    index: number,
    patch: Partial<{ label: string; value: string }>,
  ) => {
    const options = [...(field.options ?? [])];
    const current = options[index] ?? { label: "", value: "" };
    options[index] = { ...current, ...patch };
    onChange({ options });
  };

  const addOption = () => {
    const n = (field.options?.length ?? 0) + 1;
    onChange({
      options: [
        ...(field.options ?? []),
        { label: `Option ${n}`, value: `option_${n}` },
      ],
    });
  };

  const removeOption = (index: number) => {
    const options = [...(field.options ?? [])];
    options.splice(index, 1);
    onChange({ options: options.length ? options : undefined });
  };

  return (
    <div className="flex flex-col gap-4 rounded-lg border bg-card p-4 shadow-sm">
      <div>
        <h3 className="text-sm font-semibold text-foreground">Field settings</h3>
        <p className="text-xs text-muted-foreground">
          {field.label} · {field.type.replaceAll("_", " ")}
        </p>
      </div>

      <Separator />

      <div className="space-y-2">
        <label className="text-xs font-medium text-foreground" htmlFor="ff-label">
          Label
        </label>
        <Input
          id="ff-label"
          value={field.label}
          onChange={(e) => onChange({ label: e.target.value })}
        />
      </div>

      <div className="space-y-2">
        <label
          className="text-xs font-medium text-foreground"
          htmlFor="ff-placeholder"
        >
          Placeholder
        </label>
        <Input
          id="ff-placeholder"
          value={field.placeholder ?? ""}
          placeholder="Optional"
          onChange={(e) =>
            onChange({
              placeholder: e.target.value || undefined,
            })
          }
        />
      </div>

      <div className="space-y-2">
        <label
          className="text-xs font-medium text-foreground"
          htmlFor="ff-help"
        >
          Help text
        </label>
        <textarea
          id="ff-help"
          value={field.helpText ?? ""}
          placeholder="Shown below the field"
          rows={3}
          onChange={(e) =>
            onChange({
              helpText: e.target.value || undefined,
            })
          }
          className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
        />
      </div>

      <label className="flex cursor-pointer items-center gap-2 text-sm">
        <input
          type="checkbox"
          checked={field.required}
          onChange={(e) => onChange({ required: e.target.checked })}
          className="size-4 rounded border-input accent-primary"
        />
        Required
      </label>

      <Separator />

      <div className="space-y-2">
        <span className="text-xs font-medium text-foreground">Validation</span>
        <div className="grid grid-cols-2 gap-2">
          <Input
            type="number"
            placeholder="Min"
            value={v.min ?? ""}
            onChange={(e) =>
              onChange({
                validation: {
                  ...v,
                  min:
                    e.target.value === ""
                      ? undefined
                      : Number(e.target.value),
                },
              })
            }
          />
          <Input
            type="number"
            placeholder="Max"
            value={v.max ?? ""}
            onChange={(e) =>
              onChange({
                validation: {
                  ...v,
                  max:
                    e.target.value === ""
                      ? undefined
                      : Number(e.target.value),
                },
              })
            }
          />
        </div>
        <Input
          placeholder="Pattern (regex)"
          value={v.pattern ?? ""}
          onChange={(e) =>
            onChange({
              validation: {
                ...v,
                pattern: e.target.value || undefined,
              },
            })
          }
        />
        <Input
          type="number"
          placeholder="Max length"
          value={v.maxLength ?? ""}
          onChange={(e) =>
            onChange({
              validation: {
                ...v,
                maxLength:
                  e.target.value === ""
                    ? undefined
                    : Number(e.target.value),
              },
            })
          }
        />
      </div>

      {CHOICE_TYPES.has(field.type) ? (
        <>
          <Separator />
          <div className="space-y-2">
            <span className="text-xs font-medium text-foreground">Options</span>
            <div className="flex flex-col gap-2">
              {(field.options ?? []).map((opt, i) => (
                <div key={i} className="flex gap-2">
                  <Input
                    placeholder="Label"
                    value={opt.label}
                    onChange={(e) => updateOption(i, { label: e.target.value })}
                  />
                  <Input
                    placeholder="Value"
                    value={opt.value}
                    onChange={(e) => updateOption(i, { value: e.target.value })}
                  />
                  <Button
                    type="button"
                    size="icon"
                    variant="ghost"
                    className="shrink-0"
                    onClick={() => removeOption(i)}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </div>
              ))}
            </div>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="w-full gap-1"
              onClick={addOption}
            >
              <Plus className="size-4" />
              Add option
            </Button>
          </div>
        </>
      ) : null}

      <Separator />

      <div className="space-y-2">
        <span className="text-xs font-medium text-foreground">
          Map to task property
        </span>
        <FormMappingPicker
          workspaceId={workspaceId}
          value={field.mappedProperty}
          onChange={(next) => onChange({ mappedProperty: next })}
        />
      </div>

      <Separator />

      <div className="space-y-3">
        <div className="flex items-center justify-between gap-2">
          <span className="text-xs font-medium text-foreground">
            Conditional rules
          </span>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="h-7 gap-1 text-xs"
            onClick={() =>
              onChange({
                conditionals: [
                  ...conditionals,
                  {
                    fieldId: otherFields[0]?.id ?? "",
                    operator: "eq",
                    value: "",
                    action: "show",
                  },
                ],
              })
            }
          >
            <Plus className="size-3.5" />
            Add rule
          </Button>
        </div>
        {conditionals.length === 0 ? (
          <p className="text-xs text-muted-foreground">
            No rules. Show or hide this field based on another field&apos;s value.
          </p>
        ) : (
          <ul className="flex flex-col gap-3">
            {conditionals.map((rule, index) => (
              <li
                key={index}
                className="space-y-2 rounded-md border border-border p-2"
              >
                <div className="flex justify-end">
                  <Button
                    type="button"
                    size="icon"
                    variant="ghost"
                    className="size-7"
                    onClick={() => {
                      const next = conditionals.filter((_, i) => i !== index);
                      onChange({
                        conditionals: next.length ? next : undefined,
                      });
                    }}
                  >
                    <Trash2 className="size-3.5" />
                  </Button>
                </div>
                <select
                  className="flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm"
                  value={rule.fieldId}
                  onChange={(e) => {
                    const next = [...conditionals];
                    next[index] = { ...rule, fieldId: e.target.value };
                    onChange({ conditionals: next });
                  }}
                >
                  <option value="">Select field</option>
                  {otherFields.map((f) => (
                    <option key={f.id} value={f.id}>
                      {f.label}
                    </option>
                  ))}
                </select>
                <select
                  className="flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm"
                  value={rule.operator}
                  onChange={(e) => {
                    const next = [...conditionals];
                    next[index] = { ...rule, operator: e.target.value };
                    onChange({ conditionals: next });
                  }}
                >
                  {OPERATORS.map((op) => (
                    <option key={op} value={op}>
                      {op}
                    </option>
                  ))}
                </select>
                <Input
                  placeholder="Value"
                  value={
                    rule.value === undefined || rule.value === null
                      ? ""
                      : String(rule.value)
                  }
                  disabled={rule.operator === "isEmpty"}
                  onChange={(e) => {
                    const next = [...conditionals];
                    next[index] = { ...rule, value: e.target.value };
                    onChange({ conditionals: next });
                  }}
                />
                <select
                  className="flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm"
                  value={rule.action}
                  onChange={(e) => {
                    const next = [...conditionals];
                    next[index] = { ...rule, action: e.target.value };
                    onChange({ conditionals: next });
                  }}
                >
                  {ACTIONS.map((a) => (
                    <option key={a} value={a}>
                      {a}
                    </option>
                  ))}
                </select>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}
