/**
 * WordPress-Specific Validation Utilities
 *
 * Validation functions specific to WordPress data structures including post parameters,
 * pagination, search queries, and status validation.
 */

import { WordPressAPIError } from "@/types/client.js";
import { validateId } from "./core.js";
import { validateString, validateArray } from "./core.js";
import { sanitizeHtml } from "./security.js";

/**
 * Validates WordPress post status values
 */
export function validatePostStatus(status: string): string {
  const validStatuses = ["publish", "draft", "pending", "private", "future", "auto-draft", "trash"];
  if (!validStatuses.includes(status)) {
    throw new WordPressAPIError(`Invalid status: must be one of ${validStatuses.join(", ")}`, 400, "INVALID_PARAMETER");
  }
  return status;
}

/**
 * Validates and sanitizes search queries
 */
export function validateSearchQuery(query: string): string {
  // Remove potentially dangerous characters while preserving search functionality
  let sanitized = query.trim();

  // Limit length to prevent DoS
  if (sanitized.length > 200) {
    sanitized = sanitized.substring(0, 200);
  }

  // Remove SQL-like patterns (basic protection)
  sanitized = sanitized.replace(/(\b(union|select|insert|update|delete|drop|create)\b)/gi, "");

  // Remove special characters that might be used for injection
  sanitized = sanitized.replace(/[<>'"`;\\]/g, "");

  return sanitized;
}

/**
 * Validates pagination parameters as a set
 */
export function validatePaginationParams(params: { page?: unknown; per_page?: unknown; offset?: unknown }): {
  page?: number;
  per_page?: number;
  offset?: number;
} {
  // Handle null/undefined params object
  if (!params || typeof params !== "object") {
    return {};
  }

  const validated: { page?: number; per_page?: number; offset?: number } = {};

  // Validate page
  if (params.page !== undefined) {
    const page = parseInt(String(params.page), 10);
    if (isNaN(page) || page < 1) {
      throw new WordPressAPIError("Page must be a positive integer", 400, "INVALID_PARAMETER");
    }
    if (page > 10000) {
      throw new WordPressAPIError("Page number too high (max 10000)", 400, "INVALID_PARAMETER");
    }
    validated.page = page;
  }

  // Validate per_page
  if (params.per_page !== undefined) {
    const perPage = parseInt(String(params.per_page), 10);
    if (isNaN(perPage) || perPage < 1) {
      throw new WordPressAPIError("Per page must be a positive integer", 400, "INVALID_PARAMETER");
    }
    if (perPage > 100) {
      throw new WordPressAPIError(`Per page exceeds maximum allowed (100), got ${perPage}`, 400, "INVALID_PARAMETER");
    }
    validated.per_page = perPage;
  }

  // Validate offset
  if (params.offset !== undefined) {
    const offset = parseInt(String(params.offset), 10);
    if (isNaN(offset) || offset < 0) {
      throw new WordPressAPIError("Offset must be a non-negative integer", 400, "INVALID_PARAMETER");
    }
    if (offset > 1000000) {
      throw new WordPressAPIError("Offset too large (max 1000000)", 400, "INVALID_PARAMETER");
    }
    validated.offset = offset;
  }

  // Check for conflicting parameters
  if (validated.page && validated.offset) {
    throw new WordPressAPIError(
      "Cannot use both 'page' and 'offset' parameters together",
      400,
      "CONFLICTING_PARAMETERS",
    );
  }

  return validated;
}

/**
 * Validates complex post creation parameters
 */
export function validatePostParams(params: unknown, isUpdate = false): Record<string, unknown> {
  const validated: Record<string, unknown> = {};

  // Type guard to ensure params is an object
  if (typeof params !== "object" || params === null || Array.isArray(params)) {
    throw new WordPressAPIError("Post parameters must be an object", 400, "INVALID_PARAMETER");
  }

  const typedParams = params as Record<string, unknown>;

  // Title validation — required on create, optional on update
  if (!isUpdate) {
    if (!typedParams.title || typeof typedParams.title !== "string") {
      throw new WordPressAPIError("Post title is required and must be a string", 400, "INVALID_PARAMETER");
    }
  }
  if (typedParams.title !== undefined) {
    validated.title = validateString(typedParams.title as string, "title", 1, 200);
  }

  // Content validation
  if (typedParams.content !== undefined) {
    validated.content = sanitizeHtml(String(typedParams.content));
  }

  // Status validation with context
  if (typedParams.status) {
    if (typeof typedParams.status !== "string") {
      throw new WordPressAPIError("Status must be a string", 400, "INVALID_PARAMETER");
    }
    validated.status = validatePostStatus(typedParams.status);

    // Future posts need a date
    if (validated.status === "future" && !typedParams.date) {
      throw new WordPressAPIError("Future posts require a 'date' parameter", 400, "MISSING_PARAMETER");
    }
  }

  // Categories and tags validation
  if (typedParams.categories) {
    const categories = validateArray<unknown>(typedParams.categories, "categories", 0, 50);
    validated.categories = categories.map((id: unknown) => validateId(id, "category ID"));
  }

  if (typedParams.tags) {
    const tags = validateArray<unknown>(typedParams.tags, "tags", 0, 100);
    validated.tags = tags.map((id: unknown) => validateId(id, "tag ID"));
  }

  // Featured media validation
  if (typedParams.featured_media !== undefined) {
    if (typedParams.featured_media === null || typedParams.featured_media === 0) {
      // Allow null or 0 to remove featured media
      validated.featured_media = 0;
    } else {
      validated.featured_media = validateId(typedParams.featured_media, "featured_media");
    }
  }

  // Date validation for scheduled posts
  if (typedParams.date) {
    try {
      const date = new Date(String(typedParams.date));
      if (isNaN(date.getTime())) {
        throw new Error("Invalid date");
      }
      // WordPress expects ISO 8601 format
      validated.date = date.toISOString();
    } catch {
      throw new WordPressAPIError(
        "Invalid date format. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss)",
        400,
        "INVALID_PARAMETER",
      );
    }
  }

  return validated;
}
