import type { VersionWithContext } from './derive';
import type { XiaobaoRiskInsight } from './xiaobao-risk-cache';
import type { XiaobaoVersionRisk } from './xiaobao-risk';
import { buildRiskInsightDisplaySignature, normalizeRiskInsightDisplaySignature } from './xiaobao-risk-ai';
import { WORK_HOURS } from './work-hours';

const WARNING_VERSION_STATUSES = new Set(['planned', 'developing']);
const PAUSED_PROJECT_STATUSES = new Set(['paused']);
const HIGH_RISK_LEVELS = new Set<XiaobaoVersionRisk['riskLevel']>(['at_risk', 'likely_delayed', 'blocked']);
const PAGE_REFRESH_ADVICE_PATTERNS = [
  /(刷新|重新加载|重载).*(页面|浏览器|小宝|预警)/i,
  /(页面|浏览器|小宝|预警).*(刷新|重新加载|重载)/i,
  /(手动|主动).*(触发|刷新).*(更新|预警|分析)/i,
  /(manual|manually).*(refresh|reload|trigger)/i,
  /(refresh|reload).*(page|browser|xiaobao|warning)/i,
];

export interface XiaobaoWarningVersionFilter {
  canManage: boolean;
  userName?: string;
}

export type XiaobaoWarningRiskFilter = 'all' | 'attention' | 'high';

export interface XiaobaoWarningRiskListFilter {
  riskFilter?: XiaobaoWarningRiskFilter;
  productId?: string;
  projectId?: string;
}

export type RiskScoreTone = 'danger' | 'warn' | 'ok';

export interface XiaobaoWarningReadState {
  userId: string;
  versionId: string;
  signature: string;
  readAt: string;
}

export function filterXiaobaoWarningVersions(
  versions: VersionWithContext[],
  filter: XiaobaoWarningVersionFilter,
): VersionWithContext[] {
  return versions.filter((version) => {
    if (!WARNING_VERSION_STATUSES.has(version.status)) return false;
    if (version.projectStatus && PAUSED_PROJECT_STATUSES.has(version.projectStatus)) return false;
    if (filter.canManage) return true;
    if (!filter.userName) return false;
    return (version.members ?? []).some((member) => member.name === filter.userName);
  });
}

export function filterXiaobaoRiskWarnings(
  risks: XiaobaoVersionRisk[],
  filter: XiaobaoWarningRiskListFilter = {},
): XiaobaoVersionRisk[] {
  return risks.filter((risk) => {
    if (risk.riskLevel === 'on_track') return false;
    if (filter.productId && risk.productId !== filter.productId) return false;
    if (filter.projectId && risk.projectId !== filter.projectId) return false;
    if (filter.riskFilter === 'attention') return true;
    if (filter.riskFilter === 'high') return HIGH_RISK_LEVELS.has(risk.riskLevel);
    return true;
  });
}

export function getXiaobaoWarningRiskCount(risks: XiaobaoVersionRisk[]): number {
  return filterXiaobaoRiskWarnings(risks).length;
}

export function getXiaobaoWarningUpdateSignature(risk: XiaobaoVersionRisk): string {
  return buildRiskInsightDisplaySignature(risk);
}

export function isXiaobaoWarningUpdated(
  risk: XiaobaoVersionRisk,
  readStates: XiaobaoWarningReadState[],
  userId?: string,
): boolean {
  if (!userId) return false;
  if (risk.aiInsightUpdating) return false;
  const currentSignature = getXiaobaoWarningUpdateSignature(risk);
  const readState = readStates.find((item) => item.userId === userId && item.versionId === risk.versionId);
  const readSignature = readState?.signature
    ? normalizeRiskInsightDisplaySignature(readState.signature) ?? readState.signature
    : undefined;
  return readSignature !== currentSignature;
}

export function shouldSkipXiaobaoRiskInsightRequestForReadState(
  risk: XiaobaoVersionRisk,
  readStates: XiaobaoWarningReadState[],
  userId: string | undefined,
  readStateLoaded: boolean,
): boolean {
  if (!userId) return false;
  if (!readStateLoaded) return true;
  return !isXiaobaoWarningUpdated(risk, readStates, userId);
}

export function getXiaobaoWarningUnreadUpdateCount(
  risks: XiaobaoVersionRisk[],
  readStates: XiaobaoWarningReadState[],
  userId?: string,
): number {
  return risks.filter((risk) => isXiaobaoWarningUpdated(risk, readStates, userId)).length;
}

export function markXiaobaoWarningRead(
  readStates: XiaobaoWarningReadState[],
  userId: string,
  risk: XiaobaoVersionRisk,
  readAt: string,
): XiaobaoWarningReadState[] {
  if (risk.aiInsightUpdating) return readStates;
  const item: XiaobaoWarningReadState = {
    userId,
    versionId: risk.versionId,
    signature: getXiaobaoWarningUpdateSignature(risk),
    readAt,
  };
  return [
    item,
    ...readStates.filter((row) => row.userId !== userId || row.versionId !== risk.versionId),
  ];
}

export function getRiskScoreTone(score: number): RiskScoreTone {
  if (score >= 75) return 'danger';
  if (score >= 55) return 'warn';
  return 'ok';
}

export function formatRemainingWork(hours: number): string {
  const safeHours = Number.isFinite(hours) && hours > 0 ? hours : 0;
  const days = safeHours / WORK_HOURS.hoursPerDay;
  return `${formatNumber(safeHours)}h / ${formatNumber(days)}天`;
}

export function sanitizeRiskInsight(insight: XiaobaoRiskInsight): XiaobaoRiskInsight {
  return {
    ...insight,
    suggestedActions: insight.suggestedActions.filter((action) => !isPageRefreshAdvice(action)),
    ownerHints: insight.ownerHints.filter((hint) => !isPageRefreshAdvice(hint)),
  };
}

function formatNumber(value: number): string {
  if (Number.isInteger(value)) return String(value);
  return value.toFixed(1).replace(/\.0$/, '');
}

function isPageRefreshAdvice(text: string): boolean {
  return PAGE_REFRESH_ADVICE_PATTERNS.some((pattern) => pattern.test(text));
}
