<?php
/**
 * Leads (Premium Module)
 *
 * @package Replyan_AI
 */

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

final class Replyan_AI_Leads {
	public function register_hooks(): void {
		add_action( 'wp_ajax_replyan_ai_get_lead', array( $this, 'get_lead' ) );
		add_action( 'wp_ajax_replyan_ai_save_lead', array( $this, 'save_lead' ) );
		add_action( 'wp_ajax_replyan_ai_get_leads', array( $this, 'get_leads' ) );
		add_action( 'wp_ajax_replyan_ai_export_leads', array( $this, 'export_leads' ) );
	}

	/**
	 * Create the leads table.
	 */
	public static function create_table(): void {
		global $wpdb;
		$charset_collate = $wpdb->get_charset_collate();
		$table           = $wpdb->prefix . 'replyan_ai_leads';

		$sql = "CREATE TABLE {$table} (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			session_id VARCHAR(64) NOT NULL,
			first_name VARCHAR(100) DEFAULT '',
			last_name VARCHAR(100) DEFAULT '',
			email VARCHAR(255) DEFAULT '',
			phone VARCHAR(50) DEFAULT '',
			address TEXT,
			postal_code VARCHAR(20) DEFAULT '',
			created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY  (id),
			UNIQUE KEY session_id (session_id)
		) {$charset_collate};";

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		dbDelta( $sql );
	}

	/**
	 * Get lead info for a session.
	 *
	 * @param string $session_id Session identifier.
	 * @return array|null
	 */
	public static function db_get_lead( string $session_id ) {
		global $wpdb;
		$table = $wpdb->prefix . 'replyan_ai_leads';
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$row = $wpdb->get_row(
			$wpdb->prepare( "SELECT * FROM {$table} WHERE session_id = %s", $session_id ),
			ARRAY_A
		);
		// phpcs:enable
		return $row;
	}

	/**
	 * Get all leads with pagination.
	 *
	 * @param int    $page     Page number (1-indexed).
	 * @param int    $per_page Items per page.
	 * @param string $search   Optional search term for name/email.
	 * @return array { total: int, leads: array }
	 */
	public static function db_get_leads( int $page = 1, int $per_page = 20, string $search = '' ): array {
		global $wpdb;
		$table  = $wpdb->prefix . 'replyan_ai_leads';
		$offset = ( $page - 1 ) * $per_page;

		$where = '';
		$args  = array();

		if ( ! empty( $search ) ) {
			$like  = '%' . $wpdb->esc_like( $search ) . '%';
			$where = 'WHERE first_name LIKE %s OR last_name LIKE %s OR email LIKE %s';
			$args  = array( $like, $like, $like );
		}

		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
		$count_sql = "SELECT COUNT(*) FROM {$table} {$where}";
		$total     = empty( $args )
			? (int) $wpdb->get_var( $count_sql )
			: (int) $wpdb->get_var( $wpdb->prepare( $count_sql, ...$args ) );

		$query_args   = array_merge( $args, array( $per_page, $offset ) );
		$leads_sql    = "SELECT * FROM {$table} {$where} ORDER BY created_at DESC LIMIT %d OFFSET %d";
		$leads        = $wpdb->get_results( $wpdb->prepare( $leads_sql, ...$query_args ), ARRAY_A );
		// phpcs:enable

		return array(
			'total' => $total,
			'leads' => $leads ?: array(),
		);
	}

	/**
	 * Save lead info for a session.
	 *
	 * @param string $session_id Session identifier.
	 * @param array  $data       Lead data.
	 * @return bool
	 */
	public static function db_save_lead( string $session_id, array $data ): bool {
		global $wpdb;
		$table = $wpdb->prefix . 'replyan_ai_leads';

		$exists = self::db_get_lead( $session_id );

		$lead_data = array(
			'session_id'  => $session_id,
			'first_name'  => sanitize_text_field( $data['first_name'] ?? '' ),
			'last_name'   => sanitize_text_field( $data['last_name'] ?? '' ),
			'email'       => sanitize_email( $data['email'] ?? '' ),
			'phone'       => sanitize_text_field( $data['phone'] ?? '' ),
			'address'     => sanitize_textarea_field( $data['address'] ?? '' ),
			'postal_code' => sanitize_text_field( $data['postal_code'] ?? '' ),
			'updated_at'  => current_time( 'mysql' ),
		);

		if ( $exists ) {
			// Merge existing data so we don't overwrite with empty strings
			foreach ( array( 'first_name', 'last_name', 'email', 'phone', 'address', 'postal_code' ) as $field ) {
				if ( empty( $lead_data[ $field ] ) && ! empty( $exists[ $field ] ) ) {
					$lead_data[ $field ] = $exists[ $field ];
				}
			}
		}

		$saved = false;
		if ( $exists ) {
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$updated = $wpdb->update(
				$table,
				$lead_data,
				array( 'session_id' => $session_id ),
				array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ),
				array( '%s' )
			);
			// phpcs:enable
			$saved = $updated !== false;
		} else {
			$lead_data['created_at'] = current_time( 'mysql' );
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$inserted = $wpdb->insert(
				$table,
				$lead_data,
				array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )
			);
			// phpcs:enable
			$saved = $inserted !== false;
		}

		if ( $saved ) {
			// Synchronize to the sessions table so the guest name changes persist
			$sessions_table = $wpdb->prefix . 'replyan_ai_sessions';
			$session_name   = trim( $lead_data['first_name'] . ' ' . $lead_data['last_name'] );
			$session_email  = $lead_data['email'];

			$wpdb->update(
				$sessions_table,
				array(
					'user_name'  => $session_name,
					'user_email' => $session_email,
				),
				array( 'session_id' => $session_id ),
				array( '%s', '%s' ),
				array( '%s' )
			);
		}

		return $saved;
	}

	public function get_lead(): void {
		check_ajax_referer( 'replyan_ai_admin_messages', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		$session_id = sanitize_text_field( wp_unslash( $_POST['session_id'] ?? '' ) );
		if ( empty( $session_id ) ) {
			wp_send_json_error( array( 'message' => 'Missing session' ) );
		}

		$lead = self::db_get_lead( $session_id );
		wp_send_json_success( array( 'lead' => $lead ) );
	}

	public function save_lead(): void {
		check_ajax_referer( 'replyan_ai_admin_messages', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		$session_id = sanitize_text_field( wp_unslash( $_POST['session_id'] ?? '' ) );
		if ( empty( $session_id ) ) {
			wp_send_json_error( array( 'message' => 'Missing session' ) );
		}

		$data = array(
			'first_name'  => sanitize_text_field( wp_unslash( $_POST['first_name'] ?? '' ) ),
			'last_name'   => sanitize_text_field( wp_unslash( $_POST['last_name'] ?? '' ) ),
			'email'       => sanitize_email( wp_unslash( $_POST['email'] ?? '' ) ),
			'phone'       => sanitize_text_field( wp_unslash( $_POST['phone'] ?? '' ) ),
			'address'     => sanitize_textarea_field( wp_unslash( $_POST['address'] ?? '' ) ),
			'postal_code' => sanitize_text_field( wp_unslash( $_POST['postal_code'] ?? '' ) ),
		);

		$saved = self::db_save_lead( $session_id, $data );
		if ( $saved ) {
			wp_send_json_success( array( 'message' => 'Lead saved successfully' ) );
		} else {
			wp_send_json_error( array( 'message' => 'Failed to save lead' ) );
		}
	}

	/**
	 * AJAX handler: retrieve all leads with pagination.
	 */
	public function get_leads(): void {
		check_ajax_referer( 'replyan_ai_admin_messages', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
		}

		$page     = max( 1, (int) ( isset( $_POST['page'] ) ? sanitize_text_field( wp_unslash( $_POST['page'] ) ) : 1 ) );
		$per_page = min( 100, max( 1, (int) ( isset( $_POST['per_page'] ) ? sanitize_text_field( wp_unslash( $_POST['per_page'] ) ) : 20 ) ) );
		$search   = sanitize_text_field( wp_unslash( $_POST['search'] ?? '' ) );

		$result = self::db_get_leads( $page, $per_page, $search );

		wp_send_json_success( array(
			'leads'    => $result['leads'],
			'total'    => $result['total'],
			'page'     => $page,
			'per_page' => $per_page,
		) );
	}

	/**
	 * AJAX handler: export all leads as CSV.
	 */
	public function export_leads(): void {
		if ( empty( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'replyan_ai_admin_messages' ) ) {
			wp_die( 'Unauthorized' );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( 'Unauthorized' );
		}

		global $wpdb;
		$table = $wpdb->prefix . 'replyan_ai_leads';
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
		$leads = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY created_at DESC", ARRAY_A );

		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename=replyan-ai-leads-' . gmdate( 'Y-m-d' ) . '.csv' );

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
		$output = fopen( 'php://output', 'w' );
		fputcsv( $output, array( 'First Name', 'Last Name', 'Email', 'Phone', 'Address', 'Postal Code', 'Date' ) );

		if ( $leads ) {
			foreach ( $leads as $lead ) {
				fputcsv( $output, array(
					$lead['first_name'],
					$lead['last_name'],
					$lead['email'],
					$lead['phone'],
					$lead['address'],
					$lead['postal_code'],
					$lead['created_at'],
				) );
			}
		}

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
		fclose( $output );
		exit;
	}
}
