<?php

namespace PixelioCartAbandonRecoveryMore\Frontend\Repositories;

use PixelioCartAbandonRecoveryMore\Includes\Utils\Pixelio_Cart_Abandon_Recovery_More_Util;

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

class Pixelio_Cart_Abandon_Recovery_More_User_Consent_Repository
{
	private string $contacts_table;
	private string $preferences_table;
	private string $consent_logs_table;
	private string $suppression_table;
	private mixed $pixelio_wordpress_wrapper;
	private mixed $wpdb;

	public function __construct($pixelio_wordpress_wrapper)
	{
		$this->wpdb = $pixelio_wordpress_wrapper->pixelio_get_wpdb();
		$this->pixelio_wordpress_wrapper = $pixelio_wordpress_wrapper;
		$this->preferences_table  = $this->wpdb->prefix . Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_plugin_db_prefix . 'email_preferences';
		$this->contacts_table     = $this->wpdb->prefix .  Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_plugin_db_prefix .'contacts';
		$this->consent_logs_table = $this->wpdb->prefix .Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_plugin_db_prefix . 'consent_logs';
		$this->suppression_table  = $this->wpdb->prefix . Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_plugin_db_prefix .'suppression_list';
	}

	/* =====================================================
	 * CONTACT MANAGEMENT
	 * ===================================================== */

	private function pixelio_get_or_create_contact(string $email,$utm_source="",
																  $utm_campaign="",$utm_medium=""): ?int
	{

		$email = strtolower(trim($email));
		if (!$this->pixelio_wordpress_wrapper->pixelio_is_email($email)) return null;

		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare(
				"SELECT id FROM {$this->contacts_table} WHERE email = %s LIMIT 1",
				$email
			)
		);

		if ($contact) {
			return (int)$contact->id;
		}

		$email_hash = hash('sha256', $email);

		$this->wpdb->insert(
			$this->contacts_table,
			[
				'email'      => $email,
				'email_hash' => $email_hash,
				'first_utm_source' => $utm_source,
				'first_utm_campaign' => $utm_campaign,
				'first_utm_medium' => $utm_medium,
				'created_at' =>  $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%s', '%s', '%s','%s','%s','%s','%s']
		);

		return $this->wpdb->insert_id ?: null;
	}


	/* =====================================================
	 * CONSENT LOGGING (RGPD PROOF)
	 * ===================================================== */

	public function pixelio_save_consent(string $email, string $consent_type,string $consent_definition, bool $given,$utm_source,
																											  $utm_campaign,$utm_medium): int
	{
		$contact_id = $this->pixelio_get_or_create_contact($email,$utm_source,
			$utm_campaign,$utm_medium);
		if (!$contact_id) return false;

		$this->wpdb->insert(
			$this->consent_logs_table,
			[
				'contact_id'        => $contact_id,
				'consent_type'      => $consent_type,
				'consent_definition'=> $consent_definition,
				'ip_address'        => $given ? $_SERVER['REMOTE_ADDR'] ?? null : null,
				'user_agent'        => $given ? $_SERVER['HTTP_USER_AGENT'] ?? null : null,
				'consent_given'     => $given ? 1 : 0,
				'created_at'        => $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%d','%s','%s','%s','%s','%d','%s']
		);
		$this->pixelio_set_email_preference( $email, $consent_type, $given,$utm_source,
			$utm_campaign,$utm_medium );
		return $contact_id;
	}




	public function pixelio_is_subscribed($email, string $email_type): bool
	{

		$email = strtolower(trim($email));
		$email_hash = hash('sha256', $email);

		// 1️⃣ suppression list check
		$blocked = $this->wpdb->get_var(
			$this->wpdb->prepare(
				"SELECT id FROM {$this->suppression_table} WHERE email_hash = %s LIMIT 1",
				$email_hash
			)
		);

		if ($blocked) return false;

		// 2️⃣ global unsubscribe
		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare(
				"SELECT id, global_unsubscribed FROM {$this->contacts_table} WHERE email = %s LIMIT 1",
				$email
			)
		);

		if (!$contact || $contact->global_unsubscribed) return false;

		// 3️⃣ email type preference
		$pref = $this->wpdb->get_var(
			$this->wpdb->prepare(
				"SELECT is_subscribed FROM {$this->preferences_table}
                 WHERE contact_id = %d AND email_type = %s LIMIT 1",
				$contact->id,
				$email_type
			)
		);

		return $pref === null ? true : (bool)$pref;
	}

	/* =====================================================
	 * EMAIL TYPE SUBSCRIPTION
	 * ===================================================== */

	public function pixelio_set_email_preference(string $email, string $email_type, bool $subscribed,$utm_source,
																						 $utm_campaign,$utm_medium): bool
	{

		$contact_id = $this->pixelio_get_or_create_contact($email,$utm_source,
			$utm_campaign,$utm_medium);
		if (!$contact_id) return false;

		return (bool) $this->wpdb->replace(
			$this->preferences_table,
			[
				'contact_id'   => $contact_id,
				'email_type'   => $email_type,
				'is_subscribed'=> $subscribed ? 1 : 0,
				'updated_at'   => $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%d','%s','%d','%s']
		);
	}
	public function pixelio_get_user_id_by_email(string $email,$utm_source,
														$utm_campaign,$utm_medium): ?int
	{

		$email = strtolower(trim($email));

		if (empty($email) || !$this->pixelio_wordpress_wrapper->pixelio_is_email($email)) {
			return null;
		}

		$user_id = $this->wpdb->get_var(
			$this->wpdb->prepare(
				"SELECT id
             FROM {$this->contacts_table}
             WHERE email = %s
             LIMIT 1",
				$email
			)
		);

		if ($user_id) {
			return (int) $user_id;
		}

		// 🔁 Fallback create si non trouvé dans ta table
		return $this->pixelio_get_or_create_contact( $email,$utm_source,
			$utm_campaign,$utm_medium);
	}

	/* =====================================================
	 * GLOBAL UNSUBSCRIBE
	 * ===================================================== */

	public function pixelio_unsubscribe(string $email): bool
	{

		$email = strtolower(trim($email));
		if (!$this->pixelio_wordpress_wrapper->pixelio_is_email($email)) return false;

		$email_hash = hash('sha256', $email);

		$contact_id = $this->pixelio_get_or_create_contact($email,"unsubscribe_email",
			"email","email");
		if (!$contact_id) return false;

		// 1️⃣ set global flag
		$this->wpdb->update(
			$this->contacts_table,
			[
				'global_unsubscribed' => 1
			],
			['id' => $contact_id],
			['%d'],
			['%d']
		);

		// 2️⃣ add to suppression list
		$this->wpdb->replace(
			$this->suppression_table,
			[
				'email_hash' => $email_hash,
				'reason'     => 'user_unsubscribe',
				'created_at' => $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%s','%s','%s']
		);

		return true;
	}

	/* =====================================================
	 * GDPR ERASE (ANONYMISATION)
	 * ===================================================== */

	public function pixelio_anonymize_contact(string $email): bool
	{

		$email = strtolower(trim($email));
		$email_hash = hash('sha256', $email);

		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare(
				"SELECT id FROM {$this->contacts_table} WHERE email = %s LIMIT 1",
				$email
			)
		);

		if (!$contact) return false;

		// anonymize
		$this->wpdb->update(
			$this->contacts_table,
			[
				'email'      => 'deleted_' . $contact->id . '@anonymized.local',
				'deleted_at' => $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['id' => $contact->id],
			['%s','%s'],
			['%d']
		);

		// ensure suppression stays
		$this->wpdb->replace(
			$this->suppression_table,
			[
				'email_hash' => $email_hash,
				'reason'     => 'gdpr_erasure',
				'created_at' =>  $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%s','%s','%s']
		);

		$this->wpdb->insert(
			$this->consent_logs_table,
			[
				'contact_id' => $contact->id,
				'consent_type' => 'gdpr_erasure',
				'consent_definition' => 'User requested personal data anonymization',
				'ip_address' => null,
				'user_agent' => null,
				'consent_given' => 0,
				'created_at' => $this->pixelio_wordpress_wrapper->pixelio_current_time()
			],
			['%d', '%s', '%s', '%s', '%s', '%d', '%s']
		);

		return true;
	}

	/**
	 * Get email by WordPress user_id.
	 *
	 * @param int|null $pixelio_user_id
	 * @return string|null
	 */
	public function pixelio_get_email_by_user_id(?int $pixelio_user_id): ?string
	{

		if (empty($pixelio_user_id) || $pixelio_user_id <= 0) {
			return null;
		}

		$email = $this->wpdb->get_var(
			$this->wpdb->prepare(
				"SELECT email
             FROM {$this->contacts_table}
             WHERE id = %d
             LIMIT 1",
				$pixelio_user_id
			)
		);

		return $email ? (string) $email : "";
	}


	public function pixelio_get_rgpd_contacts(): array
	{
		return $this->wpdb->get_results("
		SELECT
			c.id,
			c.email,
			c.email_hash,
			c.global_unsubscribed,
			c.created_at,
			c.deleted_at,
			COUNT(cl.id) AS consent_count
		FROM {$this->contacts_table} c
		LEFT JOIN {$this->consent_logs_table} cl ON cl.contact_id = c.id
		GROUP BY c.id
		ORDER BY c.created_at DESC
		LIMIT 1000
	");
	}

	public function pixelio_get_rgpd_stats(): object
	{
		return (object) [
			'total' => (int) $this->wpdb->get_var("SELECT COUNT(*) FROM {$this->contacts_table}"),
			'active' => (int) $this->wpdb->get_var("SELECT COUNT(*) FROM {$this->contacts_table} WHERE global_unsubscribed = 0 AND deleted_at IS NULL"),
			'unsubscribed' => (int) $this->wpdb->get_var("SELECT COUNT(*) FROM {$this->contacts_table} WHERE global_unsubscribed = 1"),
			'anonymized' => (int) $this->wpdb->get_var("SELECT COUNT(*) FROM {$this->contacts_table} WHERE deleted_at IS NOT NULL"),
		];
	}

	public function pixelio_get_contact_export_by_id(int $contact_id): array
	{
		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare("SELECT * FROM {$this->contacts_table} WHERE id = %d", $contact_id)
		);

		if (!$contact) {
			return [];
		}

		$preferences = $this->wpdb->get_results(
			$this->wpdb->prepare("SELECT * FROM {$this->preferences_table} WHERE contact_id = %d", $contact_id)
		);

		$consents = $this->wpdb->get_results(
			$this->wpdb->prepare("SELECT * FROM {$this->consent_logs_table} WHERE contact_id = %d ORDER BY created_at DESC", $contact_id)
		);

		return [
			'contact' => $contact,
			'preferences' => $preferences,
			'consents' => $consents,
			'exported_at' => $this->pixelio_wordpress_wrapper->pixelio_current_time(),
		];
	}

	public function pixelio_unsubscribe_by_contact_id(int $contact_id): bool
	{
		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare("SELECT email FROM {$this->contacts_table} WHERE id = %d", $contact_id)
		);

		if (!$contact || empty($contact->email)) {
			return false;
		}

		return $this->pixelio_unsubscribe($contact->email);
	}

	public function pixelio_anonymize_contact_by_id(int $contact_id): bool
	{
		$contact = $this->wpdb->get_row(
			$this->wpdb->prepare("SELECT email FROM {$this->contacts_table} WHERE id = %d", $contact_id)
		);

		if (!$contact || empty($contact->email)) {
			return false;
		}

		return $this->pixelio_anonymize_contact($contact->email);
	}

}
