import { useState, useEffect, useCallback, useRef } from 'react';
import GlassCard from '@/components/digital/GlassCard';
import CardTitleBar from '@/components/digital/CardTitleBar';
import MissionCard from '@/components/digital/MissionCard';
import FlowDetailPanel from '@/components/digital/FlowDetailPanel';
import { adaptMissions, type Mission } from '@/lib/consoleDataAdapter';
import { getDebugPlans, governanceCommand, searchDebugPlans } from '@/lib/api';
import type { GovernanceCommandKind, GovernanceCommandResponse } from '@/types/api';
import { t } from '@/lib/i18n';
import {
  completeDemoMissionOnce,
  getDemoMissions,
  runDemoMissionOnce,
} from './demoScenario';
import { domSafeId } from './navigation';

const REQUIRED_MISSION_IDS = [
  'qimingclaw-client-readiness',
  'qimingclaw-remote-task-ingress',
  'qimingclaw-daily-report',
];

const DELEGATION_FILTERS = [
  { key: 'all', label: '全部委托' },
  { key: 'daily', label: '日常任务' },
  { key: 'weekly', label: '周任务' },
  { key: 'monthly', label: '月度任务' },
  { key: 'adhoc', label: '临时任务' },
];

type MissionNotice = {
  kind: 'selected' | 'created' | 'dispatched';
  missionId: string;
  title: string;
  planId?: string;
};

function planSortTime(plan: Record<string, unknown>): number {
  const value = typeof plan.updated_at === 'string'
    ? plan.updated_at
    : typeof plan.created_at === 'string'
      ? plan.created_at
      : '';
  const time = value ? new Date(value).getTime() : 0;
  return Number.isFinite(time) ? time : 0;
}

function dateKey(value?: string | null): string {
  if (!value) return '';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '';
  return [
    date.getFullYear(),
    String(date.getMonth() + 1).padStart(2, '0'),
    String(date.getDate()).padStart(2, '0'),
  ].join('-');
}

function todayDateKey(): string {
  return dateKey(new Date().toISOString());
}

function shiftDateKey(value: string, days: number): string {
  const date = value ? new Date(`${value}T12:00:00`) : new Date();
  if (Number.isNaN(date.getTime())) return todayDateKey();
  date.setDate(date.getDate() + days);
  return dateKey(date.toISOString());
}

function plannedClockFromMission(mission: Mission): { text: string; minutes: number } | null {
  const match = `${mission.title} ${mission.id}`.match(/(?:^|\D)(\d{1,2})[:：](\d{2})(?:\D|$)/);
  if (!match) return null;
  const hour = Number(match[1]);
  const minute = Number(match[2]);
  if (!Number.isInteger(hour) || !Number.isInteger(minute) || hour > 23 || minute > 59) return null;
  return {
    text: `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`,
    minutes: hour * 60 + minute,
  };
}

function missionTaskTimes(mission: Mission): string[] {
  return mission.steps.flatMap((step) => (
    step.tasks.flatMap((task) => [task.startedAt, task.finishedAt])
  )).filter((value): value is string => Boolean(value));
}

function missionMatchesDate(mission: Mission, selectedDate: string): boolean {
  const taskDates = missionTaskTimes(mission).map(dateKey).filter(Boolean);
  if (taskDates.includes(selectedDate)) return true;
  if (plannedClockFromMission(mission)) return true;
  return [mission.updatedAt, mission.createdAt].map(dateKey).includes(selectedDate);
}

function missionDateKey(mission: Mission): string {
  const planned = plannedClockFromMission(mission);
  if (!planned) return mission.id;
  return `${mission.title}`.trim().toLowerCase() || mission.id;
}

function missionHasActualWorkOnDate(mission: Mission, selectedDate: string): boolean {
  return missionTaskTimes(mission).some((value) => dateKey(value) === selectedDate);
}

function missionDedupScore(mission: Mission, selectedDate: string): number {
  const actualScore = missionHasActualWorkOnDate(mission, selectedDate) ? 10_000 : 0;
  const requiredScore = REQUIRED_MISSION_IDS.includes(mission.id) ? 1_000 : 0;
  const selectedSyncScore = [mission.updatedAt, mission.createdAt].map(dateKey).includes(selectedDate) ? 100 : 0;
  return actualScore + requiredScore + selectedSyncScore + planSortTime({
    updated_at: mission.updatedAt || '',
    created_at: mission.createdAt || '',
  }) / 10_000_000_000_000;
}

function dedupeMissionsForDate(missions: Mission[], selectedDate: string): Mission[] {
  const byKey = new Map<string, Mission>();
  for (const mission of missions) {
    const key = missionDateKey(mission);
    const previous = byKey.get(key);
    if (!previous || missionDedupScore(mission, selectedDate) > missionDedupScore(previous, selectedDate)) {
      byKey.set(key, mission);
    }
  }
  return Array.from(byKey.values());
}

function missionDateSortValue(mission: Mission, selectedDate: string): number {
  const planned = plannedClockFromMission(mission);
  if (planned) return planned.minutes;
  const taskTimes = missionTaskTimes(mission)
    .filter((value) => dateKey(value) === selectedDate)
    .sort();
  if (taskTimes[0]) {
    const date = new Date(taskTimes[0]);
    return date.getHours() * 60 + date.getMinutes();
  }
  return 24 * 60;
}

function missionDelegationGroup(mission: Mission): string {
  const text = `${mission.id} ${mission.title} ${mission.objective}`.toLowerCase();
  if (text.includes('month') || text.includes('monthly') || text.includes('月')) return 'monthly';
  if (text.includes('week') || text.includes('weekly') || text.includes('周')) return 'weekly';
  if (text.includes('临时') || text.includes('adhoc') || text.includes('hotlist') || text.includes('monitor')) return 'adhoc';
  return 'daily';
}

async function sendMissionGovernanceCommand(
  commandKind: GovernanceCommandKind,
  contextRefs: Record<string, unknown>,
  payload: Record<string, unknown> = {},
): Promise<GovernanceCommandResponse> {
  const stamp = Date.now();
  const response = await governanceCommand({
    command_kind: commandKind,
    context_refs: contextRefs,
    payload: { source: 'digital-mission-center', ...payload },
    correlation_id: `mission-${commandKind}-${stamp}`,
    idempotency_key: `mission-${commandKind}-${Object.values(contextRefs).join('-') || 'new'}-${stamp}`,
  });
  if (!response.accepted) {
    throw new Error(response.message || `command 未被接受：${response.command_id || commandKind}`);
  }
  return response;
}

async function sendMissionPlanCommand(
  planId: string,
  commandKind: 'submit_plan' | 'approve_plan' | 'activate_plan' | 'amend_plan',
  payload: Record<string, unknown> = {},
): Promise<GovernanceCommandResponse> {
  return sendMissionGovernanceCommand(commandKind, { plan_id: planId }, payload);
}

async function dispatchMissionPlan(mission: Mission): Promise<string | null> {
  const planId = mission.sourceIds.planId;
  if (!planId) return null;
  const status = mission.status.toLowerCase();
  if (status === 'draft') {
    await sendMissionPlanCommand(planId, 'submit_plan', { requested_action: 'mission_dispatch' });
    await sendMissionPlanCommand(planId, 'approve_plan', { requested_action: 'mission_dispatch' });
  } else if (status === 'reviewing') {
    await sendMissionPlanCommand(planId, 'approve_plan', { requested_action: 'mission_dispatch' });
  } else if (!['approved', 'active', 'running'].includes(status)) {
    await sendMissionPlanCommand(planId, 'amend_plan', {
      requested_action: 'reopen_for_execution',
      summary: '数字员工任务中心请求重新执行任务',
    });
    return null;
  }
  await sendMissionPlanCommand(planId, 'activate_plan', { requested_action: 'mission_dispatch' });
  return planId;
}

function restartStepsForMission(mission: Mission) {
  const steps = mission.steps.map((step, index) => {
    const skills = new Set<string>();
    step.preferredSkills.forEach((skill) => {
      if (skill.trim()) skills.add(skill);
    });
    step.tasks.forEach((task) => {
      if (task.assignedSkillId?.trim()) skills.add(task.assignedSkillId);
    });
    const description = [
      step.description,
      ...step.tasks.map((task) => task.description),
      step.title,
      mission.objective,
      mission.title,
    ].find((value) => typeof value === 'string' && value.trim());
    return {
      title: step.title || `${mission.title} 第 ${index + 1} 步`,
      description: description || step.title || mission.objective || mission.title,
      skills: Array.from(skills),
      depends_on: index === 0 ? [] : [`step-${index}`],
    };
  }).filter((step) => step.skills.length > 0);

  if (steps.length === 0) {
    throw new Error('当前任务没有可复用的 skill，不能创建真实重新执行计划。');
  }
  return steps;
}

function restartMissionTitle(title: string): string {
  const base = title.replace(/(\s*重新执行)+$/u, '').trim();
  return `${base || title} 重新执行`;
}

async function createRestartPlan(mission: Mission): Promise<string> {
  const response = await sendMissionGovernanceCommand('create_plan', {
    session_id: 'digital-mission-center',
    plan_id: mission.sourceIds.planId || mission.id,
  }, {
    requested_action: 'mission_restart',
    title: restartMissionTitle(mission.title),
    description: mission.objective || mission.title,
    steps: restartStepsForMission(mission),
    original_plan_id: mission.sourceIds.planId || mission.id,
  });
  const planId = typeof response.result?.plan_id === 'string' ? response.result.plan_id : '';
  if (!planId) {
    throw new Error('重新执行计划已提交，但后端没有返回 plan_id。');
  }
  const status = typeof response.result?.status === 'string' ? response.result.status.toLowerCase() : '';
  if (status === 'draft') {
    await sendMissionPlanCommand(planId, 'submit_plan', { requested_action: 'mission_restart' });
    await sendMissionPlanCommand(planId, 'approve_plan', { requested_action: 'mission_restart' });
    await sendMissionPlanCommand(planId, 'activate_plan', { requested_action: 'mission_restart' });
  } else if (status === 'reviewing') {
    await sendMissionPlanCommand(planId, 'approve_plan', { requested_action: 'mission_restart' });
    await sendMissionPlanCommand(planId, 'activate_plan', { requested_action: 'mission_restart' });
  } else if (status === 'approved') {
    await sendMissionPlanCommand(planId, 'activate_plan', { requested_action: 'mission_restart' });
  }
  return planId;
}

export default function MissionCenter({
  focusMissionId,
  focusTaskId,
  focusDate,
}: {
  focusMissionId?: string | null;
  focusTaskId?: string | null;
  focusDate?: string | null;
}) {
  const initialMissionDate = focusDate || todayDateKey();
  const [missions, setMissions] = useState<Mission[]>([]);
  const [selected, setSelected] = useState<Mission | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [filter, setFilter] = useState<string>('all');
  const [dateFilter, setDateFilter] = useState<string>(() => initialMissionDate);
  const [showAllDates, setShowAllDates] = useState(false);
  const [runningMissionId, setRunningMissionId] = useState<string | null>(null);
  const [runningAll, setRunningAll] = useState(false);
  const [demoMode, setDemoMode] = useState(false);
  const [actionError, setActionError] = useState<string | null>(null);
  const [recentMissionId, setRecentMissionId] = useState<string | null>(null);
  const [missionNotice, setMissionNotice] = useState<MissionNotice | null>(null);
  const detailRef = useRef<HTMLDivElement | null>(null);

  const mountedRef = useRef(false);
  useEffect(() => {
    mountedRef.current = true;
    return () => { mountedRef.current = false; };
  }, []);

  const fetchMissions = useCallback(async (): Promise<Mission[]> => {
    setLoading(true); setError(false);
    try {
      const data = await getDebugPlans();
      if (!mountedRef.current) return [];
      const planMap = new Map<string, Record<string, unknown>>();
      const addPlan = (plan: Record<string, unknown>) => {
        const id = typeof plan.plan_id === 'string' ? plan.plan_id : '';
        if (id && !planMap.has(id)) planMap.set(id, plan);
      };
      (Array.isArray(data) ? data as Record<string, unknown>[] : []).forEach(addPlan);

      const missing = REQUIRED_MISSION_IDS.filter((id) => !planMap.has(id));
      if (missing.length > 0) {
        const extraResults = await Promise.allSettled(
          missing.map(async (id) => ({ id, plans: await searchDebugPlans(id, 20) })),
        );
        for (const result of extraResults) {
          if (result.status === 'fulfilled') {
            const exact = result.value.plans.find((plan) => plan.plan_id === result.value.id);
            if (exact) {
              addPlan(exact as Record<string, unknown>);
            }
          }
        }
      }

      const requiredPlans = REQUIRED_MISSION_IDS
        .map((id) => planMap.get(id))
        .filter((plan): plan is Record<string, unknown> => Boolean(plan));
      const recentPlans = [...planMap.entries()]
        .filter(([id]) => !REQUIRED_MISSION_IDS.includes(id))
        .map(([, plan]) => plan)
        .sort((a, b) => planSortTime(b) - planSortTime(a));
      const orderedPlans = [...recentPlans, ...requiredPlans];
      if (orderedPlans.length > 0) {
        const nextMissions = adaptMissions(orderedPlans);
        setDemoMode(false);
        setMissions(nextMissions);
        return nextMissions;
      } else {
        const demoMissions = getDemoMissions();
        setDemoMode(true);
        setMissions(demoMissions);
        return demoMissions;
      }
    } catch (err) {
      if (!mountedRef.current) return [];
      console.error('[MissionCenter] fetch failed:', err);
      const demoMissions = getDemoMissions();
      setDemoMode(true);
      setMissions(demoMissions);
      setError(false);
      return demoMissions;
    } finally {
      if (mountedRef.current) setLoading(false);
    }
  }, []);

  useEffect(() => { fetchMissions(); }, [fetchMissions]);

  useEffect(() => {
    setDateFilter(focusDate || todayDateKey());
    setShowAllDates(false);
  }, [focusDate]);

  const focusMission = useCallback((mission: Mission) => {
    setSelected(mission);
    setRecentMissionId(mission.id);
    window.setTimeout(() => {
      detailRef.current?.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });
    }, 40);
  }, []);

  const selectMission = useCallback((mission: Mission) => {
    focusMission(mission);
    setMissionNotice({
      kind: 'selected',
      missionId: mission.id,
      title: mission.title,
      planId: mission.sourceIds.planId,
    });
  }, [focusMission]);

  useEffect(() => {
    if (!focusMissionId && !focusTaskId) return;
    const matched = missions.find((mission) => (
      mission.id === focusMissionId
      || mission.sourceIds.planId === focusMissionId
      || (focusTaskId ? mission.sourceIds.taskIds.includes(focusTaskId) : false)
    ));
    if (!matched) return;
    setFilter('all');
    selectMission(matched);
    window.setTimeout(() => {
      document.getElementById(`mission-card-${domSafeId(matched.id)}`)?.scrollIntoView({
        block: 'center',
        behavior: 'smooth',
      });
    }, 80);
  }, [focusMissionId, focusTaskId, missions, selectMission]);

  const runMission = useCallback(async (mission: Mission) => {
    setRunningMissionId(mission.id);
    setError(false);
    setActionError(null);
    if (demoMode || !mission.sourceIds.planId) {
      setMissions((current) => runDemoMissionOnce(current, mission.id));
      setSelected((current) => {
        if (current?.id !== mission.id) return current;
        const next = runDemoMissionOnce([current], mission.id);
        return next[0] ?? current;
      });
      window.setTimeout(() => {
        if (!mountedRef.current) return;
        setMissions((current) => completeDemoMissionOnce(current, mission.id));
        setSelected((current) => {
          if (current?.id !== mission.id) return current;
          const next = completeDemoMissionOnce([current], mission.id);
          return next[0] ?? current;
        });
        setRunningMissionId(null);
      }, 1200);
      return;
    }
    try {
      const newPlanId = await dispatchMissionPlan(mission);
      const nextMissions = await fetchMissions();
      setFilter('all');
      if (newPlanId) {
      const selectedMission = nextMissions.find((item) => item.id === newPlanId || item.sourceIds.planId === newPlanId);
      if (selectedMission) {
        focusMission(selectedMission);
        setMissionNotice({
          kind: 'dispatched',
          missionId: selectedMission.id,
          title: selectedMission.title,
          planId: newPlanId,
        });
      } else {
        const plans = await searchDebugPlans(newPlanId, 5);
        const fallback = adaptMissions(plans as unknown as Record<string, unknown>[]).find((item) => item.id === newPlanId);
          if (fallback) {
            focusMission(fallback);
            setMissionNotice({
              kind: 'dispatched',
              missionId: fallback.id,
              title: fallback.title,
              planId: newPlanId,
            });
          }
          else setSelected(null);
        }
      } else {
        setSelected((current) => current?.id === mission.id ? null : current);
      }
    } catch (err) {
      console.error('[MissionCenter] dispatch failed:', err);
      setError(false);
      setActionError(err instanceof Error ? err.message : '任务委托失败');
    } finally {
      setRunningMissionId(null);
    }
  }, [demoMode, fetchMissions, focusMission]);

  const restartMission = useCallback(async (mission: Mission) => {
    setRunningMissionId(mission.id);
    setError(false);
    setActionError(null);
    if (demoMode || !mission.sourceIds.planId) {
      await runMission(mission);
      return;
    }
    try {
      const newPlanId = await createRestartPlan(mission);
      const nextMissions = await fetchMissions();
      setFilter('all');
      const selectedMission = nextMissions.find((item) => item.id === newPlanId || item.sourceIds.planId === newPlanId);
      if (selectedMission) {
        focusMission(selectedMission);
        setMissionNotice({
          kind: 'created',
          missionId: selectedMission.id,
          title: selectedMission.title,
          planId: newPlanId,
        });
      } else {
        setRecentMissionId(newPlanId);
        setMissionNotice({
          kind: 'created',
          missionId: newPlanId,
          title: restartMissionTitle(mission.title),
          planId: newPlanId,
        });
      }
    } catch (err) {
      console.error('[MissionCenter] restart failed:', err);
      setError(false);
      setActionError(err instanceof Error ? err.message : '重新执行失败');
    } finally {
      setRunningMissionId(null);
    }
  }, [demoMode, fetchMissions, focusMission, runMission]);

  const selectedDate = dateFilter || todayDateKey();
  const filteredByDate = dedupeMissionsForDate(
    showAllDates ? missions : missions.filter((mission) => missionMatchesDate(mission, selectedDate)),
    selectedDate,
  );

  const runnableMissions = filteredByDate.filter((mission) => (
    mission.sourceIds.planId
    && ['draft', 'reviewing', 'approved'].includes(mission.status.toLowerCase())
  ));

  const runAllMissions = useCallback(async () => {
    if (runnableMissions.length === 0) return;
    setRunningAll(true);
    setError(false);
    if (demoMode) {
      let delay = 0;
      for (const mission of runnableMissions.slice(0, 4)) {
        window.setTimeout(() => {
          if (!mountedRef.current) return;
          setRunningMissionId(mission.id);
          setMissions((current) => runDemoMissionOnce(current, mission.id));
        }, delay);
        delay += 400;
        window.setTimeout(() => {
          if (!mountedRef.current) return;
          setMissions((current) => completeDemoMissionOnce(current, mission.id));
        }, delay + 900);
      }
      window.setTimeout(() => {
        if (!mountedRef.current) return;
        setRunningMissionId(null);
        setRunningAll(false);
      }, delay + 1200);
      return;
    }
    try {
      for (const mission of runnableMissions) {
        setRunningMissionId(mission.id);
        await dispatchMissionPlan(mission);
      }
      await fetchMissions();
      setSelected(null);
    } catch (err) {
      console.error('[MissionCenter] batch dispatch failed:', err);
      setError(false);
      setActionError(err instanceof Error ? err.message : '批量委托失败');
    } finally {
      setRunningMissionId(null);
      setRunningAll(false);
    }
  }, [demoMode, fetchMissions, runnableMissions]);

  const filtered = filter === 'all'
    ? filteredByDate
    : filteredByDate.filter(m => missionDelegationGroup(m) === filter);
  const displayMissions = filtered
    .map((mission, index) => ({ mission, index }))
    .sort((a, b) => {
      const priority = (mission: Mission) => (
        (mission.id === recentMissionId ? 2 : 0)
        + (mission.id === selected?.id ? 1 : 0)
      );
      return priority(b.mission) - priority(a.mission)
        || missionDateSortValue(a.mission, selectedDate) - missionDateSortValue(b.mission, selectedDate)
        || a.index - b.index;
    })
    .map(({ mission }) => mission);
  const noticeTitle = missionNotice?.kind === 'created'
    ? '刚创建重新执行任务'
    : missionNotice?.kind === 'dispatched'
      ? '刚委托执行任务'
      : '当前查看任务';
  const focusLabelForMission = (mission: Mission): string | null => {
    if (mission.id !== recentMissionId) return null;
    if (missionNotice?.missionId === mission.id && missionNotice.kind === 'created') return '刚创建';
    if (missionNotice?.missionId === mission.id && missionNotice.kind === 'dispatched') return '刚委托';
    return '当前查看';
  };

  return (
    <div className="de-mission-center-page">
      <div className="de-mission-center-layout">
        <div className="de-mc-list">
          <GlassCard>
            <CardTitleBar title="任务委托">
              <button
                onClick={runAllMissions}
                className="de-btn-primary de-btn-sm"
                disabled={runningAll || runnableMissions.length === 0}
              >
                {runningAll ? '委托中...' : `委托可执行任务(${runnableMissions.length})`}
              </button>
              <button onClick={fetchMissions} className="de-btn-secondary de-btn-sm">{t('console.action.refresh')}</button>
            </CardTitleBar>
            <div className="de-card-body">
              {demoMode && (
                <div className="de-schedule-result de-schedule-result--success" style={{ marginBottom: 12 }}>
                  当前没有加载到 qimingclaw 任务记录，页面暂时展示本地示例数据。
                </div>
              )}
              {actionError && (
                <div className="de-schedule-result de-schedule-result--error" style={{ marginBottom: 12 }}>
                  {actionError}
                </div>
              )}
              {missionNotice && (
                <div className="de-mission-focus-notice">
                  <strong>{noticeTitle}</strong>
                  <span>{missionNotice.title}</span>
                  {missionNotice.planId && <code>{missionNotice.planId}</code>}
                </div>
              )}
              <div className="de-date-filter-row">
                <label className="de-date-filter-field">
                  <span>选择日期</span>
                  <input
                    type="date"
                    value={selectedDate}
                    onChange={(event) => {
                      setShowAllDates(false);
                      setDateFilter(event.target.value || todayDateKey());
                    }}
                  />
                </label>
                <div className="de-date-filter-actions" aria-label="日期切换">
                  <button type="button" className="de-filter-chip" onClick={() => { setShowAllDates(false); setDateFilter(shiftDateKey(selectedDate, -1)); }}>前一天</button>
                  <button type="button" className="de-filter-chip active" onClick={() => { setShowAllDates(false); setDateFilter(todayDateKey()); }}>今天</button>
                  <button type="button" className="de-filter-chip" onClick={() => { setShowAllDates(false); setDateFilter(shiftDateKey(selectedDate, 1)); }}>后一天</button>
                </div>
                <span className="de-date-filter-summary">
                  {showAllDates ? `全部 ${filteredByDate.length} 项任务` : `${filteredByDate.length} 项任务`}
                </span>
              </div>
              <div className="de-filter-row">
                {DELEGATION_FILTERS.map((item) => (
                  <button
                    key={item.key}
                    className={`de-filter-chip ${filter === item.key ? 'active' : ''}`}
                    onClick={() => setFilter(item.key)}
                  >
                    {item.label}
                  </button>
                ))}
              </div>
              {loading ? (
                <div className="de-loading-skeleton" style={{ height: 300 }} />
              ) : error ? (
                <p className="de-empty-text">{t('console.state.backendDown')}</p>
              ) : displayMissions.length === 0 ? (
                <div className="de-mission-empty-panel">
                  <strong>当前日期暂无任务</strong>
                  <p>这个日期没有匹配到 qimingclaw 任务记录，可以临时查看全部任务。</p>
                  <div className="de-mission-empty-actions">
                    <button type="button" className="de-btn-primary de-btn-sm" onClick={() => { setShowAllDates(true); setFilter('all'); }}>
                      查看全部任务
                    </button>
                    <button type="button" className="de-btn-secondary de-btn-sm" onClick={() => { setShowAllDates(false); setDateFilter(focusDate || todayDateKey()); }}>
                      返回当前日期
                    </button>
                  </div>
                </div>
              ) : (
                <div className="de-mc-card-list">
                  {displayMissions.map(m => (
                    <MissionCard
                      key={m.id}
                      mission={m}
                      selected={selected?.id === m.id}
                      focusLabel={focusLabelForMission(m)}
                      dateFilter={selectedDate}
                      running={runningMissionId === m.id}
                      onSelect={selectMission}
                      onRun={runMission}
                      onRestart={restartMission}
                    />
                  ))}
                </div>
              )}
            </div>
          </GlassCard>
        </div>
        <div className="de-mc-detail" ref={detailRef}>
          {selected ? (
            <FlowDetailPanel mission={selected} onClose={() => setSelected(null)} />
          ) : (
            <GlassCard>
              <div className="de-card-body">
                <div className="de-mission-empty-panel de-mission-empty-panel--detail">
                  <strong>选择一个任务后，右侧会显示执行步骤、运行记录和交付结果。</strong>
                  <p>任务详情会优先展示 qimingclaw 本地 Plan / Task / Run / Event 记录，以及从执行 payload 中整理出的产物线索。</p>
                </div>
              </div>
            </GlassCard>
          )}
        </div>
      </div>
    </div>
  );
}
