export type StandardizationTaskProgressSnapshot = {
  execution_mode: 'online' | 'offline';
  status: 'pending' | 'processing' | 'stopping' | 'stopped' | 'completed' | 'failed';
  provider_status: string;
  progress_current: number;
  progress_total: number;
  current_phase?: string;
};

const OFFLINE_PROVIDER_STATUS_ALIASES: Record<string, string> = {
  '': '',
  queued: 'queued',
  '排队中': 'queued',
  preparing: 'preparing',
  '准备中': 'preparing',
  uploaded: 'uploaded',
  '文件已上传': 'uploaded',
  validating: 'validating',
  '校验中': 'validating',
  in_progress: 'in_progress',
  '执行中': 'in_progress',
  finalizing: 'finalizing',
  '汇总中': 'finalizing',
  'writing-results': 'writing-results',
  '写回结果': 'writing-results',
  completed: 'completed',
  '已完成': 'completed',
  failed: 'failed',
  '失败': 'failed',
  cancelling: 'cancelling',
  '取消中': 'cancelling',
  cancelled: 'cancelled',
  '已取消': 'cancelled',
  expired: 'expired',
  '已过期': 'expired',
};

const OFFLINE_PROVIDER_STATUS_LABELS: Record<string, string> = {
  queued: '排队中',
  preparing: '准备中',
  uploaded: '文件已上传',
  validating: '校验中',
  in_progress: '执行中',
  finalizing: '汇总中',
  'writing-results': '写回结果',
  completed: '已完成',
  failed: '失败',
  cancelling: '取消中',
  cancelled: '已取消',
  expired: '已过期',
};

function clampProgressValue(value: number, total: number) {
  return Math.min(total, Math.max(0, value));
}

function calculateRawProgressPercent(snapshot: StandardizationTaskProgressSnapshot) {
  const total = Math.max(0, snapshot.progress_total);
  const current = clampProgressValue(snapshot.progress_current, total);

  if (total > 0) {
    return Math.min(100, Math.round((current / total) * 100));
  }

  return snapshot.status === 'completed' ? 100 : 0;
}

export function normalizeOfflineProviderStatus(status: string) {
  const normalized = status.trim().toLowerCase();
  return OFFLINE_PROVIDER_STATUS_ALIASES[normalized] ?? normalized;
}

function inferOfflineProviderStatus(snapshot: StandardizationTaskProgressSnapshot) {
  const normalizedProviderStatus = normalizeOfflineProviderStatus(snapshot.provider_status);
  if (normalizedProviderStatus) {
    return normalizedProviderStatus;
  }

  if (snapshot.status === 'completed') {
    return 'completed';
  }

  if (snapshot.status === 'failed') {
    return 'failed';
  }

  if (snapshot.progress_current > 0) {
    return 'in_progress';
  }

  if (snapshot.status === 'processing') {
    return 'validating';
  }

  if (snapshot.status === 'pending') {
    return 'queued';
  }

  return '';
}

function calculateOfflineMonitorPercent(snapshot: StandardizationTaskProgressSnapshot) {
  const total = Math.max(0, snapshot.progress_total);
  const current = clampProgressValue(snapshot.progress_current, total);
  const ratio = total > 0 ? current / total : 0;
  const providerStatus = inferOfflineProviderStatus(snapshot);

  if (snapshot.status === 'completed' || providerStatus === 'completed') {
    return 100;
  }

  switch (providerStatus) {
    case 'queued':
      return 2;
    case 'preparing':
      return 6;
    case 'uploaded':
      return 12;
    case 'validating':
      return 20;
    case 'in_progress':
      return Math.max(30, Math.min(90, Math.round(30 + (ratio * 60))));
    case 'finalizing':
      return 95;
    case 'writing-results':
      return 98;
    case 'cancelling':
      return Math.max(20, Math.min(96, Math.round(20 + (ratio * 70))));
    case 'failed':
    case 'cancelled':
    case 'expired':
      return total > 0 ? Math.max(5, Math.min(99, Math.round(20 + (ratio * 70)))) : 5;
    default:
      if (snapshot.status === 'failed') {
        return total > 0 ? Math.max(5, Math.min(99, Math.round(20 + (ratio * 70)))) : 5;
      }

      if (snapshot.status === 'processing') {
        return total > 0 ? Math.max(20, Math.min(90, Math.round(20 + (ratio * 70)))) : 20;
      }

      if (snapshot.status === 'pending') {
        return 0;
      }

      return calculateRawProgressPercent(snapshot);
  }
}

export function calculateStandardizationTaskProgressPercent(snapshot: StandardizationTaskProgressSnapshot) {
  return snapshot.execution_mode === 'offline'
    ? calculateOfflineMonitorPercent(snapshot)
    : calculateRawProgressPercent(snapshot);
}

export function formatOfflineProviderStatus(status: string) {
  const normalizedProviderStatus = normalizeOfflineProviderStatus(status);
  const label = OFFLINE_PROVIDER_STATUS_LABELS[normalizedProviderStatus] ?? status;
  return label || '-';
}

export function getStandardizationTaskProgressCountLabel(snapshot: Pick<StandardizationTaskProgressSnapshot, 'execution_mode'>) {
  return snapshot.execution_mode === 'offline' ? '已回执' : '已处理';
}

export function formatStandardizationTaskProgressSummary(snapshot: StandardizationTaskProgressSnapshot) {
  const total = Math.max(0, snapshot.progress_total);
  const current = clampProgressValue(snapshot.progress_current, total);
  const countLabel = getStandardizationTaskProgressCountLabel(snapshot);

  if (total > 0) {
    return `${countLabel} ${current}/${total}`;
  }

  return snapshot.execution_mode === 'offline' ? '等待 Batch 回执' : '等待处理';
}

export function getStandardizationTaskProgressStageLabel(snapshot: StandardizationTaskProgressSnapshot) {
  if (snapshot.execution_mode === 'offline') {
    const providerStatus = inferOfflineProviderStatus(snapshot);
    const label = formatOfflineProviderStatus(providerStatus);
    if (label !== '-') {
      return label;
    }

    const currentPhase = snapshot.current_phase?.trim();
    if (currentPhase) {
      return currentPhase.replace(/^离线批处理\s*·\s*/u, '');
    }
  }

  if (snapshot.status === 'completed') {
    return '已完成';
  }

  if (snapshot.status === 'failed') {
    return '失败';
  }

  if (snapshot.status === 'pending') {
    return '待处理';
  }

  return snapshot.current_phase?.trim() || '处理中';
}

export function isFailedStandardizationTaskProgress(snapshot: StandardizationTaskProgressSnapshot) {
  if (snapshot.status === 'failed') {
    return true;
  }

  if (snapshot.execution_mode !== 'offline') {
    return false;
  }

  const providerStatus = inferOfflineProviderStatus(snapshot);
  return providerStatus === 'failed' || providerStatus === 'cancelled' || providerStatus === 'expired';
}

export function isTerminalStandardizationTaskProgress(snapshot: StandardizationTaskProgressSnapshot) {
  if (snapshot.status === 'completed' || snapshot.status === 'failed') {
    return true;
  }

  if (snapshot.execution_mode !== 'offline') {
    return false;
  }

  const providerStatus = inferOfflineProviderStatus(snapshot);
  return providerStatus === 'completed' || providerStatus === 'failed' || providerStatus === 'cancelled' || providerStatus === 'expired';
}