import type {
  ScheduledConditionRecord,
  ScheduledConditionStatus,
  ScheduledConditionTaskId
} from "../types";

export type RunningWorkflowStepDefinition = {
  id: string;
  title: string;
  detail: string;
};

export type RunningWorkflowDefinition = {
  title: string;
  reportLabel: string;
  steps: RunningWorkflowStepDefinition[];
};

export type RunningWorkflowStepStatus = "done" | "current" | "pending";

export const runningWorkflowDefinitions: Record<ScheduledConditionTaskId, RunningWorkflowDefinition> = {
  "scada-diagnosis": {
    title: "SCADA 诊断流程",
    reportLabel: "生成诊断报告",
    steps: [
      {
        id: "ingest-telemetry",
        title: "读取 SCADA 遥测",
        detail: "拉取压力、流量和关键阀门测点，校验时间戳与回传频率。"
      },
      {
        id: "freshness-check",
        title: "检查新鲜度完整率",
        detail: "按测点组计算缺测、延迟和连续异常样本比例。"
      },
      {
        id: "consistency-check",
        title: "压流一致性诊断",
        detail: "比对压力变化、流量变化和相邻测点趋势是否符合水力逻辑。"
      },
      {
        id: "isolate-sources",
        title: "标记异常数据源",
        detail: "圈定疑似通信异常或越界测点，给后续模拟和调度提供屏蔽建议。"
      },
      {
        id: "diagnosis-report",
        title: "整理诊断结论",
        detail: "汇总数据质量、异常证据和是否允许进入后续工况任务。"
      }
    ]
  },
  "smart-dispatch": {
    title: "智能调度流程",
    reportLabel: "生成调度指令",
    steps: [
      {
        id: "read-condition",
        title: "读取实时工况",
        detail: "汇总目标分区压力、流量、泵站出水和阀门开度。"
      },
      {
        id: "candidate-actions",
        title: "生成候选动作",
        detail: "枚举泵站目标压力、阀门边界和高频复核测点的可执行动作。"
      },
      {
        id: "simulate-impact",
        title: "模拟影响范围",
        detail: "预估指令执行后的压力改善、分区压差和关键用户影响。"
      },
      {
        id: "rank-actions",
        title: "排序调度方案",
        detail: "按改善幅度、操作代价和数据可信度筛选建议指令。"
      },
      {
        id: "dispatch-draft",
        title: "形成复核清单",
        detail: "输出待调度员确认的管网要素调整指令和复核条件。"
      }
    ]
  },
  "network-simulation": {
    title: "定时模拟流程",
    reportLabel: "生成模拟报告",
    steps: [
      {
        id: "sync-boundary",
        title: "同步模型边界",
        detail: "读取最新泵站启停、阀门开度、需水量和 SCADA 边界条件。"
      },
      {
        id: "run-hydraulic-model",
        title: "运行水力模型",
        detail: "滚动计算全网节点压力、管段流量和分区边界平衡。"
      },
      {
        id: "compare-telemetry",
        title: "比对实测偏差",
        detail: "将模拟压力、流量与在线测点回传值进行偏差校验。"
      },
      {
        id: "locate-deviation",
        title: "定位偏差来源",
        detail: "识别模型参数、边界条件或遥测源导致的主要偏差区域。"
      },
      {
        id: "simulation-report",
        title: "输出模型复核",
        detail: "给出可信度、关注指标和是否允许用于调度决策。"
      }
    ]
  },
  "pump-energy": {
    title: "泵站能耗流程",
    reportLabel: "生成能耗报告",
    steps: [
      {
        id: "read-pump-load",
        title: "读取泵组负载",
        detail: "采集泵站频率、电流、出水压力、出水量和启停记录。"
      },
      {
        id: "calculate-energy",
        title: "计算单位电耗",
        detail: "按当前窗口供水量折算单位供水电耗和效率偏差。"
      },
      {
        id: "compare-efficiency",
        title: "比对经济区间",
        detail: "结合泵组效率曲线判断当前组合是否处于低效并联区间。"
      },
      {
        id: "pressure-guard",
        title: "校验供压约束",
        detail: "复核节能建议不会引发末端低压或分区边界异常。"
      },
      {
        id: "energy-advice",
        title: "形成节能建议",
        detail: "输出启停优化、压力设定和继续观察条件。"
      }
    ]
  }
};

export function getRunningWorkflowDefinition(condition: ScheduledConditionRecord) {
  return runningWorkflowDefinitions[condition.taskId];
}

export function getRunningWorkflowState(
  condition: ScheduledConditionRecord,
  workflow: RunningWorkflowDefinition,
  nowMs: number
) {
  if (condition.status !== "running") {
    return { currentStepIndex: workflow.steps.length - 1, progress: getCompletedProgress(condition.status) };
  }

  const scheduledAtMs = Date.parse(condition.scheduledAt);
  const startedAtMs = Number.isFinite(scheduledAtMs) ? scheduledAtMs : nowMs;
  const durationMs = Math.max(condition.durationMinutes ?? 1, 1) * 60_000;
  const elapsedMs = Math.max(0, nowMs - startedAtMs);
  const rawRatio = elapsedMs / durationMs;
  const runningRatio = Math.min(Math.max(rawRatio, 0), 0.999);
  const currentStepIndex = Math.min(
    workflow.steps.length - 1,
    Math.floor(runningRatio * workflow.steps.length)
  );
  const progress = Math.min(99, Math.max(0, Math.floor(runningRatio * 100)));

  return { currentStepIndex, progress };
}

export function getWorkflowStepStatus(
  condition: ScheduledConditionRecord,
  stepIndex: number,
  currentStepIndex: number
): RunningWorkflowStepStatus {
  if (condition.status !== "running") {
    return "done";
  }

  if (stepIndex < currentStepIndex) {
    return "done";
  }

  if (stepIndex === currentStepIndex) {
    return "current";
  }

  return "pending";
}

function getCompletedProgress(status: ScheduledConditionStatus) {
  if (status === "error") {
    return 0;
  }

  return 100;
}
