import { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import { Eye, EyeOff, Plus, Settings2, Trash2 } from 'lucide-react';
import { APP_ENDPOINTS } from '../../config/env';
import { useAppStore } from '../../store/appStore';
import { channelsZhCn } from '../../i18n/channels.zh-cn';
import { channelsEn } from '../../i18n/channels.en';
import { pickLocale } from '../../i18n';
import { wizardZhCn } from '../../i18n/wizard.zh-cn';
import { wizardEn } from '../../i18n/wizard.en';
import { useLucentPrompt } from '../../components/lucent/LucentPromptProvider';

type AgentTab = 'AGENTS' | 'SOUL' | 'USER' | 'TOOLS' | 'IDENTITY';
type ChannelType = 'feishu' | 'qq' | 'dingtalk' | 'telegram' | 'slack';

const FALLBACK_SOUL_MD = '# Soul\n\n你是专业的企业数字员工，表达清晰、可执行。';
const FALLBACK_AGENTS_MD = '# Agent Instructions\n\n- 优先完成任务目标\n- 操作前先说明意图\n- 输出必须可执行\n\n## 默认输出规范\n\n- 每次执行任务时，在 workspace 中创建新目录保存本次输出。\n- 输出内容默认采用 Markdown（.md）格式。';
const FALLBACK_USER_MD = '# User\n\n- 语言: 中文\n- 风格: 专业\n- 偏好: 简明且有步骤';
const FALLBACK_TOOLS_MD = '# Tools\n\n- 谨慎使用 shell\n- 修改文件后复核\n- 失败时说明原因并重试策略';
const FALLBACK_IDENTITY_MD = '# Identity\n\n- 角色: 企业数字员工\n- 领域: 运维与任务执行';

interface WizardChannelConfig {
  channel_type: ChannelType;
  is_active: boolean;
  external_app_id: string;
  app_secret: string;
  internal_port: number;
  extra_config: Record<string, unknown>;
}

interface NanobotImage {
  tag: string;
  status: string;
}

interface SystemDefaultsResponse {
  templates?: {
    soul_md?: string;
    agents_md?: string;
    user_md?: string;
    tools_md?: string;
    identity_md?: string;
  };
}

const providerPresets: Record<string, { model: string; note: { 'zh-cn': string; en: string }; apiBase?: string }> = {
  openrouter: {
    model: 'openai/gpt-4o-mini',
    note: {
      'zh-cn': 'OpenRouter 网关，模型名示例 openai/gpt-4o-mini。',
      en: 'OpenRouter gateway, model example: openai/gpt-4o-mini.',
    },
    apiBase: 'https://openrouter.ai/api/v1',
  },
  dashscope: {
    model: 'qwen-plus',
    note: {
      'zh-cn': '阿里云 DashScope（千问），模型示例 qwen-plus / qwen-max。',
      en: 'Alibaba DashScope (Qwen), model example: qwen-plus / qwen-max.',
    },
    apiBase: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
  },
  openai: {
    model: 'gpt-4o-mini',
    note: {
      'zh-cn': 'OpenAI 原生模型。',
      en: 'OpenAI native models.',
    },
  },
  deepseek: {
    model: 'deepseek-chat',
    note: {
      'zh-cn': 'DeepSeek 原生模型。',
      en: 'DeepSeek native models.',
    },
  },
  kimi: {
    model: 'moonshot-v1-8k',
    note: {
      'zh-cn': 'Kimi（Moonshot）接口，模型示例 moonshot-v1-8k。',
      en: 'Kimi (Moonshot) endpoint, model example: moonshot-v1-8k.',
    },
    apiBase: 'https://api.moonshot.cn/v1',
  },
  minimax: {
    model: 'MiniMax-Text-01',
    note: {
      'zh-cn': 'MiniMax 接口，模型示例 MiniMax-Text-01。',
      en: 'MiniMax endpoint, model example: MiniMax-Text-01.',
    },
    apiBase: 'https://api.minimax.chat/v1',
  },
};

const initialForm = {
  id: '',
  name: '',
  llm_provider: 'dashscope',
  llm_model: providerPresets.dashscope.model,
  api_key: '',
  api_base: providerPresets.dashscope.apiBase ?? '',
  image_tag: '',

  temperature: 0.2,
  top_p: 1.0,
  max_tokens: 8192,

  soul_md: FALLBACK_SOUL_MD,
  agents_md: FALLBACK_AGENTS_MD,
  user_md: FALLBACK_USER_MD,
  tools_md: FALLBACK_TOOLS_MD,
  identity_md: FALLBACK_IDENTITY_MD,
  env_params: {} as Record<string, string>,
  send_progress: false,
  send_tool_hints: false,
  channels: [] as WizardChannelConfig[],
};

const optionalChannelTypes: ChannelType[] = ['feishu', 'qq', 'dingtalk', 'telegram', 'slack'];

interface BotWizardModuleProps {
  onCreated?: () => void;
  onGoDashboard?: () => void;
}

export function BotWizardModule({ onCreated, onGoDashboard }: BotWizardModuleProps) {
  const { locale } = useAppStore();
  const { notify } = useLucentPrompt();
  const [step, setStep] = useState(1);
  const [images, setImages] = useState<NanobotImage[]>([]);
  const [isLoadingImages, setIsLoadingImages] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [autoStart, setAutoStart] = useState(true);
  const [isTestingProvider, setIsTestingProvider] = useState(false);
  const [testResult, setTestResult] = useState('');
  const [agentTab, setAgentTab] = useState<AgentTab>('AGENTS');
  const [showChannelModal, setShowChannelModal] = useState(false);
  const [showToolsConfigModal, setShowToolsConfigModal] = useState(false);
  const [envDraftKey, setEnvDraftKey] = useState('');
  const [envDraftValue, setEnvDraftValue] = useState('');
  const [envDraftVisible, setEnvDraftVisible] = useState(false);
  const [envVisibleByKey, setEnvVisibleByKey] = useState<Record<string, boolean>>({});
  const [newChannelType, setNewChannelType] = useState<ChannelType>('feishu');
  const [form, setForm] = useState(initialForm);
  const [defaultAgentsTemplate, setDefaultAgentsTemplate] = useState(FALLBACK_AGENTS_MD);

  const readyImages = useMemo(() => images.filter((img) => img.status === 'READY'), [images]);
  const isZh = locale === 'zh';
  const ui = pickLocale(locale, { 'zh-cn': wizardZhCn, en: wizardEn });
  const lc = isZh ? channelsZhCn : channelsEn;
  const noteLocale = pickLocale(locale, { 'zh-cn': 'zh-cn' as const, en: 'en' as const });
  const activeChannelTypes = useMemo(() => new Set(form.channels.map((c) => c.channel_type)), [form.channels]);
  const addableChannelTypes = useMemo(
    () => optionalChannelTypes.filter((t) => !activeChannelTypes.has(t)),
    [activeChannelTypes],
  );
  const envEntries = useMemo(
    () =>
      Object.entries(form.env_params || {})
        .filter(([k]) => String(k || '').trim().length > 0)
        .sort(([a], [b]) => a.localeCompare(b)),
    [form.env_params],
  );

  useEffect(() => {
    const loadSystemDefaults = async () => {
      try {
        const res = await axios.get<SystemDefaultsResponse>(`${APP_ENDPOINTS.apiBase}/system/defaults`);
        const tpl = res.data?.templates || {};
        const agentsTemplate = String(tpl.agents_md || '').trim() || FALLBACK_AGENTS_MD;
        setDefaultAgentsTemplate(agentsTemplate);
        setForm((prev) => {
          return {
            ...prev,
            soul_md: String(tpl.soul_md || '').trim() || prev.soul_md,
            agents_md: agentsTemplate,
            user_md: String(tpl.user_md || '').trim() || prev.user_md,
            tools_md: String(tpl.tools_md || '').trim() || prev.tools_md,
            identity_md: String(tpl.identity_md || '').trim() || prev.identity_md,
          };
        });
      } catch {
        // keep fallback templates
      }
    };
    void loadSystemDefaults();
  }, []);
  const configuredChannelsLabel = useMemo(
    () => (form.channels.length > 0 ? form.channels.map((c) => c.channel_type).join(', ') : '-'),
    [form.channels],
  );

  const loadImages = async () => {
    setIsLoadingImages(true);
    try {
      const res = await axios.get<NanobotImage[]>(`${APP_ENDPOINTS.apiBase}/images`);
      setImages(res.data);
      const ready = res.data.filter((img) => img.status === 'READY');
      if (!form.image_tag && ready.length > 0) {
        setForm((prev) => ({ ...prev, image_tag: ready[0].tag }));
      }
      return ready;
    } finally {
      setIsLoadingImages(false);
    }
  };

  const next = async () => {
    if (step === 1) {
      const ready = await loadImages();
      if (ready.length === 0) {
        notify(ui.noReadyImage, { tone: 'warning' });
        return;
      }
    }

    if (step === 2) {
      if (!form.id || !form.name || !form.api_key || !form.image_tag || !form.llm_model) {
        notify(ui.requiredBase, { tone: 'warning' });
        return;
      }
    }

    if (step < 4) {
      setStep((s) => s + 1);
    }
  };

  const testProvider = async () => {
    if (!form.llm_provider || !form.api_key || !form.llm_model) {
      notify(ui.providerRequired, { tone: 'warning' });
      return;
    }

    setIsTestingProvider(true);
    setTestResult('');
    try {
      const res = await axios.post(`${APP_ENDPOINTS.apiBase}/providers/test`, {
        provider: form.llm_provider,
        model: form.llm_model,
        api_key: form.api_key,
        api_base: form.api_base || undefined,
      });

      if (res.data?.ok) {
        const preview = (res.data.models_preview || []).slice(0, 3).join(', ');
        setTestResult(ui.connOk(preview));
      } else {
        setTestResult(ui.connFailed(res.data?.detail || 'unknown error'));
      }
    } catch (error: any) {
      const msg = error?.response?.data?.detail || error?.message || 'request failed';
      setTestResult(ui.connFailed(msg));
    } finally {
      setIsTestingProvider(false);
    }
  };

  const createBot = async () => {
    setIsSubmitting(true);
    try {
      await axios.post(`${APP_ENDPOINTS.apiBase}/bots`, {
        id: form.id,
        name: form.name,
        llm_provider: form.llm_provider,
        llm_model: form.llm_model,
        api_key: form.api_key,
        api_base: form.api_base || undefined,
        image_tag: form.image_tag,
        system_prompt: form.soul_md,
        temperature: clampTemperature(Number(form.temperature)),
        top_p: Number(form.top_p),
        max_tokens: Number(form.max_tokens),
        soul_md: form.soul_md,
        agents_md: form.agents_md,
        user_md: form.user_md,
        tools_md: form.tools_md,
        identity_md: form.identity_md,
        send_progress: Boolean(form.send_progress),
        send_tool_hints: Boolean(form.send_tool_hints),
        channels: form.channels.map((c) => ({
          channel_type: c.channel_type,
          is_active: c.is_active,
          external_app_id: c.external_app_id,
          app_secret: c.app_secret,
          internal_port: c.internal_port,
          extra_config: sanitizeChannelExtra(c.channel_type, c.extra_config),
        })),
        env_params: form.env_params,
      });

      if (autoStart) {
        await axios.post(`${APP_ENDPOINTS.apiBase}/bots/${form.id}/start`);
      }
      onCreated?.();
      onGoDashboard?.();
      setForm(initialForm);
      setStep(1);
      setTestResult('');
      notify(ui.created, { tone: 'success' });
    } catch (error: any) {
      const msg = error?.response?.data?.detail || ui.createFailed;
      notify(msg, { tone: 'error' });
    } finally {
      setIsSubmitting(false);
    }
  };

  const onProviderChange = (provider: string) => {
    const preset = providerPresets[provider] ?? { model: '' };
    setForm((p) => ({
      ...p,
      llm_provider: provider,
      llm_model: preset.model || p.llm_model,
      api_base: preset.apiBase ?? '',
    }));
    setTestResult('');
  };

  const tabMap: Record<AgentTab, keyof typeof form> = {
    AGENTS: 'agents_md',
    SOUL: 'soul_md',
    USER: 'user_md',
    TOOLS: 'tools_md',
    IDENTITY: 'identity_md',
  };

  const addChannel = () => {
    if (!addableChannelTypes.includes(newChannelType)) return;
    setForm((prev) => ({
      ...prev,
      channels: [
        ...prev.channels,
        {
          channel_type: newChannelType,
          is_active: true,
          external_app_id: '',
          app_secret: '',
          internal_port: 8080,
          extra_config: {},
        },
      ],
    }));
    const rest = addableChannelTypes.filter((t) => t !== newChannelType);
    if (rest.length > 0) setNewChannelType(rest[0]);
  };

  const upsertEnvParam = (key: string, value: string) => {
    const normalized = String(key || '').trim().toUpperCase();
    if (!normalized) return;
    setForm((prev) => ({
      ...prev,
      env_params: {
        ...(prev.env_params || {}),
        [normalized]: String(value || ''),
      },
    }));
  };

  const removeEnvParam = (key: string) => {
    const normalized = String(key || '').trim().toUpperCase();
    if (!normalized) return;
    setForm((prev) => {
      const next = { ...(prev.env_params || {}) };
      delete next[normalized];
      return { ...prev, env_params: next };
    });
  };

  const updateChannel = (index: number, patch: Partial<WizardChannelConfig>) => {
    setForm((prev) => ({
      ...prev,
      channels: prev.channels.map((c, i) => (i === index ? { ...c, ...patch } : c)),
    }));
  };

  const removeChannel = (index: number) => {
    setForm((prev) => ({
      ...prev,
      channels: prev.channels.filter((_, i) => i !== index),
    }));
  };

  const clampMaxTokens = (value: number) => {
    if (Number.isNaN(value)) return 8192;
    return Math.min(32768, Math.max(256, Math.round(value)));
  };
  const clampTemperature = (value: number) => {
    if (Number.isNaN(value)) return 0.2;
    return Math.min(1, Math.max(0, value));
  };

  const updateGlobalDeliveryFlag = (key: 'sendProgress' | 'sendToolHints', value: boolean) => {
    setForm((prev) => {
      if (key === 'sendProgress') return { ...prev, send_progress: value };
      return { ...prev, send_tool_hints: value };
    });
  };
  const sanitizeChannelExtra = (_channelType: string, extra: Record<string, unknown>) => {
    const next = { ...(extra || {}) };
    delete next.sendProgress;
    delete next.sendToolHints;
    return next;
  };

  const renderChannelFields = (channel: WizardChannelConfig, idx: number) => {
    if (channel.channel_type === 'telegram') {
      return (
        <>
          <input
            className="input"
            type="password"
            placeholder={lc.telegramToken}
            value={channel.app_secret}
            onChange={(e) => updateChannel(idx, { app_secret: e.target.value })}
          />
          <input
            className="input"
            placeholder={lc.proxy}
            value={String((channel.extra_config || {}).proxy || '')}
            onChange={(e) =>
              updateChannel(idx, { extra_config: { ...(channel.extra_config || {}), proxy: e.target.value } })
            }
          />
          <label className="field-label">
            <input
              type="checkbox"
              checked={Boolean((channel.extra_config || {}).replyToMessage)}
              onChange={(e) =>
                updateChannel(idx, {
                  extra_config: { ...(channel.extra_config || {}), replyToMessage: e.target.checked },
                })
              }
              style={{ marginRight: 6 }}
            />
            {lc.replyToMessage}
          </label>
        </>
      );
    }

    if (channel.channel_type === 'feishu') {
      return (
        <>
          <input className="input" placeholder={lc.appId} value={channel.external_app_id} onChange={(e) => updateChannel(idx, { external_app_id: e.target.value })} />
          <input className="input" type="password" placeholder={lc.appSecret} value={channel.app_secret} onChange={(e) => updateChannel(idx, { app_secret: e.target.value })} />
          <input
            className="input"
            placeholder={lc.encryptKey}
            value={String((channel.extra_config || {}).encryptKey || '')}
            onChange={(e) =>
              updateChannel(idx, { extra_config: { ...(channel.extra_config || {}), encryptKey: e.target.value } })
            }
          />
          <input
            className="input"
            placeholder={lc.verificationToken}
            value={String((channel.extra_config || {}).verificationToken || '')}
            onChange={(e) =>
              updateChannel(idx, { extra_config: { ...(channel.extra_config || {}), verificationToken: e.target.value } })
            }
          />
        </>
      );
    }

    if (channel.channel_type === 'dingtalk') {
      return (
        <>
          <input className="input" placeholder={lc.clientId} value={channel.external_app_id} onChange={(e) => updateChannel(idx, { external_app_id: e.target.value })} />
          <input className="input" type="password" placeholder={lc.clientSecret} value={channel.app_secret} onChange={(e) => updateChannel(idx, { app_secret: e.target.value })} />
        </>
      );
    }

    if (channel.channel_type === 'slack') {
      return (
        <>
          <input className="input" placeholder={lc.botToken} value={channel.external_app_id} onChange={(e) => updateChannel(idx, { external_app_id: e.target.value })} />
          <input className="input" type="password" placeholder={lc.appToken} value={channel.app_secret} onChange={(e) => updateChannel(idx, { app_secret: e.target.value })} />
        </>
      );
    }

    if (channel.channel_type === 'qq') {
      return (
        <>
          <input className="input" placeholder={lc.appId} value={channel.external_app_id} onChange={(e) => updateChannel(idx, { external_app_id: e.target.value })} />
          <input className="input" type="password" placeholder={lc.appSecret} value={channel.app_secret} onChange={(e) => updateChannel(idx, { app_secret: e.target.value })} />
        </>
      );
    }

    return null;
  };

  return (
    <section className="panel stack wizard-shell" style={{ height: '100%' }}>
      <div className="wizard-head">
        <h2>{ui.title}</h2>
        <p className="panel-desc">{ui.sub}</p>
      </div>

      <div className="wizard-steps wizard-steps-4 wizard-steps-enhanced">
        <div className={`wizard-step ${step === 1 ? 'active' : ''}`}>{ui.s1}</div>
        <div className={`wizard-step ${step === 2 ? 'active' : ''}`}>{ui.s2}</div>
        <div className={`wizard-step ${step === 3 ? 'active' : ''}`}>{ui.s3}</div>
        <div className={`wizard-step ${step === 4 ? 'active' : ''}`}>{ui.s4}</div>
      </div>

      {step === 1 && (
        <div className="stack">
          <button className="btn btn-secondary" onClick={() => void loadImages()}>{isLoadingImages ? ui.loading : ui.loadImages}</button>
          <div className="list-scroll" style={{ maxHeight: '52vh' }}>
            {readyImages.map((img) => (
              <label key={img.tag} className="card selectable" style={{ display: 'block', cursor: 'pointer' }}>
                <input
                  type="radio"
                  checked={form.image_tag === img.tag}
                  onChange={() => setForm((prev) => ({ ...prev, image_tag: img.tag }))}
                  style={{ marginRight: 8 }}
                />
                <span className="mono">{img.tag}</span>
                <span style={{ marginLeft: 10 }} className="badge badge-ok">READY</span>
              </label>
            ))}
            {readyImages.length === 0 && <div style={{ color: 'var(--muted)' }}>{ui.noReady}</div>}
          </div>
        </div>
      )}

      {step === 2 && (
        <div className="grid-2 wizard-step2-grid wizard-step2-grid-3" style={{ gridTemplateColumns: '1fr 1fr 1fr' }}>
          <div className="stack card wizard-step2-card">
            <div className="section-mini-title">{ui.baseInfo}</div>
            <input className="input" placeholder={ui.botIdPlaceholder} value={form.id} onChange={(e) => setForm((p) => ({ ...p, id: e.target.value }))} />
            <input className="input" placeholder={ui.botName} value={form.name} onChange={(e) => setForm((p) => ({ ...p, name: e.target.value }))} />

            <div className="section-mini-title">{ui.modelAccess}</div>
            <select className="select" value={form.llm_provider} onChange={(e) => onProviderChange(e.target.value)}>
              <option value="openrouter">openrouter</option>
              <option value="dashscope">dashscope (aliyun qwen)</option>
              <option value="openai">openai</option>
              <option value="deepseek">deepseek</option>
              <option value="kimi">kimi (moonshot)</option>
              <option value="minimax">minimax</option>
            </select>
            <input className="input" placeholder={ui.modelNamePlaceholder} value={form.llm_model} onChange={(e) => setForm((p) => ({ ...p, llm_model: e.target.value }))} />
            <input className="input" type="password" placeholder="API Key" value={form.api_key} onChange={(e) => setForm((p) => ({ ...p, api_key: e.target.value }))} />
            <input className="input" placeholder="API Base" value={form.api_base} onChange={(e) => setForm((p) => ({ ...p, api_base: e.target.value }))} />

            <div className="card wizard-note-card" style={{ fontSize: 12, color: 'var(--muted)' }}>
              {providerPresets[form.llm_provider]?.note[noteLocale]}
            </div>
            <button className="btn btn-secondary" onClick={() => void testProvider()} disabled={isTestingProvider}>
              {isTestingProvider ? ui.testing : ui.test}
            </button>
            {testResult && <div className="card wizard-note-card">{testResult}</div>}
          </div>

          <div className="stack card wizard-step2-card">
            <div className="section-mini-title">{ui.modelParams}</div>
            <div className="slider-row">
              <label className="field-label">Temperature: {form.temperature.toFixed(2)}</label>
              <input type="range" min="0" max="1" step="0.01" value={form.temperature} onChange={(e) => setForm((p) => ({ ...p, temperature: clampTemperature(Number(e.target.value)) }))} />
            </div>
            <div className="slider-row">
              <label className="field-label">Top P: {form.top_p.toFixed(2)}</label>
              <input type="range" min="0" max="1" step="0.01" value={form.top_p} onChange={(e) => setForm((p) => ({ ...p, top_p: Number(e.target.value) }))} />
            </div>
            <div className="slider-row token-input-row">
              <label className="field-label" htmlFor="wizard-max-tokens">Max Tokens</label>
              <input
                id="wizard-max-tokens"
                className="input token-number-input"
                type="number"
                step="1"
                min="256"
                max="32768"
                value={form.max_tokens}
                onChange={(e) => setForm((p) => ({ ...p, max_tokens: clampMaxTokens(Number(e.target.value)) }))}
                onBlur={(e) => setForm((p) => ({ ...p, max_tokens: clampMaxTokens(Number(e.target.value)) }))}
              />
              <div className="field-label">{ui.tokenRange}</div>
            </div>

          </div>

          <div className="stack card wizard-step2-card">
            <div className="section-mini-title">{lc.wizardSectionTitle}</div>
            <div className="card wizard-note-card wizard-channel-summary">
              <div className="field-label">{lc.wizardSectionDesc}</div>
              <div className="mono">
                {configuredChannelsLabel}
              </div>
              <button className="btn btn-secondary btn-sm icon-btn" onClick={() => setShowChannelModal(true)} title={lc.openManager} aria-label={lc.openManager}>
                <Settings2 size={14} />
              </button>
            </div>

            <div className="section-mini-title" style={{ marginTop: 6 }}>{ui.toolsConfig}</div>
            <div className="card wizard-note-card wizard-channel-summary">
              <div className="field-label">{ui.toolsDesc}</div>
              <div className="mono">
                {envEntries.length > 0 ? envEntries.map(([k]) => k).join(', ') : ui.noEnvParams}
              </div>
              <button
                className="btn btn-secondary btn-sm icon-btn"
                onClick={() => setShowToolsConfigModal(true)}
                title={ui.openToolsManager}
                aria-label={ui.openToolsManager}
              >
                <Settings2 size={14} />
              </button>
            </div>
          </div>
        </div>
      )}

      {step === 3 && (
        <div className="wizard-agent-layout">
          <div className="agent-tabs-vertical">
            {(['AGENTS', 'SOUL', 'USER', 'TOOLS', 'IDENTITY'] as AgentTab[]).map((tab) => (
              <button key={tab} className={`agent-tab ${agentTab === tab ? 'active' : ''}`} onClick={() => setAgentTab(tab)}>
                {tab}.md
              </button>
            ))}
          </div>
          <div className="stack" style={{ minWidth: 0 }}>
            {agentTab === 'AGENTS' ? (
              <div className="row-between">
                <span className="field-label">
                  {isZh
                    ? '建议：将“创建新目录并以 Markdown 输出”写入 AGENTS.md'
                    : 'Tip: Put "create output directory + markdown output" in AGENTS.md'}
                </span>
                <button
                  className="btn btn-secondary btn-sm"
                  onClick={() =>
                    setForm((p) => ({ ...p, agents_md: defaultAgentsTemplate }))
                  }
                >
                  {isZh ? '插入默认规则' : 'Insert default rule'}
                </button>
              </div>
            ) : null}
            <textarea
              className="textarea md-area"
              value={String(form[tabMap[agentTab]])}
              onChange={(e) => setForm((p) => ({ ...p, [tabMap[agentTab]]: e.target.value }))}
            />
          </div>
        </div>
      )}

      {step === 4 && (
        <div className="stack">
            <div className="card summary-grid">
            <div>{ui.image}: <span className="mono">{form.image_tag}</span></div>
            <div>Bot ID: <span className="mono">{form.id}</span></div>
            <div>{ui.name}: {form.name}</div>
            <div>Provider: {form.llm_provider}</div>
            <div>{ui.model}: {form.llm_model}</div>
            <div>Temperature: {form.temperature.toFixed(2)}</div>
            <div>Top P: {form.top_p.toFixed(2)}</div>
            <div>Max Tokens: {form.max_tokens}</div>
            <div>{ui.channels}: {configuredChannelsLabel}</div>
            <div>{ui.tools}: {envEntries.map(([k]) => k).join(', ') || '-'}</div>
          </div>
          <label>
            <input type="checkbox" checked={autoStart} onChange={(e) => setAutoStart(e.target.checked)} style={{ marginRight: 8 }} />
            {ui.autoStart}
          </label>
        </div>
      )}

      {showChannelModal && (
        <div className="modal-mask" onClick={() => setShowChannelModal(false)}>
          <div className="modal-card modal-wide" onClick={(e) => e.stopPropagation()}>
            <h3>{lc.wizardSectionTitle}</h3>
            <div className="card">
              <div className="section-mini-title">{lc.globalDeliveryTitle}</div>
              <div className="field-label">{lc.globalDeliveryDesc}</div>
              <div className="wizard-dashboard-switches" style={{ marginTop: 8 }}>
                <label className="field-label">
                  <input
                    type="checkbox"
                    checked={Boolean(form.send_progress)}
                    onChange={(e) => updateGlobalDeliveryFlag('sendProgress', e.target.checked)}
                    style={{ marginRight: 6 }}
                  />
                  {lc.sendProgress}
                </label>
                <label className="field-label">
                  <input
                    type="checkbox"
                    checked={Boolean(form.send_tool_hints)}
                    onChange={(e) => updateGlobalDeliveryFlag('sendToolHints', e.target.checked)}
                    style={{ marginRight: 6 }}
                  />
                  {lc.sendToolHints}
                </label>
              </div>
            </div>
            <div className="wizard-channel-list">
              {form.channels.map((channel, idx) => (
                <div key={`${channel.channel_type}-${idx}`} className="card wizard-channel-card wizard-channel-compact">
                  <div className="row-between">
                    <strong style={{ textTransform: 'uppercase' }}>{channel.channel_type}</strong>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <label className="field-label">
                        <input
                          type="checkbox"
                          checked={channel.is_active}
                          onChange={(e) => updateChannel(idx, { is_active: e.target.checked })}
                          style={{ marginRight: 6 }}
                        />
                        {lc.enabled}
                      </label>
                      <button
                        className="btn btn-danger btn-sm wizard-icon-btn"
                        onClick={() => removeChannel(idx)}
                        title={lc.remove}
                      >
                        <Trash2 size={14} />
                      </button>
                    </div>
                  </div>

                  {renderChannelFields(channel, idx)}
                </div>
              ))}
            </div>

            <div className="row-between">
              <select className="select" value={newChannelType} onChange={(e) => setNewChannelType(e.target.value as ChannelType)} disabled={addableChannelTypes.length === 0}>
                {addableChannelTypes.map((t) => (
                  <option key={t} value={t}>{t}</option>
                ))}
              </select>
              <button className="btn btn-secondary btn-sm icon-btn" disabled={addableChannelTypes.length === 0} onClick={addChannel} title={lc.addChannel} aria-label={lc.addChannel}>
                <Plus size={14} />
              </button>
            </div>
            <div className="row-between">
              <span className="field-label">{lc.wizardSectionDesc}</span>
              <button className="btn btn-primary" onClick={() => setShowChannelModal(false)}>{lc.close}</button>
            </div>
          </div>
        </div>
      )}

      {showToolsConfigModal && (
        <div className="modal-mask" onClick={() => setShowToolsConfigModal(false)}>
          <div className="modal-card modal-wide" onClick={(e) => e.stopPropagation()}>
            <h3>{ui.toolsSectionTitle}</h3>
            <div className="field-label" style={{ marginBottom: 8 }}>{ui.envParamsDesc}</div>
            <div className="wizard-channel-list">
              {envEntries.length === 0 ? (
                <div className="ops-empty-inline">{ui.noEnvParams}</div>
              ) : (
                envEntries.map(([key, value]) => (
                  <div key={key} className="card wizard-channel-card wizard-channel-compact">
                    <div className="row-between" style={{ alignItems: 'center', gap: 8 }}>
                      <input
                        className="input mono"
                        value={key}
                        readOnly
                        style={{ maxWidth: 280 }}
                      />
                      <input
                        className="input"
                        type={envVisibleByKey[key] ? 'text' : 'password'}
                        value={value}
                        onChange={(e) => upsertEnvParam(key, e.target.value)}
                        placeholder={ui.envValue}
                      />
                      <button
                        className="btn btn-secondary btn-sm wizard-icon-btn"
                        onClick={() => setEnvVisibleByKey((prev) => ({ ...prev, [key]: !prev[key] }))}
                        title={envVisibleByKey[key] ? ui.hideEnvValue : ui.showEnvValue}
                        aria-label={envVisibleByKey[key] ? ui.hideEnvValue : ui.showEnvValue}
                      >
                        {envVisibleByKey[key] ? <EyeOff size={14} /> : <Eye size={14} />}
                      </button>
                      <button
                        className="btn btn-danger btn-sm wizard-icon-btn"
                        onClick={() => removeEnvParam(key)}
                        title={ui.removeEnvParam}
                      >
                        <Trash2 size={14} />
                      </button>
                    </div>
                  </div>
                ))
              )}
            </div>
            <div className="row-between">
              <input
                className="input mono"
                value={envDraftKey}
                onChange={(e) => setEnvDraftKey(e.target.value.toUpperCase())}
                placeholder={ui.envKey}
              />
              <input
                className="input"
                type={envDraftVisible ? 'text' : 'password'}
                value={envDraftValue}
                onChange={(e) => setEnvDraftValue(e.target.value)}
                placeholder={ui.envValue}
              />
              <button
                className="btn btn-secondary btn-sm icon-btn"
                onClick={() => setEnvDraftVisible((v) => !v)}
                title={envDraftVisible ? ui.hideEnvValue : ui.showEnvValue}
                aria-label={envDraftVisible ? ui.hideEnvValue : ui.showEnvValue}
              >
                {envDraftVisible ? <EyeOff size={14} /> : <Eye size={14} />}
              </button>
              <button
                className="btn btn-secondary btn-sm icon-btn"
                onClick={() => {
                  const key = String(envDraftKey || '').trim().toUpperCase();
                  if (!key) return;
                  upsertEnvParam(key, envDraftValue);
                  setEnvDraftKey('');
                  setEnvDraftValue('');
                }}
                title={ui.addEnvParam}
                aria-label={ui.addEnvParam}
              >
                <Plus size={14} />
              </button>
            </div>
            <div className="row-between">
              <span className="field-label">{ui.toolsDesc}</span>
              <button className="btn btn-primary" onClick={() => setShowToolsConfigModal(false)}>{lc.close}</button>
            </div>
          </div>
        </div>
      )}

      <div className="row-between">
        <button className="btn btn-secondary" disabled={step === 1 || isSubmitting} onClick={() => setStep((s) => Math.max(1, s - 1))}>{ui.prev}</button>
        {step < 4 ? (
          <button className="btn btn-primary" onClick={() => void next()}>{ui.next}</button>
        ) : (
          <button className="btn btn-primary" disabled={isSubmitting} onClick={() => void createBot()}>{isSubmitting ? ui.creating : ui.finish}</button>
        )}
      </div>
    </section>
  );
}
