import { listChatExtractions } from '@/lib/server/chat-extraction';
import { clamp, nowIso, persistPhaseArtifacts, uniqueStrings, toStage } from '@/lib/server/projects';
import type { CanonicalProductModel } from '@/lib/types/product-model';
import type { ChatExtractionRecord } from '@/lib/types/chat-extraction';

const average = (numbers: number[]) =>
  numbers.length ? numbers.reduce((sum, value) => sum + value, 0) / numbers.length : 0;

export async function buildCanonicalProductModel(projectId: string): Promise<CanonicalProductModel> {
  const extractions = await listChatExtractions(projectId);
  if (!extractions.length) {
    throw new Error('No chat extractions found for project');
  }

  const completionAvg = average(
    extractions.map(
      (record) =>
        (record.data as any)?.summary_scores?.overall_completion ?? record.overallCompletion ?? 0,
    ),
  );
  const confidenceAvg = average(
    extractions.map(
      (record) =>
        (record.data as any)?.summary_scores?.overall_confidence ?? record.overallConfidence ?? 0,
    ),
  );

  const canonical = mapExtractionToCanonical(
    projectId,
    pickHighestConfidence(extractions as any),
    completionAvg,
    confidenceAvg,
  );

  await persistPhaseArtifacts(projectId, (phaseData, phaseScores, phaseHistory) => {
    phaseData.canonicalProductModel = canonical;
    phaseScores.vision = {
      overallCompletion: canonical.overallCompletion,
      overallConfidence: canonical.overallConfidence,
      updatedAt: nowIso(),
    };
    phaseHistory.push({ phase: 'vision', status: 'completed', timestamp: nowIso() });
    return { phaseData, phaseScores, phaseHistory, nextPhase: 'vision_ready' };
  });

  return canonical;
}

function pickHighestConfidence(records: ChatExtractionRecord[]) {
  return records.reduce((best, record) =>
    record.overallConfidence > best.overallConfidence ? record : best,
  );
}

function mapExtractionToCanonical(
  projectId: string,
  record: ChatExtractionRecord,
  completionAvg: number,
  confidenceAvg: number,
): CanonicalProductModel {
  const data = record.data;

  const coreFeatures = data.solution_and_features.core_features.map(
    (feature) => feature.name || feature.description,
  );
  const niceToHaveFeatures = data.solution_and_features.nice_to_have_features.map(
    (feature) => feature.name || feature.description,
  );

  return {
    projectId,
    workingTitle: data.project_summary.working_title ?? null,
    oneLiner: data.project_summary.one_liner ?? null,
    problem: data.product_vision.problem_statement.description ?? null,
    targetUser: data.target_users.primary_segment.description ?? null,
    desiredOutcome: data.product_vision.target_outcome.description ?? null,
    coreSolution: data.solution_and_features.core_solution.description ?? null,
    coreFeatures: uniqueStrings(coreFeatures),
    niceToHaveFeatures: uniqueStrings(niceToHaveFeatures),
    marketCategory: data.market_and_competition.market_category.description ?? null,
    competitors: uniqueStrings(
      data.market_and_competition.competitors.map((competitor) => competitor.name),
    ),
    techStack: uniqueStrings(
      data.tech_and_constraints.stack_mentions.map((item) => item.description),
    ),
    constraints: uniqueStrings(
      data.tech_and_constraints.constraints.map((constraint) => constraint.description),
    ),
    currentStage: toStage(data.project_summary.stage),
    shortTermGoals: uniqueStrings(
      data.goals_and_success.short_term_goals.map((goal) => goal.description),
    ),
    longTermGoals: uniqueStrings(
      data.goals_and_success.long_term_goals.map((goal) => goal.description),
    ),
    overallCompletion: clamp(completionAvg),
    overallConfidence: clamp(confidenceAvg),
  };
}


