"use client";

import type { Edge } from "@xyflow/react";
import {
  Braces,
  GitBranch,
  Plus,
  Trash2,
} from "lucide-react";
import { useState } from "react";

import { SectionCard } from "@/components/editor/section-card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";

import { NodeSelect } from "./controls";
import type { ExpressionRule, WorkflowEdgeData } from "../specs";

export function EdgeSettingsPanel({
  edge,
  sourceType,
  isOnlyOutgoing,
  hasOtherDefaultPath,
  onChange,
}: {
  edge: Edge;
  sourceType?: string;
  isOnlyOutgoing: boolean;
  hasOtherDefaultPath: boolean;
  onChange: (patch: Partial<WorkflowEdgeData>) => void;
}) {
  const data = (edge.data ?? { mode: "always", priority: 10 }) as WorkflowEdgeData;
  const [mode, setMode] = useState(data.mode ?? "always");
  const [condition, setCondition] = useState(data.condition ?? "");
  const [combinator, setCombinator] = useState<"and" | "or">(
    data.expression?.combinator ?? "and",
  );
  const [rules, setRules] = useState<ExpressionRule[]>(
    data.expression?.rules?.length
      ? data.expression.rules
      : [{ variable: "", operator: "eq", value: "" }],
  );

  const publish = ({
    nextMode = mode,
    nextCondition = condition,
    nextCombinator = combinator,
    nextRules = rules,
  }: {
    nextMode?: WorkflowEdgeData["mode"];
    nextCondition?: string;
    nextCombinator?: "and" | "or";
    nextRules?: ExpressionRule[];
  }) =>
    onChange({
      mode: nextMode,
      condition: nextMode === "llm" ? nextCondition : undefined,
      expression:
        nextMode === "expression"
          ? { combinator: nextCombinator, rules: nextRules }
          : undefined,
    });

  const setRule = (index: number, patch: Partial<ExpressionRule>) => {
    const nextRules = rules.map((rule, ruleIndex) =>
      ruleIndex === index ? { ...rule, ...patch } : rule,
    );
    setRules(nextRules);
    publish({ nextRules });
  };

  const parseValue = (value: string): unknown => {
    if (value === "true") return true;
    if (value === "false") return false;
    if (value !== "" && Number.isFinite(Number(value))) return Number(value);
    return value;
  };

  return (
    <div className="space-y-3">
      <SectionCard
        icon={<GitBranch size={15} />}
        title="路由方式"
        description="每个节点最多一条默认路径，也可以配置多条条件路径"
      >
        <NodeSelect
          label="条件类型"
          value={mode}
          options={[
            {
              value: "always",
              label: "默认路径",
              disabled:
                mode !== "always" &&
                (hasOtherDefaultPath ||
                  (sourceType === "agent" && isOnlyOutgoing)),
            },
            { value: "llm", label: "大模型判断" },
            { value: "expression", label: "表达式" },
          ]}
          onChange={(value) => {
            const nextMode =
              (value as WorkflowEdgeData["mode"]) || "always";
            setMode(nextMode);
            publish({ nextMode });
          }}
          allowNone={false}
        />
        {mode !== "always" && hasOtherDefaultPath && (
          <span className="-mt-1 block text-xs text-muted-foreground">
            当前节点已经有一条默认路径；其它出边需要使用大模型判断或表达式。
          </span>
        )}
        {sourceType === "agent" && isOnlyOutgoing && mode === "always" && (
          <span className="-mt-1 block text-xs text-destructive">
            Agent 不能只有默认路径；请改为条件路径，或删除连接以持续对话。
          </span>
        )}
      </SectionCard>

      <SectionCard
        icon={<Braces size={15} />}
        title="触发条件"
        description="配置这条连接被命中的条件"
      >
        {mode === "llm" && (
          <label className="block">
            <div className="mb-1.5 text-sm font-medium text-foreground">
              自然语言条件 <span className="text-destructive">*</span>
            </div>
            <Textarea
              rows={4}
              value={condition}
              placeholder="例如：用户已经明确表示需要人工客服。"
              onChange={(event) => {
                const nextCondition = event.target.value;
                setCondition(nextCondition);
                publish({ nextCondition });
              }}
              className="field-sizing-fixed min-h-24 resize-y border-hairline-strong bg-background text-sm text-foreground placeholder:text-muted-soft"
            />
            {!condition.trim() && (
              <span className="mt-1.5 block text-xs text-destructive">
                LLM 判断需要填写触发条件。
              </span>
            )}
          </label>
        )}

        {mode === "expression" && (
          <div className="space-y-3">
            <NodeSelect
              label="规则组合"
              value={combinator}
              options={[
                { value: "and", label: "全部满足（AND）" },
                { value: "or", label: "任一满足（OR）" },
              ]}
              onChange={(value) => {
                const nextCombinator = value === "or" ? "or" : "and";
                setCombinator(nextCombinator);
                publish({ nextCombinator });
              }}
              allowNone={false}
            />
            {rules.map((rule, index) => (
              <div
                key={index}
                className="space-y-2 rounded-xl border border-hairline bg-canvas-soft p-3"
              >
                <Input
                  value={rule.variable}
                  placeholder="动态变量名"
                  onChange={(event) => setRule(index, { variable: event.target.value })}
                  className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
                />
                <div className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto] gap-2">
                  <Select
                    value={rule.operator}
                    onValueChange={(value) =>
                      setRule(index, {
                        operator: value as ExpressionRule["operator"],
                      })
                    }
                  >
                    <SelectTrigger className="border-hairline-strong bg-background">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {[
                        "eq",
                        "neq",
                        "gt",
                        "gte",
                        "lt",
                        "lte",
                        "contains",
                        "in",
                        "exists",
                      ].map((operator) => (
                        <SelectItem key={operator} value={operator}>
                          {operator}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <Input
                    disabled={rule.operator === "exists"}
                    value={rule.value == null ? "" : String(rule.value)}
                    placeholder="比较值"
                    onChange={(event) =>
                      setRule(index, {
                        value: parseValue(event.target.value),
                      })
                    }
                    className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
                  />
                  <Button
                    type="button"
                    size="icon"
                    variant="outline"
                    disabled={rules.length === 1}
                    aria-label={`删除第 ${index + 1} 条规则`}
                    onClick={() => {
                      const nextRules = rules.filter(
                        (_, ruleIndex) => ruleIndex !== index,
                      );
                      setRules(nextRules);
                      publish({ nextRules });
                    }}
                  >
                    <Trash2 size={14} />
                  </Button>
                </div>
                {!rule.variable.trim() && (
                  <span className="text-xs text-destructive">
                    请输入动态变量名。
                  </span>
                )}
              </div>
            ))}
            <Button
              type="button"
              variant="outline"
              className="w-full gap-2 border-hairline-strong"
              onClick={() => {
                const nextRules = [
                  ...rules,
                  { variable: "", operator: "eq", value: "" } as ExpressionRule,
                ];
                setRules(nextRules);
                publish({ nextRules });
              }}
            >
              <Plus size={14} />
              添加规则
            </Button>
          </div>
        )}

        {mode === "always" && (
          <p className="rounded-xl border border-hairline bg-canvas-soft px-3.5 py-3 text-sm leading-6 text-muted-foreground">
            当前节点没有其它条件命中时，将沿这条默认路径继续执行。
          </p>
        )}
      </SectionCard>
    </div>
  );
}
