import fs from 'node:fs';

export const REQUIRED_COVERAGE_UNITS = Object.freeze([
  'support-gate', 'user-auth', 'workspace', 'current-task', 'projects',
  'project-detail', 'editor', 'export', 'credits', 'settings',
  'preview-user-variant', 'admin-auth', 'admin-overview', 'admin-users',
  'admin-invites', 'admin-models', 'admin-assets', 'admin-preview',
  'admin-generations', 'admin-services-storage', 'admin-audit', 'system-ui',
]);

const REQUIRED_VIEWPORTS = Object.freeze([
  { width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 100 },
  { width: 1920, height: 1080, deviceScaleFactor: 1, zoom: 200 },
]);

function blocked(code, details = {}) {
  return { status: 'externally_blocked', code, ...details };
}

export function loadCandidateRecord(path) {
  if (!path || !fs.existsSync(path)) return blocked('candidate_record_missing');
  try {
    const record = JSON.parse(fs.readFileSync(path, 'utf8'));
    if (!Array.isArray(record.browsers) || record.browsers.length !== 2) {
      return blocked('candidate_browser_record_incomplete');
    }
    const brands = new Set(record.browsers.map((browser) => browser.brand));
    if (brands.size !== 2 || !brands.has('Google Chrome') || !brands.has('Microsoft Edge')) {
      return blocked('candidate_browser_pair_invalid');
    }
    if (record.windows?.build == null || !record.candidate_package?.sha256 || !record.candidate_package?.fixed_port) {
      return blocked('candidate_identity_incomplete');
    }
    if (record.browsers.some((browser) => !browser.full_version || !browser.major)) {
      return blocked('candidate_full_version_missing');
    }
    return { status: 'ready', record };
  } catch {
    return blocked('candidate_record_invalid');
  }
}

export function validateCoverageEvidence(evidence) {
  if (!evidence || !Array.isArray(evidence.coverage_units)) {
    return blocked('coverage_evidence_missing');
  }
  const actual = new Set(evidence.coverage_units.map((unit) => unit.page_id));
  const missing = REQUIRED_COVERAGE_UNITS.filter((unit) => !actual.has(unit));
  if (missing.length) return blocked('coverage_units_incomplete', { missing });
  const missingStates = evidence.coverage_units
    .filter((unit) => REQUIRED_COVERAGE_UNITS.includes(unit.page_id))
    .filter((unit) => !Array.isArray(unit.states) || unit.states.length === 0)
    .map((unit) => unit.page_id);
  if (missingStates.length) return blocked('coverage_states_incomplete', { missingStates });
  const viewportKeys = new Set((evidence.viewports ?? []).map((viewport) => JSON.stringify(viewport)));
  const missingViewports = REQUIRED_VIEWPORTS.filter((viewport) => !viewportKeys.has(JSON.stringify(viewport)));
  if (missingViewports.length) return blocked('candidate_viewports_incomplete', { missingViewports });
  return { status: 'ready' };
}

export function runWp705Gate({ candidatePath, evidence, dependencies = {} }) {
  const candidate = loadCandidateRecord(candidatePath);
  if (candidate.status !== 'ready') return candidate;
  const coverage = validateCoverageEvidence(evidence);
  if (coverage.status !== 'ready') return coverage;
  const externalBlockers = Object.entries(dependencies)
    .filter(([, status]) => status === 'externally_blocked')
    .map(([task]) => task);
  if (externalBlockers.length) return blocked('upstream_external_blocked', { externalBlockers });
  return { status: 'ready_for_execution' };
}
