/**
 * Submission-Specific Validation Utilities
 * 
 * Validates submission and moderation request structures
 * Ensures type safety across the submission pipeline
 */

import {
  validateUUID,
  validateUUIDArray,
  validateEntityType,
  validateActionType,
  validateObject,
  validateString,
  validateArray,
  type ValidEntityType,
  type ValidActionType,
} from './typeValidation.ts';

/**
 * Validated approval request structure
 */
export interface ValidatedApprovalRequest {
  submissionId: string;
  itemIds: string[];
}

/**
 * Validated rejection request structure
 */
export interface ValidatedRejectionRequest {
  submissionId: string;
  itemIds: string[];
  rejectionReason: string;
}

/**
 * Validated submission item
 */
export interface ValidatedSubmissionItem {
  id: string;
  item_type: ValidEntityType;
  action_type: ValidActionType;
  entity_id?: string | null;
  item_data?: Record<string, unknown>;
}

/**
 * Validate approval request body
 */
export function validateApprovalRequest(
  body: unknown,
  requestId?: string
): ValidatedApprovalRequest {
  validateObject(body, 'request_body', { requestId });
  const obj = body as Record<string, unknown>;

  validateUUID(obj.submissionId, 'submissionId', { requestId });
  validateUUIDArray(obj.itemIds, 'itemIds', 1, { requestId });

  return {
    submissionId: obj.submissionId as string,
    itemIds: obj.itemIds as string[],
  };
}

/**
 * Validate rejection request body
 */
export function validateRejectionRequest(
  body: unknown,
  requestId?: string
): ValidatedRejectionRequest {
  validateObject(body, 'request_body', { requestId });
  const obj = body as Record<string, unknown>;

  validateUUID(obj.submissionId, 'submissionId', { requestId });
  validateUUIDArray(obj.itemIds, 'itemIds', 1, { requestId });
  validateString(obj.rejectionReason, 'rejectionReason', { requestId });

  return {
    submissionId: obj.submissionId as string,
    itemIds: obj.itemIds as string[],
    rejectionReason: obj.rejectionReason as string,
  };
}

/**
 * Validate submission item from database
 */
export function validateSubmissionItemFromDB(
  item: unknown,
  context?: Record<string, unknown>
): ValidatedSubmissionItem {
  validateObject(item, 'submission_item', context);
  const obj = item as Record<string, unknown>;

  // Validate required fields
  validateUUID(obj.id, 'submission_item.id', context);
  validateEntityType(obj.item_type, 'submission_item.item_type', {
    ...context,
    itemId: obj.id,
  });
  validateActionType(obj.action_type, 'submission_item.action_type', {
    ...context,
    itemId: obj.id,
  });

  return {
    id: obj.id as string,
    item_type: obj.item_type as ValidEntityType,
    action_type: obj.action_type as ValidActionType,
    entity_id: obj.entity_id as string | null | undefined,
    item_data: obj.item_data as Record<string, unknown> | undefined,
  };
}

/**
 * Validate array of submission items
 */
export function validateSubmissionItems(
  items: unknown,
  context?: Record<string, unknown>
): ValidatedSubmissionItem[] {
  validateArray(items, 'submission_items', 1, context);
  
  const itemArray = items as unknown[];
  return itemArray.map((item, index) =>
    validateSubmissionItemFromDB(item, {
      ...context,
      itemIndex: index,
    })
  );
}

/**
 * Validate that entity type matches the expected submission table
 * Helps catch data model mismatches early
 */
export function validateEntityTypeConsistency(
  item: ValidatedSubmissionItem,
  expectedTypes: ValidEntityType[],
  context?: Record<string, unknown>
): void {
  if (!expectedTypes.includes(item.item_type)) {
    throw new Error(
      `Entity type mismatch: expected one of [${expectedTypes.join(', ')}] but got '${item.item_type}' ` +
      `for item ${item.id}. This may indicate a data model inconsistency. ` +
      `Context: ${JSON.stringify(context)}`
    );
  }
}

/**
 * Map entity type to submission table name
 * Useful for debugging and error messages
 */
export function getSubmissionTableName(entityType: ValidEntityType): string {
  const tableMap: Record<ValidEntityType, string> = {
    park: 'park_submissions',
    ride: 'ride_submissions',
    manufacturer: 'company_submissions',
    operator: 'company_submissions',
    property_owner: 'company_submissions',
    designer: 'company_submissions',
    company: 'company_submissions',
    ride_model: 'ride_model_submissions',
    photo: 'photo_submissions',
    milestone: 'timeline_event_submissions',
    timeline_event: 'timeline_event_submissions',
  };

  return tableMap[entityType] || 'unknown_submissions';
}

/**
 * Map entity type to main table name
 * Useful for debugging and error messages
 */
export function getMainTableName(entityType: ValidEntityType): string {
  const tableMap: Record<ValidEntityType, string> = {
    park: 'parks',
    ride: 'rides',
    manufacturer: 'companies',
    operator: 'companies',
    property_owner: 'companies',
    designer: 'companies',
    company: 'companies',
    ride_model: 'ride_models',
    photo: 'photos',
    milestone: 'timeline_events',
    timeline_event: 'timeline_events',
  };

  return tableMap[entityType] || 'unknown_table';
}
