<?php
/**
 * Customer Sync Class
 *
 * @package FunnelKit_Square
 */

namespace FKWCSQ\Includes\Sync;

use FKWCSQ\Includes\Traits\Instance;
use WC_Customer;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * Handles customer synchronization between WooCommerce and Square
 */
class Customer {
	use Instance;

	/**
	 * Square API instance
	 *
	 * @var \FKWCSQ\Includes\API
	 */
	private $api;

	/**
	 * Instance of this class
	 *
	 * @var Customer
	 */
	private static $instance = null;

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->api = \FKWCSQ\Includes\API::get_instance();
	}

	/**
	 * Sync all customers to Square
	 *
	 * @return array Summary of sync results
	 */
	public function sync_all_customers_to_square() {
		// Get all customer IDs
		$customer_query = new \WP_User_Query(
			array(
				'role'   => 'customer',
				'fields' => 'ID',
				'number' => -1,
			)
		);

		$customer_ids = $customer_query->get_results();

		if ( empty( $customer_ids ) ) {
			return array(
				'total'       => 0,
				'success'     => 0,
				'failed'      => 0,
				'success_ids' => array(),
				'failed_ids'  => array(),
				'errors'      => array(),
			);
		}

		$success_count = 0;
		$failed_count  = 0;
		$success_ids   = array();
		$failed_ids    = array();
		$errors        = array();
		$total_count   = count( $customer_ids );

		// Process each customer
		foreach ( $customer_ids as $customer_id ) {
			try {
				$result = $this->sync_customer_to_square( $customer_id );
				if ( $result ) {
					++$success_count;
					$success_ids[] = $customer_id;
				} else {
					++$failed_count;
					$failed_ids[] = $customer_id;
					$errors[]     = sprintf( 'Customer ID %d: sync failed', $customer_id );
				}
			} catch ( \Exception $e ) {
				++$failed_count;
				$failed_ids[] = $customer_id;
				$errors[]     = sprintf( 'Customer ID %d: %s', $customer_id, $e->getMessage() );
			}

			// Optional: Add a small delay to avoid API rate limits
			usleep( 200000 ); // 200ms pause between requests
		}

		return array(
			'total'       => $total_count,
			'success'     => $success_count,
			'failed'      => $failed_count,
			'success_ids' => $success_ids,
			'failed_ids'  => $failed_ids,
			'errors'      => $errors,
		);
	}

	/**
	 * Manually trigger a sync of all customers to Square
	 *
	 * @return bool Success status
	 */
	public function trigger_manual_sync() {
		return $this->sync_all_customers_to_square();
	}

	/**
	 * Synchronize customer from WooCommerce to Square
	 *
	 * @param int $customer_id The WooCommerce customer ID
	 *
	 * @return bool Success status
	 */
	public function sync_customer_to_square( $customer_id ) {
		try {
			$customer = new \WC_Customer( $customer_id );
			if ( ! $customer ) {
				return false;
			}

			// Format customer data for Square
			$customer_data = array(
				'given_name'    => $customer->get_first_name(),
				'family_name'   => $customer->get_last_name(),
				'email_address' => $customer->get_email(),
				'phone_number'  => $customer->get_billing_phone(),
				'address'       => array(
					'address_line_1'                  => $customer->get_billing_address_1(),
					'address_line_2'                  => $customer->get_billing_address_2(),
					'locality'                        => $customer->get_billing_city(),
					'administrative_district_level_1' => $customer->get_billing_state(),
					'postal_code'                     => $customer->get_billing_postcode(),
					'country'                         => $customer->get_billing_country(),
				),
			);
			// Check if customer already exists in Square
			$square_customer_id = get_user_meta( $customer_id, '_square_customer_id', true );
			if ( $square_customer_id ) {
				// Update existing customer
				$result = $this->api->update_customer( $square_customer_id, $customer_data );
			} else {
				// Create new customer
				$result = $this->api->create_customer( $customer_data );
				if ( ! is_wp_error( $result ) && ! empty( $result['customer']['id'] ) ) {
					update_user_meta( $customer_id, '_square_customer_id', $result['customer']['id'] );
				}
			}

			// Check if result is WP_Error
			if ( is_wp_error( $result ) ) {
				return false;
			}

			return ( ! empty( $result ) && ! isset( $result['errors'] ) );
		} catch ( \Exception | \Error $e ) {
			return false;
		}
	}

	/**
	 * Synchronize customer from Square to WooCommerce
	 *
	 * @param string $square_customer_id The Square customer ID
	 *
	 * @return bool Success status
	 */
	public function sync_customer_from_square( $square_customer_id ) {
		// Get customer data from Square
		$square_customer = $this->api->get_customer( $square_customer_id );

		if ( is_wp_error( $square_customer ) || empty( $square_customer['customer'] ) ) {
			return false;
		}

		$customer_data = $square_customer['customer'];

		// Find existing WooCommerce customer by email
		$user = get_user_by( 'email', $customer_data['email_address'] );

		if ( $user ) {
			// Update existing customer
			$customer = new WC_Customer( $user->ID );
		} else {
			// Create new customer
			$username = $this->generate_username( $customer_data['given_name'], $customer_data['family_name'] );
			$password = wp_generate_password();

			$user_id = wc_create_new_customer( $customer_data['email_address'], $username, $password );

			if ( is_wp_error( $user_id ) ) {
				return false;
			}

			$customer = new \WC_Customer( $user_id );
		}

		// Update customer data
		$customer->set_first_name( $customer_data['given_name'] );
		$customer->set_last_name( $customer_data['family_name'] );
		$customer->set_billing_phone( $customer_data['phone_number'] );

		if ( ! empty( $customer_data['address'] ) ) {
			$address = $customer_data['address'];
			$customer->set_billing_address_1( $address['address_line_1'] );
			$customer->set_billing_address_2( $address['address_line_2'] );
			$customer->set_billing_city( $address['locality'] );
			$customer->set_billing_state( $address['administrative_district_level_1'] );
			$customer->set_billing_postcode( $address['postal_code'] );
			$customer->set_billing_country( $address['country'] );
		}

		$customer->save();

		// Store Square customer ID
		update_user_meta( $customer->get_id(), '_square_id', $square_customer_id );

		return true;
	}

	/**
	 * Handle customer deletion
	 *
	 * @param int $customer_id The WooCommerce customer ID
	 *
	 * @return bool Success status
	 */
	public function on_customer_delete( $customer_id ) {
		$square_customer_id = get_user_meta( $customer_id, '_square_customer_id', true );
		if ( ! $square_customer_id ) {
			return false;
		}

		// Delete customer from Square
		$result = $this->api->delete_customer( $square_customer_id );

		// Remove Square customer ID meta
		delete_user_meta( $customer_id, '_square_customer_id' );

		// Check if result is WP_Error
		if ( is_wp_error( $result ) ) {
			return false;
		}

		return ( ! empty( $result ) && ! isset( $result['errors'] ) );
	}

	/**
	 * Generate a unique username
	 *
	 * @param string $first_name Customer first name
	 * @param string $last_name Customer last name
	 *
	 * @return string Generated username
	 */
	protected function generate_username( $first_name, $last_name ) {
		$base_username = sanitize_user( $first_name . $last_name, true );
		$username      = $base_username;
		$counter       = 1;

		while ( username_exists( $username ) ) {
			$username = $base_username . $counter;
			++$counter;
		}

		return $username;
	}
}
