<?php
/* =======================================================================
   247ChatMate – Central Opt-In Receiver (Hardened Production Build)
   Receives:
     email, updates=yes/no, skool=yes/no, domain, locale,
     version, timestamp, ua, site_hash

   Stores safely in:
     /matewa/optins.csv

   Security:
     - POST only
     - Nonce verification
     - Sanitisation of all fields
     - Reject missing critical fields
     - CSV locking (LOCK_EX)
     - Duplicate overwrite via site_hash
     - UTF-8 safe
======================================================================= */

defined( 'ABSPATH' ) || exit;

header( 'Content-Type: text/plain; charset=utf-8' );

// ------------------------------------------------------
// 1. Only allow POST requests
// ------------------------------------------------------
$matewa_request_method = isset( $_SERVER['REQUEST_METHOD'] )
	? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) )
	: '';

if ( 'POST' !== $matewa_request_method ) {
	status_header( 405 );
	exit( 'Invalid method' );
}

// ------------------------------------------------------
// 2. Verify nonce
// ------------------------------------------------------
$matewa_optin_nonce = isset( $_POST['matewa_optin_nonce'] )
	? sanitize_text_field( wp_unslash( $_POST['matewa_optin_nonce'] ) )
	: '';

if ( '' === $matewa_optin_nonce || ! wp_verify_nonce( $matewa_optin_nonce, 'matewa_optin_submit' ) ) {
	status_header( 403 );
	exit( 'Invalid nonce' );
}

// ------------------------------------------------------
// 3. Extract + sanitise input
// ------------------------------------------------------
$matewa_email = isset( $_POST['email'] )
	? sanitize_email( wp_unslash( $_POST['email'] ) )
	: '';

$matewa_updates = isset( $_POST['updates'] )
	? sanitize_text_field( wp_unslash( $_POST['updates'] ) )
	: '';
$matewa_updates = ( 'yes' === $matewa_updates ) ? 'yes' : 'no';

$matewa_skool = isset( $_POST['skool'] )
	? sanitize_text_field( wp_unslash( $_POST['skool'] ) )
	: '';
$matewa_skool = ( 'yes' === $matewa_skool ) ? 'yes' : 'no';

$matewa_domain_raw = isset( $_POST['domain'] )
	? sanitize_text_field( wp_unslash( $_POST['domain'] ) )
	: '';
$matewa_domain = esc_url_raw( $matewa_domain_raw );

// Normalise domain for safety.
$matewa_domain = preg_replace( '/[^a-zA-Z0-9\.\-\/\:_]/', '', (string) $matewa_domain );

$matewa_locale = isset( $_POST['locale'] )
	? sanitize_text_field( wp_unslash( $_POST['locale'] ) )
	: '';
$matewa_locale = preg_replace( '/[^a-zA-Z0-9_-]/', '', (string) $matewa_locale );

$matewa_version = isset( $_POST['version'] )
	? sanitize_text_field( wp_unslash( $_POST['version'] ) )
	: '';
$matewa_version = preg_replace( '/[^0-9\.]/', '', (string) $matewa_version );

$matewa_site_hash = isset( $_POST['site_hash'] )
	? sanitize_text_field( wp_unslash( $_POST['site_hash'] ) )
	: '';
$matewa_site_hash = preg_replace( '/[^a-f0-9]/', '', strtolower( (string) $matewa_site_hash ) );

$matewa_timestamp = isset( $_POST['timestamp'] )
	? absint( wp_unslash( $_POST['timestamp'] ) )
	: time();

$matewa_ua = isset( $_POST['ua'] )
	? sanitize_text_field( wp_unslash( $_POST['ua'] ) )
	: 'unknown';
$matewa_ua = substr( $matewa_ua, 0, 240 );

// ------------------------------------------------------
// 4. Validate required fields
// ------------------------------------------------------
if ( '' === $matewa_email || '' === $matewa_site_hash ) {
	status_header( 400 );
	exit( 'Missing email or site_hash' );
}

if ( ! is_email( $matewa_email ) ) {
	status_header( 400 );
	exit( 'Invalid email' );
}

// ------------------------------------------------------
// 5. CSV path
// ------------------------------------------------------
$matewa_csv_path = __DIR__ . '/optins.csv';

// Create file with header if missing.
if ( ! file_exists( $matewa_csv_path ) ) {
	file_put_contents(
		$matewa_csv_path,
		"site_hash,email,updates,skool,domain,locale,version,timestamp,ua\n",
		LOCK_EX
	); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
}

// ------------------------------------------------------
// 6. Load CSV safely
// ------------------------------------------------------
$matewa_rows = file( $matewa_csv_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file

if ( ! is_array( $matewa_rows ) || 0 === count( $matewa_rows ) ) {
	// Rebuild header if file corrupted.
	$matewa_rows = array( 'site_hash,email,updates,skool,domain,locale,version,timestamp,ua' );
}

$matewa_clean   = array();
$matewa_clean[] = $matewa_rows[0]; // Always preserve header.

// ------------------------------------------------------
// 7. Remove old entry for this site_hash
// ------------------------------------------------------
$matewa_row_count = count( $matewa_rows );

for ( $matewa_i = 1; $matewa_i < $matewa_row_count; $matewa_i++ ) {
	$matewa_cols = str_getcsv( $matewa_rows[ $matewa_i ] );

	if ( ! isset( $matewa_cols[0] ) ) {
		continue;
	}

	if ( $matewa_cols[0] !== $matewa_site_hash ) {
		$matewa_clean[] = $matewa_rows[ $matewa_i ];
	}
}

// ------------------------------------------------------
// 8. Build new row
// ------------------------------------------------------
$matewa_new_row = array(
	$matewa_site_hash,
	$matewa_email,
	$matewa_updates,
	$matewa_skool,
	$matewa_domain,
	$matewa_locale,
	$matewa_version,
	(string) $matewa_timestamp,
	$matewa_ua,
);

// Escape values for CSV.
$matewa_escaped = array_map(
	static function ( $matewa_value ) {
		return str_replace( '"', '""', trim( (string) $matewa_value ) );
	},
	$matewa_new_row
);

$matewa_clean[] = '"' . implode( '","', $matewa_escaped ) . '"';

// ------------------------------------------------------
// 9. Save CSV file with exclusive lock
// ------------------------------------------------------
file_put_contents(
	$matewa_csv_path,
	implode( "\n", $matewa_clean ) . "\n",
	LOCK_EX
); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents

// ------------------------------------------------------
// 10. Return silent success
// ------------------------------------------------------
status_header( 200 );
exit( 'OK' );