<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Niwa_AI_Email_Validator {

	/**
	 * Validate an email address: format, disposable domain, duplicate check.
	 *
	 * @param string $email Email to validate.
	 * @return array { valid: bool, message: string, action: 'insert'|'update'|'reject' }
	 */
	public function validate( $email ) {
		$email = trim( (string) $email );

		if ( ! is_email( $email ) ) {
			return array(
				'valid'   => false,
				'message' => 'Invalid email address.',
				'action'  => 'reject',
			);
		}

		if ( $this->is_disposable( $email ) ) {
			return array(
				'valid'   => false,
				'message' => 'Please use a real email address.',
				'action'  => 'reject',
			);
		}

		// Check for existing contact in DB.
		global $wpdb;
		$table = $wpdb->prefix . 'niwa_ai_contacts';

		// Skip duplicate lookup until the contacts table exists.
		$previous_suppress = method_exists( $wpdb, 'suppress_errors' ) ? $wpdb->suppress_errors( true ) : false;
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
		if ( method_exists( $wpdb, 'suppress_errors' ) ) {
			$wpdb->suppress_errors( $previous_suppress );
		}
		if ( $table !== $table_exists ) {
			return array(
				'valid'   => true,
				'message' => 'Email is valid.',
				'action'  => 'insert',
			);
		}

		$previous_suppress = method_exists( $wpdb, 'suppress_errors' ) ? $wpdb->suppress_errors( true ) : false;
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$existing = $wpdb->get_var(
			$wpdb->prepare( "SELECT id FROM {$table} WHERE email = %s", $email )
		);
		if ( method_exists( $wpdb, 'suppress_errors' ) ) {
			$wpdb->suppress_errors( $previous_suppress );
		}

		if ( $existing ) {
			return array(
				'valid'   => true,
				'message' => 'Contact exists, will be updated.',
				'action'  => 'update',
			);
		}

		return array(
			'valid'   => true,
			'message' => 'Email is valid.',
			'action'  => 'insert',
		);
	}

	/**
	 * Check if the email belongs to a disposable / throwaway domain.
	 *
	 * @param string $email Email address.
	 * @return bool
	 */
	public function is_disposable( $email ) {
		$parts = explode( '@', $email );
		if ( count( $parts ) < 2 ) {
			return false;
		}

		$domain  = strtolower( $parts[1] );
		$domains = $this->get_disposable_domains();

		return in_array( $domain, $domains, true );
	}

	/**
	 * Get the list of known disposable email domains.
	 *
	 * @return array
	 */
	private function get_disposable_domains() {
		$domains = array(
			'mailinator.com',
			'tempmail.com',
			'guerrillamail.com',
			'yopmail.com',
			'throwaway.email',
			'temp-mail.org',
			'10minutemail.com',
			'trashmail.com',
			'fakeinbox.com',
			'sharklasers.com',
			'guerrillamail.info',
			'grr.la',
			'guerrillamail.net',
			'guerrillamail.org',
			'dispostable.com',
			'mailnesia.com',
			'maildrop.cc',
			'discard.email',
			'tempail.com',
			'getnada.com',
		);

		return apply_filters( 'niwa_ai_disposable_domains', $domains );
	}
}
