"use client";

import { useState } from "react";
import { Input } from "@/components/ui/Input";
import { Select } from "@/components/ui/Select";
import { Toggle } from "@/components/ui/Toggle";
import { Field, Label } from "@/components/ui/Card";
import { Button } from "@/components/ui/Button";
import { Plus, Trash2 } from "lucide-react";
import type { BuilderQuestion } from "@/types/builder";
import type { QuestionOptionsConfig, QuestionValidationConfig } from "@/types";

interface QuestionSettingsPanelProps {
  question: BuilderQuestion | null;
  allQuestions: BuilderQuestion[];
  onUpdate: (patch: Partial<{
    title: string;
    isRequired: boolean;
    randomizeOptions: boolean;
    optionsConfig: QuestionOptionsConfig | null;
    validationConfig: QuestionValidationConfig | null;
  }>) => void;
  onLogicUpdate: (logic: {
    conditionType: "equals" | "not_equals" | "any_answer";
    conditionValue: string | null;
    action: "skip_to_question" | "end_survey";
    targetQuestionId: string | null;
  }) => void;
  className?: string;
}

export function QuestionSettingsPanel({
  question,
  allQuestions,
  onUpdate,
  onLogicUpdate,
  className,
}: QuestionSettingsPanelProps) {
  if (!question) {
    return (
      <div className={className}>
        <p className="px-3.5 py-10 text-center text-[13px] leading-relaxed text-muted">
          Select a question on the canvas to edit its settings, validation, and
          branching logic.
        </p>
      </div>
    );
  }

  const q = question;
  const rule = q.logicRules[0];
  const choices = q.optionsConfig?.choices ?? [];
  const hasChoices =
    q.type === "multiple_choice" ||
    q.type === "checkbox" ||
    q.type === "dropdown";
  const rows = q.optionsConfig?.rows ?? [];
  const columns = q.optionsConfig?.columns ?? [];
  const minRating = q.optionsConfig?.minRating ?? 1;
  const maxRating = q.optionsConfig?.maxRating ?? 5;

  const laterQuestions = allQuestions
    .filter((item) => item.position > q.position)
    .sort((a, b) => a.position - b.position);
  const nextQuestion = laterQuestions[0] ?? null;
  const jumpTargets = laterQuestions.filter((item) => item.id !== nextQuestion?.id);
  const skipTargetId = rule?.targetQuestionId ?? "";
  const skipIsNoOp =
    Boolean(skipTargetId) && skipTargetId === nextQuestion?.id;
  const skipSelectValue = skipIsNoOp ? "" : skipTargetId;
  const skippedCount =
    skipSelectValue && !skipIsNoOp
      ? laterQuestions.findIndex((item) => item.id === skipSelectValue)
      : 0;

  function updateChoice(index: number, value: string) {
    const next = [...choices];
    next[index] = value;
    onUpdate({ optionsConfig: { ...q.optionsConfig, choices: next } });
  }

  function addChoice() {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        choices: [...choices, `Option ${String.fromCharCode(65 + choices.length)}`],
      },
    });
  }

  function removeChoice(index: number) {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        choices: choices.filter((_, i) => i !== index),
      },
    });
  }

  function updateRow(index: number, value: string) {
    const next = [...rows];
    next[index] = value;
    onUpdate({ optionsConfig: { ...q.optionsConfig, rows: next } });
  }

  function addRow() {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        rows: [...rows, `Statement ${rows.length + 1}`],
      },
    });
  }

  function removeRow(index: number) {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        rows: rows.filter((_, i) => i !== index),
      },
    });
  }

  function updateColumn(index: number, value: string) {
    const next = [...columns];
    next[index] = value;
    onUpdate({ optionsConfig: { ...q.optionsConfig, columns: next } });
  }

  function addColumn() {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        columns: [...columns, `Option ${columns.length + 1}`],
      },
    });
  }

  function removeColumn(index: number) {
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        columns: columns.filter((_, i) => i !== index),
      },
    });
  }

  // Update while typing without clamping — clamping mid-keystroke makes it
  // impossible to type multi-digit numbers (e.g. clearing "5" to type "10"
  // would otherwise snap back on every intermediate digit).
  function updateRatingMin(next: number) {
    onUpdate({
      optionsConfig: { ...q.optionsConfig, minRating: Number.isFinite(next) ? next : 0 },
    });
  }

  function updateRatingMax(next: number) {
    onUpdate({
      optionsConfig: { ...q.optionsConfig, maxRating: Number.isFinite(next) ? next : 1 },
    });
  }

  // Only normalize an invalid range (min >= max) once the user leaves the field.
  function normalizeRatingScale() {
    if (minRating < maxRating) return;
    onUpdate({
      optionsConfig: {
        ...q.optionsConfig,
        minRating,
        maxRating: minRating + 1,
      },
    });
  }

  return (
    <div className={`bg-white p-[18px] ${className ?? ""}`}>
      <div className="mb-2 text-[11px] font-bold uppercase tracking-wide text-muted">
        Question settings
      </div>

      <Field>
        <Label htmlFor="q-title">Question text</Label>
        <Input
          id="q-title"
          value={q.title}
          onChange={(e) => onUpdate({ title: e.target.value })}
        />
      </Field>

      <div className="flex items-center justify-between border-b border-[#F1F5F9] py-2.5 text-[13px] font-semibold">
        <span>Required</span>
        <Toggle
          checked={q.isRequired}
          onChange={(v) => onUpdate({ isRequired: v })}
        />
      </div>

      {hasChoices && (
        <>
          <div className="flex items-center justify-between border-b border-[#F1F5F9] py-2.5 text-[13px] font-semibold">
            <span>Randomize options</span>
            <Toggle
              checked={q.randomizeOptions}
              onChange={(v) => onUpdate({ randomizeOptions: v })}
            />
          </div>

          {q.type === "dropdown" && (
            <div className="mb-1 mt-4">
              <div className="mb-2 text-[11px] font-bold uppercase tracking-wide text-muted">
                Selection
              </div>
              <div className="grid grid-cols-2 gap-1.5 rounded-[10px] bg-[#F1F5F9] p-1">
                <button
                  type="button"
                  onClick={() =>
                    onUpdate({
                      optionsConfig: { ...q.optionsConfig, allowMultiple: false },
                    })
                  }
                  className={`rounded-[8px] px-2 py-2 text-center text-[12px] font-semibold leading-tight ${
                    !q.optionsConfig?.allowMultiple
                      ? "bg-white text-primary shadow"
                      : "text-muted hover:text-navy"
                  }`}
                >
                  Single
                  <span className="mt-0.5 block text-[10px] font-medium opacity-70">
                    Pick one
                  </span>
                </button>
                <button
                  type="button"
                  onClick={() =>
                    onUpdate({
                      optionsConfig: { ...q.optionsConfig, allowMultiple: true },
                    })
                  }
                  className={`rounded-[8px] px-2 py-2 text-center text-[12px] font-semibold leading-tight ${
                    q.optionsConfig?.allowMultiple
                      ? "bg-white text-primary shadow"
                      : "text-muted hover:text-navy"
                  }`}
                >
                  Multi
                  <span className="mt-0.5 block text-[10px] font-medium opacity-70">
                    Pick several
                  </span>
                </button>
              </div>
            </div>
          )}

          <div className="mb-2 mt-4 text-[11px] font-bold uppercase tracking-wide text-muted">
            Options
          </div>
          {choices.map((choice, i) => (
            <div key={i} className="mb-2 flex gap-2">
              <Input
                value={choice}
                onChange={(e) => updateChoice(i, e.target.value)}
              />
              <Button
                type="button"
                variant="icon"
                size="row"
                onClick={() => removeChoice(i)}
                disabled={choices.length <= 1}
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </div>
          ))}
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="mb-4 w-full"
            onClick={addChoice}
          >
            <Plus className="mr-1 h-3.5 w-3.5" />
            Add option
          </Button>
        </>
      )}

      {q.type === "rating" && (
        <>
          <div className="mb-2 mt-4 text-[11px] font-bold uppercase tracking-wide text-muted">
            Scale
          </div>
          <div className="mb-4 flex gap-2">
            <Field className="mb-0 flex-1">
              <Label htmlFor="q-min-rating">Min</Label>
              <Input
                id="q-min-rating"
                type="number"
                value={minRating}
                onChange={(e) => updateRatingMin(Number(e.target.value))}
                onBlur={normalizeRatingScale}
              />
            </Field>
            <Field className="mb-0 flex-1">
              <Label htmlFor="q-max-rating">Max</Label>
              <Input
                id="q-max-rating"
                type="number"
                value={maxRating}
                onChange={(e) => updateRatingMax(Number(e.target.value))}
                onBlur={normalizeRatingScale}
              />
            </Field>
          </div>
        </>
      )}

      {q.type === "matrix" && (
        <>
          <div className="mb-2 mt-4 text-[11px] font-bold uppercase tracking-wide text-muted">
            Rows (statements)
          </div>
          {rows.map((row, i) => (
            <div key={i} className="mb-2 flex gap-2">
              <Input value={row} onChange={(e) => updateRow(i, e.target.value)} />
              <Button
                type="button"
                variant="icon"
                size="row"
                onClick={() => removeRow(i)}
                disabled={rows.length <= 1}
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </div>
          ))}
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="mb-4 w-full"
            onClick={addRow}
          >
            <Plus className="mr-1 h-3.5 w-3.5" />
            Add row
          </Button>

          <div className="mb-2 mt-2 text-[11px] font-bold uppercase tracking-wide text-muted">
            Columns (scale)
          </div>
          {columns.map((col, i) => (
            <div key={i} className="mb-2 flex gap-2">
              <Input value={col} onChange={(e) => updateColumn(i, e.target.value)} />
              <Button
                type="button"
                variant="icon"
                size="row"
                onClick={() => removeColumn(i)}
                disabled={columns.length <= 1}
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </div>
          ))}
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="mb-4 w-full"
            onClick={addColumn}
          >
            <Plus className="mr-1 h-3.5 w-3.5" />
            Add column
          </Button>
        </>
      )}

      <div className="mb-2 mt-2 text-[11px] font-bold uppercase tracking-wide text-muted">
        Branching logic
      </div>

      <Field>
        <Label>If answer is…</Label>
        <Select
          value={
            rule?.conditionType === "equals" || rule?.conditionType === "not_equals"
              ? (rule.conditionValue ?? "any_answer")
              : "any_answer"
          }
          onChange={(e) => {
            const val = e.target.value;
            const base = {
              action: rule?.action ?? "skip_to_question",
              targetQuestionId: rule?.targetQuestionId ?? null,
            };
            if (val === "any_answer") {
              onLogicUpdate({
                ...base,
                conditionType: "any_answer",
                conditionValue: null,
              });
            } else {
              onLogicUpdate({
                ...base,
                conditionType: "equals",
                conditionValue: val,
              });
            }
          }}
        >
          <option value="any_answer">Any answer</option>
          {hasChoices &&
            choices.map((c) => (
              <option key={c} value={c}>
                {c}
              </option>
            ))}
          {!hasChoices && q.type === "nps" && (
            <>
              <option value="0-6">Detractor (0–6)</option>
              <option value="7-8">Passive (7–8)</option>
              <option value="9-10">Promoter (9–10)</option>
            </>
          )}
          {!hasChoices &&
            q.type === "rating" &&
            Array.from(
              { length: Math.max(1, maxRating - minRating + 1) },
              (_, i) => minRating + i
            ).map((n) => (
              <option key={n} value={String(n)}>
                {n} star{n === 1 ? "" : "s"}
              </option>
            ))}
        </Select>
      </Field>

      <Field>
        <Label>Then</Label>
        <Select
          value={rule?.action ?? "skip_to_question"}
          onChange={(e) =>
            onLogicUpdate({
              conditionType: rule?.conditionType ?? "any_answer",
              conditionValue:
                rule?.conditionType === "equals" ||
                rule?.conditionType === "not_equals"
                  ? rule?.conditionValue
                  : null,
              action: e.target.value as "skip_to_question" | "end_survey",
              targetQuestionId: rule?.targetQuestionId ?? null,
            })
          }
        >
          <option value="skip_to_question">Go to question</option>
          <option value="end_survey">End survey</option>
        </Select>
      </Field>

      {(rule?.action ?? "skip_to_question") === "skip_to_question" && (
        <Field>
          <Label>Jump to</Label>
          <Select
            value={skipSelectValue}
            onChange={(e) =>
              onLogicUpdate({
                conditionType: rule?.conditionType ?? "any_answer",
                conditionValue: rule?.conditionValue ?? null,
                action: "skip_to_question",
                targetQuestionId: e.target.value || null,
              })
            }
          >
            <option value="">
              Next question
              {nextQuestion ? ` (Q${allQuestions.indexOf(nextQuestion) + 1})` : ""}
            </option>
            {jumpTargets.map((item) => (
              <option key={item.id} value={item.id}>
                Question {allQuestions.indexOf(item) + 1}: {item.title.slice(0, 40)}
              </option>
            ))}
          </Select>
          {skipIsNoOp && (
            <p className="mt-1.5 text-[11.5px] leading-snug text-warning">
              That is already the next question, so nothing is skipped. Pick a
              later question (for example Q3) to jump over the ones in between.
            </p>
          )}
          {skippedCount > 0 && (
            <p className="mt-1.5 text-[11.5px] leading-snug text-muted">
              This answer will skip {skippedCount} question
              {skippedCount === 1 ? "" : "s"} in between.
            </p>
          )}
        </Field>
      )}

      <div className="mb-2 mt-4 text-[11px] font-bold uppercase tracking-wide text-muted">
        Validation
      </div>

      {q.type === "open_text" && (
        <>
          <Field>
            <Label>Response type</Label>
            <Select
              value={q.validationConfig?.responseType ?? "text"}
              onChange={(e) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    responseType: e.target.value as "text" | "number" | "email" | "regex",
                  },
                })
              }
            >
              <option value="text">Text</option>
              <option value="number">Number</option>
              <option value="email">Email</option>
              <option value="regex">Regex pattern</option>
            </Select>
          </Field>
          <Field>
            <Label>Max length</Label>
            <Input
              type="number"
              min={1}
              value={q.validationConfig?.maxLength ?? ""}
              onChange={(e) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    maxLength: e.target.value
                      ? Number(e.target.value)
                      : undefined,
                  },
                })
              }
            />
          </Field>
        </>
      )}

      {(q.type === "checkbox" ||
        (q.type === "dropdown" && q.optionsConfig?.allowMultiple)) && (
        <div className="mb-4 flex gap-2">
          <Field className="mb-0 flex-1">
            <Label htmlFor="q-min-selections">Min selections</Label>
            <Input
              id="q-min-selections"
              type="number"
              min={0}
              placeholder="No minimum"
              value={q.validationConfig?.minSelections ?? ""}
              onChange={(e) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    minSelections: e.target.value
                      ? Number(e.target.value)
                      : undefined,
                  },
                })
              }
            />
          </Field>
          <Field className="mb-0 flex-1">
            <Label htmlFor="q-max-selections">Max selections</Label>
            <Input
              id="q-max-selections"
              type="number"
              min={1}
              placeholder="No maximum"
              value={q.validationConfig?.maxSelections ?? ""}
              onChange={(e) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    maxSelections: e.target.value
                      ? Number(e.target.value)
                      : undefined,
                  },
                })
              }
            />
          </Field>
        </div>
      )}

      {q.type === "file_upload" && (
        <>
          <Field>
            <Label>Max file size (MB)</Label>
            <Input
              type="number"
              min={1}
              value={q.validationConfig?.maxFileSizeMb ?? 10}
              onChange={(e) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    maxFileSizeMb: Number(e.target.value) || 10,
                  },
                })
              }
            />
          </Field>
          <Field>
            <Label>Allowed file types</Label>
            <AllowedFileTypesInput
              key={q.id}
              initialValue={q.validationConfig?.allowedFileTypes ?? []}
              onUpdate={(types) =>
                onUpdate({
                  validationConfig: {
                    ...q.validationConfig,
                    allowedFileTypes: types,
                  },
                })
              }
            />
          </Field>
        </>
      )}
    </div>
  );
}

/**
 * Free-text comma-separated tag input. Keeps its own local buffer so typing
 * a trailing comma (to start the next tag) isn't immediately stripped away
 * by the round-tripped, cleaned value coming back down from parent state.
 * Remounts (via `key={question.id}` from the caller) when switching questions.
 */
function AllowedFileTypesInput({
  initialValue,
  onUpdate,
}: {
  initialValue: string[];
  onUpdate: (types: string[]) => void;
}) {
  const [text, setText] = useState(initialValue.join(", "));

  return (
    <Input
      placeholder="e.g. .pdf, .jpg, .png (leave blank to allow any)"
      value={text}
      onChange={(e) => {
        setText(e.target.value);
        onUpdate(
          e.target.value
            .split(",")
            .map((s) => s.trim())
            .filter(Boolean)
        );
      }}
    />
  );
}
