import React, { useEffect, useMemo, useState } from 'react';

import useStudioStore from '../../Store/Studio/StudioSlice';
import FieldLabel from './edit/FieldLabel';
import VariableChips from './edit/VariableChips';
import {
  DEFAULT_THINKING_PROMPT,
  orderNodesByIds,
  sortNodesByLogic,
} from './edit/variableUtils';
import WorldbookInsertion from './edit/WorldbookInsertion';
import ScoringDimensions from './edit/ScoringDimensions';

import './StudioEditPage.css';

/*
 * Node detail layout: primary config center + secondary fixed edge rail.
 * Industry refs: n8n (Parameters center + Settings sidebar), Retool inspector,
 * Figma right properties rail — main editing in fluid center, refs in ~300px rail.
 */

const DEFAULT_TEMPLATE_ID = 'builtin.studio.example';

const WORKFLOW_GOAL_TIP =
  '此内容会在运行时被注入到 LLM 系统提示中，作为工作流整体目标，供各步骤参考。';

const WORKFLOW_DESC_TIP =
  '仅供人类阅读的简短说明，不会写入 LLM 提示。';

const NODE_SORT_STORAGE_KEY = 'studio-node-sort-mode';

function getStoredSortMode(projectId) {
  if (!projectId || typeof sessionStorage === 'undefined') return 'manual';
  return sessionStorage.getItem(`${NODE_SORT_STORAGE_KEY}:${projectId}`) || 'manual';
}

function storeSortMode(projectId, mode) {
  if (!projectId || typeof sessionStorage === 'undefined') return;
  sessionStorage.setItem(`${NODE_SORT_STORAGE_KEY}:${projectId}`, mode);
}
function getSkillTemplate(skillTemplates, skillId) {
  return skillTemplates.find((t) => t.skillId === skillId);
}

function StudioEditPage() {
  const {
    projects,
    workflowTemplates,
    currentProjectId,
    meta,
    pipeline,
    skillTemplates,
    selectedNodeId,
    loading,
    saving,
    error,
    saveMessage,
    setPipelineLocal,
    setMetaLocal,
    setSelectedNodeId,
    updateNode,
    updateNodeConfig,
    addNode,
    removeNode,
    fetchProject,
    savePipeline,
    createProject,
    deleteProject,
    renameProject,
    updateProjectMeta,
    clearSaveMessage,
  } = useStudioStore();

  const [dragIndex, setDragIndex] = useState(null);
  const [showAddNode, setShowAddNode] = useState(false);
  const [showNewProjectModal, setShowNewProjectModal] = useState(false);
  const [showRenameProjectModal, setShowRenameProjectModal] = useState(false);
  const [newNodeSkillId, setNewNodeSkillId] = useState('studio.worldbook_entry');
  const [newNodeName, setNewNodeName] = useState('');
  const [newProjectName, setNewProjectName] = useState('');
  const [newProjectTemplateId, setNewProjectTemplateId] = useState(DEFAULT_TEMPLATE_ID);
  const [renameProjectName, setRenameProjectName] = useState('');
  const [nodeSortMode, setNodeSortMode] = useState('manual');
  const [manualOrder, setManualOrder] = useState([]);

  useEffect(() => {
    if (!currentProjectId) return;
    setNodeSortMode(getStoredSortMode(currentProjectId));
  }, [currentProjectId]);

  useEffect(() => {
    if (!pipeline?.nodes) {
      setManualOrder([]);
      return;
    }
    setManualOrder(pipeline.nodes.map((n) => n.id));
  }, [currentProjectId, pipeline?.nodes?.length]);

  const displayNodes = useMemo(() => {
    const nodes = pipeline?.nodes || [];
    if (nodeSortMode === 'logic') {
      return sortNodesByLogic(pipeline);
    }
    return orderNodesByIds(nodes, manualOrder);
  }, [pipeline, nodeSortMode, manualOrder]);

  const handleSortModeChange = (mode) => {
    setNodeSortMode(mode);
    if (currentProjectId) storeSortMode(currentProjectId, mode);
    if (mode === 'manual' && pipeline?.nodes) {
      setManualOrder(pipeline.nodes.map((n) => n.id));
    }
  };
  const selectedNode = pipeline?.nodes?.find((n) => n.id === selectedNodeId) ?? null;
  const selectedTpl = selectedNode
    ? getSkillTemplate(skillTemplates, selectedNode.skillId)
    : null;
  const isWorldbook = selectedNode?.skillId === 'studio.worldbook_entry';
  const insertion = selectedNode?.config?.insertion || {};
  const scoring = selectedNode?.config?.scoring || { enabled: true, dimensions: [] };
  const dimensions = scoring.dimensions || [];

  const templateOptions =
    workflowTemplates.length > 0
      ? workflowTemplates
      : [{ id: DEFAULT_TEMPLATE_ID, name: '世界书条目创建' }];

  const handleProjectChange = async (e) => {
    const id = e.target.value;
    if (id) await fetchProject(id);
  };

  const openNewProjectModal = () => {
    setNewProjectName('');
    setNewProjectTemplateId(templateOptions[0]?.id || DEFAULT_TEMPLATE_ID);
    setShowNewProjectModal(true);
  };

  const openRenameProjectModal = () => {
    setRenameProjectName(meta?.name || '');
    setShowRenameProjectModal(true);
  };

  const handleCreateProject = async (e) => {
    e.preventDefault();
    const name = newProjectName.trim() || '新项目';
    const result = await createProject(name, newProjectTemplateId);
    if (result) {
      setShowNewProjectModal(false);
      setNewProjectName('');
    }
  };

  const handleRenameProject = async (e) => {
    e.preventDefault();
    if (!currentProjectId) return;
    const name = renameProjectName.trim();
    if (!name) return;
    const result = await renameProject(currentProjectId, name);
    if (result) {
      setShowRenameProjectModal(false);
    }
  };

  const handleDeleteProject = async () => {
    if (!currentProjectId || !meta) return;
    const confirmed = window.confirm(
      `确定删除项目「${meta.name}」？\n\n将同时删除该项目下的所有运行记录，此操作不可撤销。`
    );
    if (!confirmed) return;
    await deleteProject(currentProjectId);
  };

  const handleDescriptionBlur = () => {
    if (!currentProjectId || !meta) return;
    updateProjectMeta(currentProjectId, { description: meta.description ?? '' });
  };

  const handleDragStart = (index) => {
    if (nodeSortMode !== 'manual') return;
    setDragIndex(index);
  };

  const handleDragOver = (e, index) => {
    if (nodeSortMode !== 'manual') return;
    e.preventDefault();
    if (dragIndex === null || dragIndex === index) return;

    const ids = displayNodes.map((n) => n.id);
    const nextIds = [...ids];
    const [moved] = nextIds.splice(dragIndex, 1);
    nextIds.splice(index, 0, moved);

    const nodeMap = Object.fromEntries((pipeline.nodes || []).map((n) => [n.id, n]));
    const reordered = nextIds.map((id) => nodeMap[id]).filter(Boolean);
    setPipelineLocal({ ...pipeline, nodes: reordered });
    setManualOrder(nextIds);
    setDragIndex(index);
  };
  const handleDragEnd = () => setDragIndex(null);

  const toggleInputRef = (nodeId, ref, label) => {
    const node = pipeline.nodes.find((n) => n.id === nodeId);
    if (!node) return;
    const exists = (node.inputs || []).some((i) => i.ref === ref);
    let inputs;
    if (exists) {
      inputs = (node.inputs || []).filter((i) => i.ref !== ref);
    } else {
      inputs = [...(node.inputs || []), { ref, label }];
    }
    updateNode(nodeId, { inputs });
  };

  const updateInsertion = (field, value) => {
    if (!selectedNode) return;
    const next = { ...(selectedNode.config?.insertion || {}), [field]: value };
    updateNodeConfig(selectedNode.id, { insertion: next });
  };

  const updateRagConfig = (field, value) => {
    if (!selectedNode) return;
    const ragConfig = {
      ...(insertion.ragConfig || {}),
      [field]: value,
    };
    updateInsertion('ragConfig', ragConfig);
  };

  const updateScoring = (field, value) => {
    if (!selectedNode) return;
    const next = { ...(selectedNode.config?.scoring || {}), [field]: value };
    updateNodeConfig(selectedNode.id, { scoring: next });
  };

  const addDimension = () => {
    const id = `dim-${Date.now()}`;
    updateScoring('dimensions', [
      ...dimensions,
      { id, name: '', criteria: '' },
    ]);
  };

  const updateDimension = (index, field, value) => {
    const next = dimensions.map((d, i) =>
      i === index ? { ...d, [field]: value } : d
    );
    updateScoring('dimensions', next);
  };

  const removeDimension = (index) => {
    updateScoring(
      'dimensions',
      dimensions.filter((_, i) => i !== index)
    );
  };

  if (loading && !pipeline) {
    return <div className="studio-edit-loading">加载中…</div>;
  }

  return (
    <div className="studio-edit-page">
      <header className="studio-edit-top">
        <div className="studio-edit-top__label studio-edit-top__label--project">
          <span className="studio-edit-top__label-text">项目</span>
        </div>
        <div className="studio-edit-top__label studio-edit-top__label--goal">
          <FieldLabel tip={WORKFLOW_GOAL_TIP}>工作流目标</FieldLabel>
        </div>
        <div className="studio-edit-top__label studio-edit-top__label--desc">
          <FieldLabel tip={WORKFLOW_DESC_TIP}>工作流简介</FieldLabel>
        </div>

        <div className="studio-edit-top__control studio-edit-top__control--project">
          <select
            className="studio-edit-select studio-edit-select--project"
            value={currentProjectId || ''}
            onChange={handleProjectChange}
            aria-label="选择项目"
          >
            {projects.length === 0 && <option value="">无项目</option>}
            {projects.map((p) => (
              <option key={p.id} value={p.id}>
                {p.name}
              </option>
            ))}
          </select>
          <div className="studio-edit-top__actions">
            <button
              type="button"
              className="studio-edit-btn studio-edit-btn-danger studio-edit-btn-sm"
              onClick={handleDeleteProject}
              disabled={!currentProjectId || loading || saving}
              title="删除当前项目及其运行记录"
            >
              删除项目
            </button>
            <button
              type="button"
              className="studio-edit-btn studio-edit-btn-sm"
              onClick={openRenameProjectModal}
              disabled={!currentProjectId || loading || saving}
            >
              改名
            </button>
            <button
              type="button"
              className="studio-edit-btn studio-edit-btn-sm"
              onClick={openNewProjectModal}
              disabled={loading}
            >
              新建项目
            </button>
          </div>
        </div>
        <div className="studio-edit-top__control studio-edit-top__control--goal">
          <textarea
            className="studio-edit-textarea studio-edit-textarea--goal"
            rows={2}
            value={pipeline?.workflowGoal ?? ''}
            onChange={(e) =>
              setPipelineLocal({ ...pipeline, workflowGoal: e.target.value })
            }
            placeholder="描述本 Studio 项目要完成的整体设计目标…"
            aria-label="工作流目标"
          />
        </div>
        <div className="studio-edit-top__control studio-edit-top__control--desc">
          <input
            type="text"
            className="studio-edit-input studio-edit-input--desc"
            value={meta?.description ?? ''}
            onChange={(e) => setMetaLocal({ description: e.target.value })}
            onBlur={handleDescriptionBlur}
            placeholder="简短备注"
            maxLength={120}
            disabled={!currentProjectId || saving}
            aria-label="工作流简介"
          />
        </div>

      </header>
      {(error || saveMessage) && (
        <div
          className={`studio-edit-banner ${error ? 'error' : 'success'}`}
          role="status"
        >
          {error || saveMessage}
          <button type="button" className="studio-edit-banner-close" onClick={clearSaveMessage}>
            ×
          </button>
        </div>
      )}

      <div className="studio-edit-main">
        <aside className="studio-edit-nodes">
          <div className="studio-edit-nodes-header">
            <h2 className="studio-edit-subtitle">节点列表</h2>
            <div className="studio-edit-nodes-header__actions">
              <div className="studio-edit-sort-toggle" role="group" aria-label="节点排序">
                <button
                  type="button"
                  className={`studio-edit-sort-btn${nodeSortMode === 'manual' ? ' active' : ''}`}
                  onClick={() => handleSortModeChange('manual')}
                  title="按拖拽/保存顺序排列"
                >
                  手动
                </button>
                <button
                  type="button"
                  className={`studio-edit-sort-btn${nodeSortMode === 'logic' ? ' active' : ''}`}
                  onClick={() => handleSortModeChange('logic')}
                  title="按引用依赖拓扑排序"
                >
                  逻辑
                </button>
              </div>
              <button
                type="button"
                className="studio-edit-btn studio-edit-btn-sm"
                onClick={() => setShowAddNode(!showAddNode)}
              >
                添加节点
              </button>
            </div>
          </div>
          {showAddNode && (
            <div className="studio-edit-add-node">
              <select
                className="studio-edit-select"
                value={newNodeSkillId}
                onChange={(e) => setNewNodeSkillId(e.target.value)}
              >
                {skillTemplates.map((t) => (
                  <option key={t.skillId} value={t.skillId}>
                    {t.displayName}
                  </option>
                ))}
              </select>
              <input
                type="text"
                className="studio-edit-input"
                placeholder="展示名"
                value={newNodeName}
                onChange={(e) => setNewNodeName(e.target.value)}
              />
              <button
                type="button"
                className="studio-edit-btn studio-edit-btn-sm"
                onClick={() => {
                  addNode(
                    newNodeSkillId,
                    newNodeName ||
                      getSkillTemplate(skillTemplates, newNodeSkillId)?.displayName
                  );
                  setNewNodeName('');
                  setShowAddNode(false);
                }}
              >
                确认
              </button>
            </div>
          )}

          <ul className="studio-edit-node-list">
            {displayNodes.map((node, index) => {
              const tpl = getSkillTemplate(skillTemplates, node.skillId);
              const isManualSort = nodeSortMode === 'manual';
              return (
                <li
                  key={node.id}
                  className={`studio-edit-node-item ${
                    selectedNodeId === node.id ? 'selected' : ''
                  } ${!node.enabled ? 'disabled' : ''}${!isManualSort ? ' no-drag' : ''}`}
                  draggable={isManualSort}
                  onDragStart={() => handleDragStart(index)}
                  onDragOver={(e) => handleDragOver(e, index)}
                  onDragEnd={handleDragEnd}
                  onClick={() => setSelectedNodeId(node.id)}
                >
                  {isManualSort ? (
                    <span className="studio-edit-drag-handle" title="拖拽排序">
                      ⋮⋮
                    </span>
                  ) : (
                    <span className="studio-edit-drag-handle studio-edit-drag-handle--muted" title="逻辑排序模式下不可拖拽">
                      ↕
                    </span>
                  )}                  <div className="studio-edit-node-text">
                    <span className="studio-edit-node-title">{node.displayName}</span>
                    <span className="studio-edit-node-skill">
                      {tpl?.displayName || node.skillId}
                    </span>
                  </div>
                  <label
                    className="studio-edit-switch"
                    onClick={(e) => e.stopPropagation()}
                  >
                    <input
                      type="checkbox"
                      checked={node.enabled}
                      onChange={(e) =>
                        updateNode(node.id, { enabled: e.target.checked })
                      }
                    />
                    <span>启用</span>
                  </label>
                </li>
              );
            })}
          </ul>
        </aside>

        <section className="studio-edit-detail">
          {!selectedNode ? (
            <p className="studio-edit-empty">选择左侧节点进行编辑</p>
          ) : (
            <div className="studio-edit-detail-inner">
              <div className="studio-edit-meta-strip">
                <label className="studio-edit-meta-strip__field">
                  <span className="studio-edit-field-label">展示名</span>
                  <input
                    type="text"
                    className="studio-edit-input"
                    value={selectedNode.displayName}
                    onChange={(e) =>
                      updateNode(selectedNode.id, { displayName: e.target.value })
                    }
                  />
                </label>
                <label className="studio-edit-meta-strip__field">
                  <span className="studio-edit-field-label">模板类型</span>
                  <input
                    type="text"
                    className="studio-edit-input"
                    readOnly
                    value={selectedTpl?.displayName || selectedNode.skillId}
                  />
                </label>
                {selectedTpl?.artifacts?.length > 0 && (
                  <span className="studio-edit-meta-strip__hint">
                    产物：
                    {selectedTpl.artifacts.map((a) => a.displayName).join('、')}
                  </span>
                )}
              </div>

              <div className="studio-edit-detail-body">
                <div className="studio-edit-primary">
                  <div className="studio-edit-primary-card">
                    <span className="studio-edit-primary-card__badge">主要设置</span>

                    {isWorldbook ? (
                      <>
                        <label className="studio-edit-field studio-edit-field--primary">
                          <span className="studio-edit-field-label studio-edit-field-label--primary">
                            <FieldLabel tip="本步骤要产出的内容目标，会注入模型系统提示">
                              步骤目标
                            </FieldLabel>
                          </span>
                          <textarea
                            className="studio-edit-textarea studio-edit-textarea--primary"
                            rows={5}
                            value={selectedNode.config?.stepGoal ?? ''}
                            onChange={(e) =>
                              updateNodeConfig(selectedNode.id, {
                                stepGoal: e.target.value,
                              })
                            }
                            placeholder="描述本步骤要产出的内容…"
                          />
                        </label>

                        <label className="studio-edit-field studio-edit-field--primary">
                          <span className="studio-edit-field-label studio-edit-field-label--primary">
                            <FieldLabel tip="引导模型在本步骤中的思考方式、关注点与推理路径">
                              思考提示词
                            </FieldLabel>
                          </span>
                          <textarea
                            className="studio-edit-textarea studio-edit-textarea--primary"
                            rows={5}
                            value={selectedNode.config?.thinkingPrompt ?? ''}
                            onChange={(e) =>
                              updateNodeConfig(selectedNode.id, {
                                thinkingPrompt: e.target.value,
                              })
                            }
                            placeholder="引导模型如何思考本步骤…"
                          />
                          {!selectedNode.config?.thinkingPrompt && (
                            <button
                              type="button"
                              className="studio-edit-btn studio-edit-btn-sm studio-edit-think-default"
                              onClick={() =>
                                updateNodeConfig(selectedNode.id, {
                                  thinkingPrompt: DEFAULT_THINKING_PROMPT,
                                })
                              }
                            >
                              填入默认思考流程模板
                            </button>
                          )}
                        </label>

                        <ScoringDimensions
                          scoring={scoring}
                          dimensions={dimensions}
                          onUpdateScoring={updateScoring}
                          onUpdateDimension={updateDimension}
                          onRemoveDimension={removeDimension}
                          onAddDimension={addDimension}
                        />
                      </>
                    ) : selectedNode.skillId === 'studio.init_bind' ? (
                      <>
                        <p className="studio-edit-hint">
                          运行时在引导区填写；编辑页可预览字段定义。
                        </p>
                        <ul className="studio-edit-dp-list studio-edit-dp-list--compact">
                          {(selectedNode.displayParams || []).map((dp) => (
                            <li key={dp.key}>
                              {dp.label} ({dp.key})
                              {dp.required ? ' · 必填' : ''}
                            </li>
                          ))}
                        </ul>
                      </>
                    ) : null}
                  </div>
                </div>

                <aside className="studio-edit-edge-rail">
                  {isWorldbook ? (
                    <>
                      <div className="studio-edit-edge-card">
                        <VariableChips
                          variant="compact"
                          pipeline={pipeline}
                          selectedNode={selectedNode}
                          onToggleRef={(ref, label) =>
                            toggleInputRef(selectedNode.id, ref, label)
                          }
                        />
                      </div>
                      <div className="studio-edit-edge-card">
                        <WorldbookInsertion
                          insertion={insertion}
                          onUpdateInsertion={updateInsertion}
                          onUpdateRagConfig={updateRagConfig}
                        />
                      </div>
                    </>
                  ) : (
                    <div className="studio-edit-edge-card studio-edit-edge-card--empty">
                      <p className="studio-edit-edge-empty-tip">创建步骤无需引用变量</p>
                    </div>
                  )}
                </aside>
              </div>

              <div className="studio-edit-detail-footer">
                <button
                  type="button"
                  className="studio-edit-btn studio-edit-btn-danger"
                  onClick={() => {
                    if (window.confirm(`删除节点「${selectedNode.displayName}」？`)) {
                      removeNode(selectedNode.id);
                    }
                  }}
                >
                  删除节点
                </button>
                <button
                  type="button"
                  className="studio-edit-btn studio-edit-btn-primary"
                  onClick={savePipeline}
                  disabled={saving || !currentProjectId}
                >
                  {saving ? '保存中…' : '保存'}
                </button>
              </div>
            </div>
          )}
        </section>
      </div>

      {showNewProjectModal && (
        <div
          className="studio-modal-overlay"
          role="presentation"
          onClick={() => setShowNewProjectModal(false)}
        >
          <div
            className="studio-modal"
            role="dialog"
            aria-labelledby="new-project-title"
            onClick={(e) => e.stopPropagation()}
          >
            <h2 id="new-project-title" className="studio-modal-title">
              新建项目
            </h2>
            <form onSubmit={handleCreateProject}>
              <label className="studio-edit-label-block">
                项目名称
                <input
                  type="text"
                  className="studio-edit-input"
                  value={newProjectName}
                  onChange={(e) => setNewProjectName(e.target.value)}
                  placeholder="例如：帝国骑士维尔"
                  autoFocus
                  required
                />
              </label>
              <label className="studio-edit-label-block">
                选择工作流模板
                <select
                  className="studio-edit-select"
                  value={newProjectTemplateId}
                  onChange={(e) => setNewProjectTemplateId(e.target.value)}
                >
                  {templateOptions.map((t) => (
                    <option key={t.id} value={t.id}>
                      {t.name}
                    </option>
                  ))}
                </select>
              </label>
              <div className="studio-modal-actions">
                <button
                  type="button"
                  className="studio-edit-btn"
                  onClick={() => setShowNewProjectModal(false)}
                >
                  取消
                </button>
                <button
                  type="submit"
                  className="studio-edit-btn studio-edit-btn-primary"
                  disabled={loading}
                >
                  {loading ? '创建中…' : '创建'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      {showRenameProjectModal && (
        <div
          className="studio-modal-overlay"
          role="presentation"
          onClick={() => setShowRenameProjectModal(false)}
        >
          <div
            className="studio-modal"
            role="dialog"
            aria-labelledby="rename-project-title"
            onClick={(e) => e.stopPropagation()}
          >
            <h2 id="rename-project-title" className="studio-modal-title">
              改名
            </h2>
            <form onSubmit={handleRenameProject}>
              <label className="studio-edit-label-block">
                项目名称
                <input
                  type="text"
                  className="studio-edit-input"
                  value={renameProjectName}
                  onChange={(e) => setRenameProjectName(e.target.value)}
                  autoFocus
                  required
                  maxLength={120}
                />
              </label>
              <div className="studio-modal-actions">
                <button
                  type="button"
                  className="studio-edit-btn"
                  onClick={() => setShowRenameProjectModal(false)}
                >
                  取消
                </button>
                <button
                  type="submit"
                  className="studio-edit-btn studio-edit-btn-primary"
                  disabled={saving}
                >
                  {saving ? '保存中…' : '确定'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

export default StudioEditPage;
