import type { DiagnosticCheck, DiagnosticReport, DiagnosticStatus } from './types';

const VALID_STATUSES: DiagnosticStatus[] = ['pass', 'warn', 'fail', 'skipped'];

function normalizeStatus(value: unknown): DiagnosticStatus {
  if (typeof value === 'string' && VALID_STATUSES.includes(value as DiagnosticStatus)) {
    return value as DiagnosticStatus;
  }
  return 'skipped';
}

function normalizeCheck(raw: unknown): DiagnosticCheck | null {
  if (!raw || typeof raw !== 'object') {
    return null;
  }

  const check = raw as Record<string, unknown>;
  const id = check.id;
  if (typeof id !== 'string' || id.length === 0) {
    return null;
  }

  return {
    id,
    status: normalizeStatus(check.status),
    details: typeof check.details === 'string' ? check.details : '',
    fixHint: typeof check.fixHint === 'string' ? check.fixHint : '',
  };
}

/**
 * Normalize a native diagnostic payload into a DiagnosticReport
 */
export function parseDiagnosticReport(raw: unknown): DiagnosticReport {
  const payload = raw && typeof raw === 'object' ? (raw as Record<string, unknown>) : {};
  const checks = Array.isArray(payload.checks)
    ? payload.checks.map(normalizeCheck).filter((check): check is DiagnosticCheck => check !== null)
    : [];

  const platform = payload.platform === 'android' ? 'android' : 'ios';
  const overallStatus =
    typeof payload.overallStatus === 'string' && payload.overallStatus.length > 0
      ? payload.overallStatus
      : deriveOverallStatus(checks);

  const prettyPrinted =
    typeof payload.prettyPrinted === 'string' && payload.prettyPrinted.length > 0
      ? payload.prettyPrinted
      : formatDiagnosticReport({
          overallStatus,
          checks,
          prettyPrinted: '',
          platform,
        });

  const architecture =
    payload.architecture === 'old' || payload.architecture === 'new'
      ? payload.architecture
      : undefined;
  const turboModule = typeof payload.turboModule === 'boolean' ? payload.turboModule : undefined;

  return {
    overallStatus,
    checks,
    prettyPrinted,
    platform,
    ...(architecture ? { architecture } : {}),
    ...(turboModule !== undefined ? { turboModule } : {}),
  };
}

function deriveOverallStatus(checks: DiagnosticCheck[]): DiagnosticStatus {
  if (checks.some((check) => check.status === 'fail')) {
    return 'fail';
  }
  if (checks.some((check) => check.status === 'warn')) {
    return 'warn';
  }
  if (checks.length > 0 && checks.every((check) => check.status === 'pass')) {
    return 'pass';
  }
  return 'skipped';
}

/**
 * Format a diagnostic report for logs or sharing with support
 */
export function formatDiagnosticReport(report: DiagnosticReport): string {
  const lines = [
    `Freshdesk diagnostics (${report.platform}) — overall: ${report.overallStatus}`,
    '',
  ];

  if (report.checks.length === 0) {
    lines.push('No diagnostic checks returned.');
    return lines.join('\n');
  }

  for (const check of report.checks) {
    lines.push(`[${check.status.toUpperCase()}] ${check.id}`);
    if (check.details) {
      lines.push(`  details: ${check.details}`);
    }
    if (check.fixHint) {
      lines.push(`  fix: ${check.fixHint}`);
    }
    lines.push('');
  }

  return lines.join('\n').trimEnd();
}
