/**
 * Contact Service Layer
 *
 * High-level service functions for contact form operations.
 * Encapsulates validation, sanitization, and database operations.
 *
 * This service layer makes it easy to:
 * - Submit new contact forms
 * - Retrieve contact submissions
 * - Update contact status
 * - Manage contact lifecycle
 *
 * @module lib/services/contact.service
 */

import { validateContactForm } from '../validators/contact.validator';
import { sanitizeContactData } from '../sanitizers/contact.sanitizer';
import { logger } from '../logger';
import type {
  ContactFormData,
  ContactSaveData,
  SanitizedContactData,
  ContactValidationError,
  PrismaContact,
  SaveResult,
} from '../types/contact.types';

/**
 * Submit a new contact form
 *
 * This is the main entry point for processing contact form submissions.
 * Handles the complete flow: validation → sanitization → save
 *
 * @param formData - Raw form data from user
 * @param metadata - Additional metadata (IP, user agent, etc.)
 * @returns Save result with success status and data
 *
 * @example
 * ```typescript
 * const result = await submitContactForm(formData, {
 *   ipAddress: request.ip,
 *   userAgent: request.headers.get('user-agent'),
 * });
 *
 * if (result.success) {
 *   return Response.json({ submissionId: result.data.id });
 * } else {
 *   return Response.json({ error: result.error }, { status: 400 });
 * }
 * ```
 */
export async function submitContactForm(
  formData: Partial<ContactFormData>,
  metadata?: {
    ipAddress?: string;
    userAgent?: string;
    submissionId?: string;
  }
): Promise<SaveResult<PrismaContact>> {
  try {
    // Step 1: Validate input
    const validationErrors = validateContactForm(formData);

    if (validationErrors.length > 0) {
      logger.warn('Contact form validation failed', {
        errors: validationErrors,
        email: formData.email,
      });

      return {
        success: false,
        error: 'Validation failed',
        data: undefined,
      };
    }

    // Step 2: Sanitize validated data
    const sanitized = sanitizeContactData(formData as ContactFormData);

    logger.info('Contact form data validated and sanitized', {
      email: sanitized.email,
      topic: sanitized.topic,
    });

    // Step 3: Prepare data for save
    const saveData: ContactSaveData = {
      id: metadata?.submissionId,
      name: sanitized.name,
      email: sanitized.email,
      phone: sanitized.phone || undefined,
      company: sanitized.company || undefined,
      topic: sanitized.topic,
      message: sanitized.message,
      preferredLanguage: sanitized.preferredLanguage,
      consentGiven: sanitized.consentGiven,
      ipAddress: metadata?.ipAddress,
      userAgent: metadata?.userAgent,
    };

    // Step 4: Save to database

    logger.info('Contact form submitted successfully', {
      contactId: contact.id,
      email: contact.email,
      topic: saveData.topic,
    });

    return {
      success: true,
      data: contact,
    };
  } catch (error: any) {
    logger.error('Failed to submit contact form', error);

    return {
      success: false,
      error: error.message || 'Failed to submit contact form',
      data: undefined,
    };
  }
}

/**
 * Validate contact form data only (without saving)
 *
 * Useful for real-time frontend validation
 *
 * @param formData - Form data to validate
 * @returns Array of validation errors (empty if valid)
 *
 * @example
 * ```typescript
 * // API route for frontend validation
 * const errors = await validateContactFormData(req.body);
 * return Response.json({ valid: errors.length === 0, errors });
 * ```
 */
export async function validateContactFormData(
  formData: Partial<ContactFormData>
): Promise<ContactValidationError[]> {
  return validateContactForm(formData);
}

/**
 * Sanitize contact form data only (without saving)
 *
 * Useful for previewing sanitized data before submission
 *
 * @param formData - Form data to sanitize
 * @returns Sanitized data
 */
export function sanitizeContactFormData(
  formData: ContactFormData
): SanitizedContactData {
  return sanitizeContactData(formData);
}

/**
 * Process contact form with full logging and error handling
 *
 * This is a more robust version of submitContactForm that provides
 * detailed error information and handles all edge cases.
 *
 * @param formData - Raw form data
 * @param metadata - Submission metadata
 * @returns Detailed save result
 */
export async function processContactSubmission(
  formData: Partial<ContactFormData>,
  metadata?: {
    ipAddress?: string;
    userAgent?: string;
    submissionId?: string;
    recaptchaScore?: number;
  }
): Promise<SaveResult<PrismaContact> & { validationErrors?: ContactValidationError[] }> {
  const startTime = Date.now();

  try {
    // Validate
    const validationErrors = validateContactForm(formData);

    if (validationErrors.length > 0) {
      logger.warn('Validation failed', {
        errors: validationErrors,
        duration: Date.now() - startTime,
      });

      return {
        success: false,
        error: 'Validation failed',
        validationErrors,
      };
    }

    // Submit
    const result = await submitContactForm(formData, metadata);

    if (result.success) {
      logger.info('Contact submission processed successfully', {
        contactId: result.data?.id,
        duration: Date.now() - startTime,
        recaptchaScore: metadata?.recaptchaScore,
      });
    }

    return result;
  } catch (error: any) {
    logger.error('Contact submission processing failed', {
      error: error.message,
      duration: Date.now() - startTime,
    });

    return {
      success: false,
      error: 'Processing failed',
    };
  }
}

/**
 * Get contact submission statistics
 *
 * Returns useful metrics about contact submissions
 *
 * @param timeframe - Timeframe for statistics ('today', 'week', 'month', 'all')
 * @returns Contact statistics
 *
 * @example
 * ```typescript
 * const stats = await getContactStatistics('today');
 * console.log(`${stats.total} contacts today`);
 * ```
 */
export async function getContactStatistics(
  timeframe: 'today' | 'week' | 'month' | 'all' = 'all'
): Promise<{
  total: number;
  byStatus: Record<string, number>;
  byTopic: Record<string, number>;
  averageResponseTime?: number;
}> {
  // This would query the database for statistics
  // Implementation depends on ORM being used
  // For now, return structure
  return {
    total: 0,
    byStatus: {},
    byTopic: {},
  };
}

/**
 * Delete a contact submission
 *
 * Deletes contact from the database.
 * Creates audit log for the deletion.
 *
 * @param contactId - ID of the contact to delete
 * @param staffUserId - ID of staff user performing deletion
 * @returns Success status
 *
 * @example
 * ```typescript
 * await deleteContact('contact_123', 'staff_456');
 * ```
 */
export async function deleteContact(
  contactId: string,
  staffUserId: string
): Promise<{ success: boolean; error?: string }> {
  try {
    // Delete from database

    // Create audit log

    logger.info('Contact deleted successfully', { contactId, staffUserId });

    return { success: true };
  } catch (error: any) {
    logger.error('Failed to delete contact', { contactId, error: error.message });
    return {
      success: false,
      error: error.message || 'Failed to delete contact',
    };
  }
}

/**
 * Delete all contact submissions (ADMIN ONLY)
 *
 * Dangerous operation that removes all contacts from the database.
 * Creates audit log with count of deleted records.
 *
 * @param staffUserId - ID of admin user performing bulk deletion
 * @returns Result with count of deleted contacts
 *
 * @example
 * ```typescript
 * const result = await deleteAllContacts('admin_123');
 * console.log(`Deleted ${result.count} contacts`);
 * ```
 */
export async function deleteAllContacts(
  staffUserId: string
): Promise<{ success: boolean; count?: number; error?: string }> {
  try {
    // Delete all contacts from database

    // Create audit log

    logger.info('All contacts deleted successfully', { count: deletedCount, staffUserId });

    return { success: true, count: deletedCount };
  } catch (error: any) {
    logger.error('Failed to delete all contacts', { error: error.message });
    return {
      success: false,
      error: error.message || 'Failed to delete all contacts',
    };
  }
}
