import React, { useEffect } from "react";
import {
  Modal,
  TextInput,
  Textarea,
  Select,
  NumberInput,
  Button,
  Stack,
  Group,
  Divider,
  Switch,
  Text,
  Alert,
  Code,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { useTranslation } from "react-i18next";
import { SlashCommandDto, CreateSlashCommandPayload } from "../services/slash-commands-client";

const ACTION_TYPE_OPTIONS = [
  { value: "insert-template", label: "Insert Template" },
  { value: "insert-table", label: "Insert Table" },
  { value: "embed-url", label: "Embed URL" },
  { value: "run-webhook", label: "Run Webhook" },
  { value: "insert-snippet", label: "Insert Code Snippet" },
];

interface Props {
  opened: boolean;
  onClose: () => void;
  onSubmit: (payload: CreateSlashCommandPayload) => void;
  initialValues?: SlashCommandDto | null;
  isLoading?: boolean;
}

interface FormValues {
  keyword: string;
  label: string;
  description: string;
  icon: string;
  actionType: string;
  isEnabled: boolean;
  // insert-template
  template: string;
  // insert-table
  rows: number;
  cols: number;
  withHeaderRow: boolean;
  // embed-url
  url: string;
  // run-webhook
  webhookUrl: string;
  webhookHeaders: string;
  // insert-snippet
  language: string;
  code: string;
}

/**
 * Polymorphic create/edit form for custom slash commands.
 *
 * The action_config section renders different fields depending on the selected
 * actionType (discriminated union pattern). Validation is done client-side
 * before submission; backend validates again with Zod.
 */
export function SlashCommandForm({
  opened,
  onClose,
  onSubmit,
  initialValues,
  isLoading,
}: Props) {
  const { t } = useTranslation();

  const form = useForm<FormValues>({
    initialValues: {
      keyword: "",
      label: "",
      description: "",
      icon: "",
      actionType: "insert-template",
      isEnabled: true,
      template: "# Title\n\n",
      rows: 3,
      cols: 3,
      withHeaderRow: true,
      url: "",
      webhookUrl: "",
      webhookHeaders: "",
      language: "typescript",
      code: "",
    },
    validate: {
      keyword: (v) =>
        /^[a-z0-9-]+$/.test(v)
          ? null
          : t("slash_commands.keyword_format_error"),
      label: (v) => (v.trim().length > 0 ? null : t("slash_commands.label_required")),
      url: (v, values) =>
        values.actionType === "embed-url" && !v.startsWith("http")
          ? t("slash_commands.url_required")
          : null,
      webhookUrl: (v, values) =>
        values.actionType === "run-webhook" && !v.startsWith("https://")
          ? t("slash_commands.webhook_https_required")
          : null,
      language: (v, values) =>
        values.actionType === "insert-snippet" && !v.trim()
          ? t("slash_commands.language_required")
          : null,
    },
  });

  // Populate form when editing an existing command
  useEffect(() => {
    if (!initialValues) {
      form.reset();
      return;
    }
    const cfg = initialValues.actionConfig as Record<string, unknown>;
    form.setValues({
      keyword: initialValues.keyword,
      label: initialValues.label,
      description: initialValues.description ?? "",
      icon: initialValues.icon ?? "",
      actionType: initialValues.actionType,
      isEnabled: initialValues.isEnabled,
      template:
        typeof cfg["template"] === "string"
          ? cfg["template"]
          : JSON.stringify(cfg["template"], null, 2),
      rows: (cfg["rows"] as number) ?? 3,
      cols: (cfg["cols"] as number) ?? 3,
      withHeaderRow: (cfg["withHeaderRow"] as boolean) ?? true,
      url: (cfg["url"] as string) ?? "",
      webhookUrl: (cfg["webhookUrl"] as string) ?? "",
      webhookHeaders: cfg["headers"]
        ? JSON.stringify(cfg["headers"], null, 2)
        : "",
      language: (cfg["language"] as string) ?? "typescript",
      code: (cfg["code"] as string) ?? "",
    });
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [initialValues?.id]);

  function buildActionConfig(values: FormValues): Record<string, unknown> {
    switch (values.actionType) {
      case "insert-template":
        return { template: values.template };
      case "insert-table":
        return {
          rows: values.rows,
          cols: values.cols,
          withHeaderRow: values.withHeaderRow,
        };
      case "embed-url":
        return { url: values.url };
      case "run-webhook": {
        let headers: Record<string, string> | undefined;
        if (values.webhookHeaders.trim()) {
          try {
            headers = JSON.parse(values.webhookHeaders) as Record<string, string>;
          } catch {
            // Headers JSON is invalid — backend Zod will reject cleanly
          }
        }
        return { webhookUrl: values.webhookUrl, ...(headers ? { headers } : {}) };
      }
      case "insert-snippet":
        return { language: values.language, code: values.code };
      default:
        return {};
    }
  }

  function handleSubmit(values: FormValues) {
    onSubmit({
      keyword: values.keyword,
      label: values.label,
      description: values.description || undefined,
      icon: values.icon || undefined,
      actionType: values.actionType as CreateSlashCommandPayload["actionType"],
      actionConfig: buildActionConfig(values),
      isEnabled: values.isEnabled,
    });
  }

  const actionType = form.values.actionType;

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={
        initialValues
          ? t("slash_commands.edit_title")
          : t("slash_commands.create_title")
      }
      size="lg"
    >
      <form onSubmit={form.onSubmit(handleSubmit)}>
        <Stack gap="sm">
          <TextInput
            label={t("slash_commands.keyword_label")}
            description={t("slash_commands.keyword_description")}
            placeholder="meeting-note"
            {...form.getInputProps("keyword")}
            disabled={!!initialValues}
          />
          <TextInput
            label={t("slash_commands.label_label")}
            placeholder="Meeting Note"
            {...form.getInputProps("label")}
          />
          <Textarea
            label={t("slash_commands.description_label")}
            placeholder={t("slash_commands.description_placeholder")}
            autosize
            minRows={2}
            {...form.getInputProps("description")}
          />
          <TextInput
            label={t("slash_commands.icon_label")}
            description={t("slash_commands.icon_description")}
            placeholder="IconNotes"
            {...form.getInputProps("icon")}
          />
          <Select
            label={t("slash_commands.action_type_label")}
            data={ACTION_TYPE_OPTIONS}
            {...form.getInputProps("actionType")}
          />
          <Switch
            label={t("slash_commands.enabled_label")}
            {...form.getInputProps("isEnabled", { type: "checkbox" })}
          />

          <Divider label={t("slash_commands.action_config_section")} />

          {/* Polymorphic config fields */}
          {actionType === "insert-template" && (
            <Textarea
              label={t("slash_commands.template_label")}
              description={t("slash_commands.template_description")}
              autosize
              minRows={4}
              styles={{ input: { fontFamily: "monospace" } }}
              {...form.getInputProps("template")}
            />
          )}

          {actionType === "insert-table" && (
            <>
              <NumberInput
                label={t("slash_commands.rows_label")}
                min={1}
                max={50}
                {...form.getInputProps("rows")}
              />
              <NumberInput
                label={t("slash_commands.cols_label")}
                min={1}
                max={20}
                {...form.getInputProps("cols")}
              />
              <Switch
                label={t("slash_commands.header_row_label")}
                {...form.getInputProps("withHeaderRow", { type: "checkbox" })}
              />
            </>
          )}

          {actionType === "embed-url" && (
            <TextInput
              label={t("slash_commands.url_label")}
              placeholder="https://example.com/embed"
              {...form.getInputProps("url")}
            />
          )}

          {actionType === "run-webhook" && (
            <>
              <Alert color="yellow" title={t("slash_commands.webhook_security_title")}>
                {t("slash_commands.webhook_security_note")}
              </Alert>
              <TextInput
                label={t("slash_commands.webhook_url_label")}
                placeholder="https://hooks.example.com/trigger"
                {...form.getInputProps("webhookUrl")}
              />
              <Textarea
                label={t("slash_commands.webhook_headers_label")}
                description={t("slash_commands.webhook_headers_description")}
                placeholder={'{"X-Tenant": "acadenice"}'}
                autosize
                minRows={2}
                styles={{ input: { fontFamily: "monospace" } }}
                {...form.getInputProps("webhookHeaders")}
              />
            </>
          )}

          {actionType === "insert-snippet" && (
            <>
              <TextInput
                label={t("slash_commands.language_label")}
                placeholder="typescript"
                {...form.getInputProps("language")}
              />
              <Textarea
                label={t("slash_commands.snippet_code_label")}
                description={t("slash_commands.snippet_code_description")}
                autosize
                minRows={3}
                styles={{ input: { fontFamily: "monospace" } }}
                {...form.getInputProps("code")}
              />
            </>
          )}

          <Group justify="flex-end" mt="md">
            <Button variant="default" onClick={onClose} disabled={isLoading}>
              {t("Cancel")}
            </Button>
            <Button type="submit" loading={isLoading}>
              {initialValues ? t("Save") : t("Create")}
            </Button>
          </Group>
        </Stack>
      </form>
    </Modal>
  );
}
