/**
 * validate.ts — Structural (Zod) + business-rule validation. No side effects.
 */
import { InitSpecSchema, type InitSpec } from './types.js';

export interface ValidationResult {
  valid: boolean;
  data?: InitSpec;
  blockers: string[];
  warnings: string[];
}

export function validate(raw: unknown): ValidationResult {
  const blockers: string[] = [];
  const warnings: string[] = [];

  // ── Structural validation (Zod) ─────────────────────────
  const parsed = InitSpecSchema.safeParse(raw);
  if (!parsed.success) {
    for (const issue of parsed.error.issues) {
      blockers.push(`[${issue.path.join('.')}] ${issue.message}`);
    }
    return { valid: false, blockers, warnings };
  }

  const data = parsed.data;

  // ── Business rules ──────────────────────────────────────

  // A URL is required to build (proposal mode may still echo the derived name).
  if (data.url) {
    const looksRemote =
      /^(https?:\/\/|git@|ssh:\/\/)/.test(data.url) || data.url.includes('dev.azure.com');
    if (!looksRemote) {
      warnings.push(`URL does not look like a git remote: ${data.url}`);
    }
    if (
      !data.url.includes('github.com') &&
      !data.url.includes('dev.azure.com') &&
      !data.url.includes('gitlab.com') &&
      !data.url.startsWith('git@') &&
      !/^[A-Za-z]:[\\/]/.test(data.url) // allow a local path as a test/import source
    ) {
      warnings.push(`URL provider not recognized: ${data.url}`);
    }
  }

  // Project name must be a safe folder/repo name.
  if (data.name && !/^[a-z0-9][a-z0-9._-]*$/i.test(data.name)) {
    blockers.push(`Invalid project name: ${data.name}`);
  }

  return { valid: blockers.length === 0, data, blockers, warnings };
}
