"use client";

import { useState } from "react";
import type { Block, ButtonBlockProps, FormBlockProps } from "@/features/editor/state/editorStore";
import { NumericPropertyControl } from "@/features/editor/components/NumericPropertyControl";
import { computeFormControllerPublicTokens } from "@/features/editor/utils/formHelpers";
import { useAppLocale } from "@/features/i18n/LocaleProvider";
import { getEditorFormControllerPanelMessages } from "@/features/i18n/messages/editorFormControllerPanel";

interface FormControllerPanelProps {
  block: Block; // type === "form"
  blocks: Block[];
  selectedBlockId: string | null;
  updateBlock: (id: string, partial: any) => void;
}

export function FormControllerPanel({ block, blocks, selectedBlockId, updateBlock }: FormControllerPanelProps) {
  if (!selectedBlockId || block.id !== selectedBlockId) return null;

  const [showSheetsGuide, setShowSheetsGuide] = useState(false);

  const formProps = block.props as FormBlockProps;
  const locale = useAppLocale();
  const m = getEditorFormControllerPanelMessages(locale);

  const sheetsScriptExample = (() => {
    const tokens = computeFormControllerPublicTokens(block, blocks);
    const fieldNames = tokens.fields.map((f) => f.name).filter((name) => !!name);

    if (fieldNames.length === 0) {
      return (
        "function doPost(e) {\n" +
        '  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("시트1");\n' +
        "  if (!sheet) { sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; }\n" +
        "  var params = e.parameter; // x-www-form-urlencoded\n" +
        "  var row = [\n" +
        '    params.name || "",\n' +
        '    params.email || "",\n' +
        '    params.message || "",\n' +
        "    new Date(),\n" +
        "  ];\n" +
        "  sheet.appendRow(row);\n" +
        "  return ContentService\n" +
        "    .createTextOutput(JSON.stringify({ ok: true }))\n" +
        "    .setMimeType(ContentService.MimeType.JSON);\n" +
        "}"
      );
    }

    const headerNames = [...fieldNames, "createdAt"];
    const rowLines = fieldNames.map((name) => `    params.${name} || "",`);
    rowLines.push("    new Date(),");

    const lines: string[] = [];
    lines.push("function doPost(e) {");
    lines.push('  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("시트1");');
    lines.push("  if (!sheet) { sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; }");
    lines.push("  var params = e.parameter; // x-www-form-urlencoded");
    lines.push("  // 시트의 1행 헤더는 다음과 같이 맞춰 주세요:");
    lines.push(`  // ${headerNames.join(", ")}`);
    lines.push("  var row = [");
    for (const line of rowLines) {
      lines.push(line);
    }
    lines.push("  ];");
    lines.push("  sheet.appendRow(row);");
    lines.push("  return ContentService");
    lines.push("    .createTextOutput(JSON.stringify({ ok: true }))");
    lines.push("    .setMimeType(ContentService.MimeType.JSON);");
    lines.push("}");

    return lines.join("\n");
  })();

  return (
    <div className="space-y-4 text-xs">
      <p className="text-slate-400">
        {m.introTextPrefix}
        <code className="font-mono text-[11px]">/api/forms/submit</code>
        {m.introTextSuffix}
      </p>

      <div className="space-y-2">
        <label className="flex flex-col gap-1">
          <span className="text-slate-500 dark:text-slate-400">{m.submitTargetLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            value={formProps.submitTarget ?? "internal"}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                submitTarget: e.target.value as FormBlockProps["submitTarget"],
              } as any)
            }
          >
            <option value="internal">{m.submitTargetOptionInternal}</option>
            <option value="webhook">{m.submitTargetOptionWebhook}</option>
          </select>
        </label>

        {formProps.submitTarget === "webhook" && (
          <div className="space-y-3">
            <label className="flex flex-col gap-1">
              <span className="text-slate-500 dark:text-slate-400">{m.webhookUrlLabel}</span>
              <input
                className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                placeholder={m.webhookUrlPlaceholder}
                value={formProps.destinationUrl ?? ""}
                onChange={(e) =>
                  updateBlock(selectedBlockId, {
                    destinationUrl: e.target.value,
                  } as any)
                }
              />
            </label>
            <label className="flex items-center justify-between gap-2">
              <span className="text-slate-500 dark:text-slate-400">{m.payloadFormatLabel}</span>
              <select
                className="w-40 rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                value={formProps.payloadFormat ?? "form"}
                onChange={(e) =>
                  updateBlock(selectedBlockId, {
                    payloadFormat: e.target.value as any,
                  } as any)
                }
              >
                <option value="form">{m.payloadFormatOptionForm}</option>
                <option value="json">{m.payloadFormatOptionJson}</option>
              </select>
            </label>
            <label className="flex items-center justify-between gap-2">
              <span className="text-slate-500 dark:text-slate-400">{m.httpMethodLabel}</span>
              <select
                className="w-28 rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                value={formProps.method ?? "POST"}
                onChange={(e) =>
                  updateBlock(selectedBlockId, {
                    method: e.target.value as FormBlockProps["method"],
                  } as any)
                }
              >
                <option value="POST">POST</option>
                <option value="GET">GET</option>
              </select>
            </label>
            <label className="flex flex-col gap-1">
              <span className="text-slate-500 dark:text-slate-400">{m.authTokenLabel}</span>
              <input
                className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                placeholder={m.authTokenPlaceholder}
                value={formProps.headers?.Authorization ?? ""}
                onChange={(e) =>
                  updateBlock(selectedBlockId, {
                    headers: {
                      ...(formProps.headers ?? {}),
                      Authorization: e.target.value,
                    },
                  } as any)
                }
              />
            </label>
            <label className="flex flex-col gap-1">
              <span className="text-slate-500 dark:text-slate-400">{m.extraParamsLabel}</span>
              <textarea
                className="w-full h-16 rounded border border-slate-300 bg-white px-2 py-1 text-[11px] font-mono text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                placeholder={m.extraParamsPlaceholder}
                value={Object.entries(formProps.extraParams ?? {})
                  .map(([k, v]) => `${k}=${v}`)
                  .join("\n")}
                onChange={(e) => {
                  const lines = e.target.value.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
                  const next: Record<string, string> = {};
                  for (const line of lines) {
                    const idx = line.indexOf("=");
                    if (idx > 0) {
                      const key = line.slice(0, idx).trim();
                      const value = line.slice(idx + 1).trim();
                      if (key) next[key] = value;
                    }
                  }

                  updateBlock(selectedBlockId, {
                    extraParams: next,
                  } as any);
                }}
              />
            </label>

            <div className="flex justify-end">
              <button
                type="button"
                className="inline-flex items-center gap-1 rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100 dark:hover:bg-slate-800"
                onClick={() => setShowSheetsGuide(true)}
              >
                {m.sheetsGuideButtonLabel}
              </button>
            </div>
          </div>
        )}
      </div>

      <div className="space-y-2 border-t border-slate-800 pt-3 mt-4">
        <h3 className="text-[11px] font-semibold text-slate-800 dark:text-slate-200">{m.layoutSectionTitle}</h3>
        <label className="flex flex-col gap-1 text-xs text-slate-500 dark:text-slate-400">
          <span>{m.formWidthModeLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            value={formProps.formWidthMode ?? "auto"}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                formWidthMode: e.target.value as FormBlockProps["formWidthMode"],
              } as any)
            }
          >
            <option value="auto">{m.formWidthModeOptionAuto}</option>
            <option value="full">{m.formWidthModeOptionFull}</option>
            <option value="fixed">{m.formWidthModeOptionFixed}</option>
          </select>
        </label>

        {(formProps.formWidthMode ?? "auto") === "fixed" && (
          <NumericPropertyControl
            label={m.formFixedWidthLabel}
            unitLabel="(px)"
            value={typeof formProps.formWidthPx === "number" ? formProps.formWidthPx : 480}
            min={160}
            max={1200}
            step={10}
            presets={[
              { id: "sm", label: m.formFixedWidthPresetNarrow, value: 320 },
              { id: "md", label: m.formFixedWidthPresetNormal, value: 480 },
              { id: "lg", label: m.formFixedWidthPresetWide, value: 640 },
            ]}
            onChangeValue={(v) =>
              updateBlock(selectedBlockId, {
                formWidthPx: v,
              } as any)
            }
          />
        )}

        <NumericPropertyControl
          label={m.marginYLabel}
          unitLabel="(px)"
          value={typeof formProps.marginYPx === "number" ? formProps.marginYPx : 24}
          min={0}
          max={160}
          step={4}
          presets={[
            { id: "none", label: m.marginYPresetNone, value: 0 },
            { id: "compact", label: m.marginYPresetCompact, value: 16 },
            { id: "normal", label: m.marginYPresetNormal, value: 24 },
            { id: "spacious", label: m.marginYPresetSpacious, value: 40 },
          ]}
          onChangeValue={(v) =>
            updateBlock(selectedBlockId, {
              marginYPx: v,
            } as any)
          }
        />
      </div>

      <div className="space-y-2 border-t border-slate-800 pt-3 mt-4">
        <h3 className="text-[11px] font-semibold text-slate-800 dark:text-slate-200">{m.messagesSectionTitle}</h3>
        <label className="flex flex-col gap-1 text-xs text-slate-500 dark:text-slate-400">
          <span>{m.successMessageLabel}</span>
          <input
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            placeholder={m.successMessagePlaceholder}
            value={formProps.successMessage ?? ""}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                successMessage: e.target.value,
              } as any)
            }
          />
        </label>
        <label className="flex flex-col gap-1 text-xs text-slate-500 dark:text-slate-400">
          <span>{m.errorMessageLabel}</span>
          <input
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-xs text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            placeholder={m.errorMessagePlaceholder}
            value={formProps.errorMessage ?? ""}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                errorMessage: e.target.value,
              } as any)
            }
          />
        </label>
      </div>

      <div className="space-y-3 border-t border-slate-800 pt-3 mt-4">
        <h3 className="text-[11px] font-semibold text-slate-800 dark:text-slate-200">{m.controllerSectionTitle}</h3>

        <fieldset className="space-y-2" aria-label={m.fieldMappingAriaLabel}>
          <legend className="text-[11px] text-slate-400 mb-1">{m.fieldMappingLegend}</legend>
          {blocks
            .filter((b) =>
              b.type === "formInput" ||
              b.type === "formSelect" ||
              b.type === "formCheckbox" ||
              b.type === "formRadio",
            )
            .map((fieldBlock) => {
              const fieldId = fieldBlock.id;
              const anyProps: any = fieldBlock.props ?? {};

              const transmissionKey: string | undefined = anyProps.formFieldName;
              const labelText: string | undefined = anyProps.label ?? anyProps.groupLabel;

              const displayLabel = transmissionKey
                ? labelText && labelText !== transmissionKey
                  ? `${transmissionKey} (${labelText})`
                  : transmissionKey
                : labelText || fieldId;

              const checked = (formProps.fieldIds ?? []).includes(fieldId);
              const required = (formProps.requiredFieldIds ?? []).includes(fieldId);

              return (
                <label
                  key={fieldId}
                  className="flex items-center gap-2 text-[11px] text-slate-800 dark:text-slate-200"
                >
                  <input
                    type="checkbox"
                    className="h-3 w-3 rounded border border-slate-300 bg-white text-slate-900 dark:border-slate-600 dark:bg-slate-900"
                    checked={checked}
                    onChange={(e) => {
                      const current = formProps.fieldIds ?? [];
                      const next = e.target.checked
                        ? [...current, fieldId]
                        : current.filter((id) => id !== fieldId);

                      updateBlock(selectedBlockId, {
                        fieldIds: next,
                      } as any);
                    }}
                  />
                  <span className="flex-1 truncate">{displayLabel}</span>
                  <label className="inline-flex items-center gap-1 text-[11px] text-slate-400">
                    <input
                      type="checkbox"
                      className="h-3 w-3 rounded border border-slate-300 bg-white text-slate-900 dark:border-slate-600 dark:bg-slate-900"
                      checked={required}
                      onChange={(e) => {
                        const current = formProps.requiredFieldIds ?? [];
                        const next = e.target.checked
                          ? Array.from(new Set([...current, fieldId]))
                          : current.filter((id) => id !== fieldId);

                        updateBlock(selectedBlockId, {
                          requiredFieldIds: next,
                        } as any);
                      }}
                    />
                    <span>{m.requiredLabel}</span>
                  </label>
                </label>
              );
            })}
        </fieldset>

        <div className="space-y-1">
          <span className="text-[11px] text-slate-400">{m.submitButtonLabel}</span>
          <select
            className="w-full rounded border border-slate-300 bg-white px-2 py-1 text-[11px] text-slate-900 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
            aria-label={m.submitButtonAriaLabel}
            value={formProps.submitButtonId ?? ""}
            onChange={(e) =>
              updateBlock(selectedBlockId, {
                submitButtonId: e.target.value || null,
              } as any)
            }
          >
            <option value="">{m.submitButtonNoneOptionLabel}</option>
            {blocks
              .filter((b) => b.type === "button")
              .map((buttonBlock) => {
                const btnProps = buttonBlock.props as ButtonBlockProps;
                const transmissionKey = btnProps.formFieldName;
                const labelText = btnProps.label;
                const displayLabel = transmissionKey
                  ? labelText && labelText !== transmissionKey
                    ? `${transmissionKey} (${labelText})`
                    : transmissionKey
                  : labelText || buttonBlock.id;

                return (
                  <option key={buttonBlock.id} value={buttonBlock.id}>
                    {displayLabel}
                  </option>
                );
              })}
          </select>
        </div>
      </div>

      {showSheetsGuide && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60">
          <div className="w-full max-w-xl rounded border border-slate-200 bg-white px-4 py-3 text-xs text-slate-900 shadow-lg dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100">
            <div className="mb-2 flex items-center justify-between">
              <h4 className="text-[11px] font-semibold">{m.sheetsGuideHeading}</h4>
              <button
                type="button"
                className="text-[11px] text-slate-400 hover:text-slate-100"
                onClick={() => setShowSheetsGuide(false)}
                aria-label={m.sheetsGuideCloseAriaLabel}
              >
                ×
              </button>
            </div>
            <p className="text-[11px] text-slate-500 dark:text-slate-400 leading-relaxed">
              {m.sheetsGuideIntro}
            </p>
            <ol className="list-decimal list-inside space-y-1 text-[11px] text-slate-400 mt-2">
              <li>{m.sheetsGuideStep1}</li>
              <li>{m.sheetsGuideStep2}</li>
              <li>{m.sheetsGuideStep3}</li>
            </ol>
            <div className="mt-2 space-y-1">
              <span className="text-[11px] text-slate-500 dark:text-slate-400">{m.sheetsGuideExampleCodeLabel}</span>
              <textarea
                className="w-full h-40 rounded border border-slate-300 bg-white px-2 py-1 text-[11px] font-mono text-slate-900 outline-none dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100"
                readOnly
                value={sheetsScriptExample}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
