<?php
namespace WooNooW\Api;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use WP_User;
use WC_Customer;

/**
 * CustomersController
 * 
 * Handles customer CRUD operations via REST API
 * 
 * @package WooNooW\Api
 */
class CustomersController {
	
	/**
	 * Register REST API routes
	 */
	public static function register_routes() {
		// List customers
		register_rest_route('woonoow/v1', '/customers', [
			'methods'             => 'GET',
			'callback'            => [__CLASS__, 'list_customers'],
			'permission_callback' => function () { return current_user_can('list_users'); },
		]);
		
		// Get single customer
		register_rest_route('woonoow/v1', '/customers/(?P<id>\d+)', [
			'methods'             => 'GET',
			'callback'            => [__CLASS__, 'get_customer'],
			'permission_callback' => function () { return current_user_can('list_users'); },
		]);
		
		// Create customer
		register_rest_route('woonoow/v1', '/customers', [
			'methods'             => 'POST',
			'callback'            => [__CLASS__, 'create_customer'],
			'permission_callback' => function () { return current_user_can('create_users'); },
		]);
		
		// Update customer
		register_rest_route('woonoow/v1', '/customers/(?P<id>\d+)', [
			'methods'             => 'PUT',
			'callback'            => [__CLASS__, 'update_customer'],
			'permission_callback' => function () { return current_user_can('edit_users'); },
		]);
		
		// Delete customer
		register_rest_route('woonoow/v1', '/customers/(?P<id>\d+)', [
			'methods'             => 'DELETE',
			'callback'            => [__CLASS__, 'delete_customer'],
			'permission_callback' => function () { return current_user_can('delete_users'); },
		]);
		
		// Search customers (for autocomplete)
		register_rest_route('woonoow/v1', '/customers/search', [
			'methods'             => 'GET',
			'callback'            => [__CLASS__, 'search_customers'],
			'permission_callback' => function () { return current_user_can('list_users'); },
		]);
	}
	
	/**
	 * GET /woonoow/v1/customers
	 * List all customers with pagination and filtering
	 */
	public static function list_customers(WP_REST_Request $request): WP_REST_Response {
		$page = max(1, (int) $request->get_param('page') ?: 1);
		$per_page = max(1, min(100, (int) $request->get_param('per_page') ?: 20));
		$search = sanitize_text_field($request->get_param('search') ?: '');
		$role = sanitize_text_field($request->get_param('role') ?: 'customer');
		
		$args = [
			'role'    => $role,
			'number'  => $per_page,
			'paged'   => $page,
			'orderby' => 'registered',
			'order'   => 'DESC',
		];
		
		// Search by name or email
		if ($search) {
			$args['search'] = '*' . $search . '*';
			$args['search_columns'] = ['user_login', 'user_email', 'display_name'];
		}
		
		$user_query = new \WP_User_Query($args);
		$users = $user_query->get_results();
		$total = $user_query->get_total();
		
		$customers = [];
		foreach ($users as $user) {
			$customers[] = self::format_customer($user, true); // Include stats for list view
		}
		
		return new WP_REST_Response([
			'data' => $customers,
			'pagination' => [
				'total'       => $total,
				'total_pages' => ceil($total / $per_page),
				'current'     => $page,
				'per_page'    => $per_page,
			],
		]);
	}
	
	/**
	 * GET /woonoow/v1/customers/{id}
	 * Get single customer by ID
	 */
	public static function get_customer(WP_REST_Request $request): WP_REST_Response|WP_Error {
		$id = (int) $request->get_param('id');
		$user = get_user_by('ID', $id);
		
		if (!$user) {
			return new WP_Error('customer_not_found', __('Customer not found', 'woonoow'), ['status' => 404]);
		}
		
		return new WP_REST_Response(self::format_customer($user, true));
	}
	
	/**
	 * POST /woonoow/v1/customers
	 * Create new customer
	 */
	public static function create_customer(WP_REST_Request $request): WP_REST_Response|WP_Error {
		$data = $request->get_json_params();
		
		// Validate required fields
		if (empty($data['email'])) {
			return new WP_Error('missing_email', __('Email is required', 'woonoow'), ['status' => 400]);
		}
		
		if (empty($data['first_name'])) {
			return new WP_Error('missing_first_name', __('First name is required', 'woonoow'), ['status' => 400]);
		}
		
		if (empty($data['last_name'])) {
			return new WP_Error('missing_last_name', __('Last name is required', 'woonoow'), ['status' => 400]);
		}
		
		// Check if email already exists
		if (email_exists($data['email'])) {
			return new WP_Error('email_exists', __('Email already exists', 'woonoow'), ['status' => 400]);
		}
		
		// Generate username from email if not provided
		$username = !empty($data['username']) ? sanitize_user($data['username']) : sanitize_user($data['email']);
		
		// Check if username exists
		if (username_exists($username)) {
			// Append number to make it unique
			$base_username = $username;
			$counter = 1;
			while (username_exists($username)) {
				$username = $base_username . $counter;
				$counter++;
			}
		}
		
		// Generate password if not provided
		$password = !empty($data['password']) ? $data['password'] : wp_generate_password(12, true, true);
		
		// Create user
		$user_id = wp_create_user($username, $password, sanitize_email($data['email']));
		
		if (is_wp_error($user_id)) {
			return new WP_Error('create_failed', $user_id->get_error_message(), ['status' => 500]);
		}
		
		// Set role to customer
		$user = new WP_User($user_id);
		$user->set_role('customer');
		
		// Update user meta
		wp_update_user([
			'ID'           => $user_id,
			'first_name'   => sanitize_text_field($data['first_name']),
			'last_name'    => sanitize_text_field($data['last_name']),
			'display_name' => sanitize_text_field($data['first_name'] . ' ' . $data['last_name']),
		]);
		
		// Update WooCommerce customer data
		$customer = new WC_Customer($user_id);
		
		// Billing address
		if (!empty($data['billing'])) {
			$billing = $data['billing'];
			$customer->set_billing_first_name(sanitize_text_field($billing['first_name'] ?? $data['first_name']));
			$customer->set_billing_last_name(sanitize_text_field($billing['last_name'] ?? $data['last_name']));
			$customer->set_billing_company(sanitize_text_field($billing['company'] ?? ''));
			$customer->set_billing_address_1(sanitize_text_field($billing['address_1'] ?? ''));
			$customer->set_billing_address_2(sanitize_text_field($billing['address_2'] ?? ''));
			$customer->set_billing_city(sanitize_text_field($billing['city'] ?? ''));
			$customer->set_billing_state(sanitize_text_field($billing['state'] ?? ''));
			$customer->set_billing_postcode(sanitize_text_field($billing['postcode'] ?? ''));
			$customer->set_billing_country(sanitize_text_field($billing['country'] ?? ''));
			$customer->set_billing_phone(sanitize_text_field($billing['phone'] ?? ''));
		}
		
		// Shipping address
		if (!empty($data['shipping'])) {
			$shipping = $data['shipping'];
			$customer->set_shipping_first_name(sanitize_text_field($shipping['first_name'] ?? $data['first_name']));
			$customer->set_shipping_last_name(sanitize_text_field($shipping['last_name'] ?? $data['last_name']));
			$customer->set_shipping_company(sanitize_text_field($shipping['company'] ?? ''));
			$customer->set_shipping_address_1(sanitize_text_field($shipping['address_1'] ?? ''));
			$customer->set_shipping_address_2(sanitize_text_field($shipping['address_2'] ?? ''));
			$customer->set_shipping_city(sanitize_text_field($shipping['city'] ?? ''));
			$customer->set_shipping_state(sanitize_text_field($shipping['state'] ?? ''));
			$customer->set_shipping_postcode(sanitize_text_field($shipping['postcode'] ?? ''));
			$customer->set_shipping_country(sanitize_text_field($shipping['country'] ?? ''));
		}
		
		$customer->save();
		
		// Send new account email if requested
		if (!empty($data['send_email'])) {
			wp_new_user_notification($user_id, null, 'both');
		}
		
		return new WP_REST_Response(self::format_customer(get_user_by('ID', $user_id), true), 201);
	}
	
	/**
	 * PUT /woonoow/v1/customers/{id}
	 * Update existing customer
	 */
	public static function update_customer(WP_REST_Request $request): WP_REST_Response|WP_Error {
		$id = (int) $request->get_param('id');
		$data = $request->get_json_params();
		
		$user = get_user_by('ID', $id);
		if (!$user) {
			return new WP_Error('customer_not_found', __('Customer not found', 'woonoow'), ['status' => 404]);
		}
		
		// Update user data
		$user_data = ['ID' => $id];
		
		if (!empty($data['email'])) {
			// Check if email is changing and if new email exists
			if ($data['email'] !== $user->user_email && email_exists($data['email'])) {
				return new WP_Error('email_exists', __('Email already exists', 'woonoow'), ['status' => 400]);
			}
			$user_data['user_email'] = sanitize_email($data['email']);
		}
		
		if (!empty($data['first_name'])) {
			$user_data['first_name'] = sanitize_text_field($data['first_name']);
		}
		
		if (!empty($data['last_name'])) {
			$user_data['last_name'] = sanitize_text_field($data['last_name']);
		}
		
		if (isset($data['first_name']) || isset($data['last_name'])) {
			$first = $data['first_name'] ?? get_user_meta($id, 'first_name', true);
			$last = $data['last_name'] ?? get_user_meta($id, 'last_name', true);
			$user_data['display_name'] = trim($first . ' ' . $last);
		}
		
		if (!empty($data['password'])) {
			$user_data['user_pass'] = $data['password'];
		}
		
		$result = wp_update_user($user_data);
		if (is_wp_error($result)) {
			return new WP_Error('update_failed', $result->get_error_message(), ['status' => 500]);
		}
		
		// Update WooCommerce customer data
		$customer = new WC_Customer($id);
		
		// Billing address
		if (!empty($data['billing'])) {
			$billing = $data['billing'];
			if (isset($billing['first_name'])) $customer->set_billing_first_name(sanitize_text_field($billing['first_name']));
			if (isset($billing['last_name'])) $customer->set_billing_last_name(sanitize_text_field($billing['last_name']));
			if (isset($billing['company'])) $customer->set_billing_company(sanitize_text_field($billing['company']));
			if (isset($billing['address_1'])) $customer->set_billing_address_1(sanitize_text_field($billing['address_1']));
			if (isset($billing['address_2'])) $customer->set_billing_address_2(sanitize_text_field($billing['address_2']));
			if (isset($billing['city'])) $customer->set_billing_city(sanitize_text_field($billing['city']));
			if (isset($billing['state'])) $customer->set_billing_state(sanitize_text_field($billing['state']));
			if (isset($billing['postcode'])) $customer->set_billing_postcode(sanitize_text_field($billing['postcode']));
			if (isset($billing['country'])) $customer->set_billing_country(sanitize_text_field($billing['country']));
			if (isset($billing['phone'])) $customer->set_billing_phone(sanitize_text_field($billing['phone']));
		}
		
		// Shipping address
		if (!empty($data['shipping'])) {
			$shipping = $data['shipping'];
			if (isset($shipping['first_name'])) $customer->set_shipping_first_name(sanitize_text_field($shipping['first_name']));
			if (isset($shipping['last_name'])) $customer->set_shipping_last_name(sanitize_text_field($shipping['last_name']));
			if (isset($shipping['company'])) $customer->set_shipping_company(sanitize_text_field($shipping['company']));
			if (isset($shipping['address_1'])) $customer->set_shipping_address_1(sanitize_text_field($shipping['address_1']));
			if (isset($shipping['address_2'])) $customer->set_shipping_address_2(sanitize_text_field($shipping['address_2']));
			if (isset($shipping['city'])) $customer->set_shipping_city(sanitize_text_field($shipping['city']));
			if (isset($shipping['state'])) $customer->set_shipping_state(sanitize_text_field($shipping['state']));
			if (isset($shipping['postcode'])) $customer->set_shipping_postcode(sanitize_text_field($shipping['postcode']));
			if (isset($shipping['country'])) $customer->set_shipping_country(sanitize_text_field($shipping['country']));
		}
		
		$customer->save();
		
		return new WP_REST_Response(self::format_customer(get_user_by('ID', $id), true));
	}
	
	/**
	 * DELETE /woonoow/v1/customers/{id}
	 * Delete customer
	 */
	public static function delete_customer(WP_REST_Request $request): WP_REST_Response|WP_Error {
		$id = (int) $request->get_param('id');
		
		$user = get_user_by('ID', $id);
		if (!$user) {
			return new WP_Error('customer_not_found', __('Customer not found', 'woonoow'), ['status' => 404]);
		}
		
		// Don't allow deleting current user
		if ($id === get_current_user_id()) {
			return new WP_Error('cannot_delete_self', __('You cannot delete your own account', 'woonoow'), ['status' => 403]);
		}
		
		require_once(ABSPATH . 'wp-admin/includes/user.php');
		$result = wp_delete_user($id);
		
		if (!$result) {
			return new WP_Error('delete_failed', __('Failed to delete customer', 'woonoow'), ['status' => 500]);
		}
		
		return new WP_REST_Response(['success' => true]);
	}
	
	/**
	 * GET /woonoow/v1/customers/search
	 * Search customers for autocomplete
	 */
	public static function search_customers(WP_REST_Request $request): WP_REST_Response {
		$search = sanitize_text_field($request->get_param('q') ?: '');
		$limit = max(1, min(50, (int) $request->get_param('limit') ?: 10));
		
		if (empty($search)) {
			return new WP_REST_Response([]);
		}
		
		$args = [
			'role'           => 'customer',
			'number'         => $limit,
			'search'         => '*' . $search . '*',
			'search_columns' => ['user_login', 'user_email', 'display_name'],
		];
		
		$user_query = new \WP_User_Query($args);
		$users = $user_query->get_results();
		
		$results = [];
		foreach ($users as $user) {
			$results[] = [
				'id'    => $user->ID,
				'name'  => $user->display_name,
				'email' => $user->user_email,
			];
		}
		
		return new WP_REST_Response($results);
	}
	
	/**
	 * Format customer data for API response
	 */
	private static function format_customer(WP_User $user, bool $detailed = false): array {
		$customer = new WC_Customer($user->ID);
		
		$data = [
			'id'            => $user->ID,
			'username'      => $user->user_login,
			'email'         => $user->user_email,
			'first_name'    => $user->first_name,
			'last_name'     => $user->last_name,
			'display_name'  => $user->display_name,
			'registered'    => $user->user_registered,
			'role'          => !empty($user->roles) ? $user->roles[0] : '',
		];
		
		if ($detailed) {
			$data['billing'] = [
				'first_name' => $customer->get_billing_first_name(),
				'last_name'  => $customer->get_billing_last_name(),
				'company'    => $customer->get_billing_company(),
				'address_1'  => $customer->get_billing_address_1(),
				'address_2'  => $customer->get_billing_address_2(),
				'city'       => $customer->get_billing_city(),
				'state'      => $customer->get_billing_state(),
				'postcode'   => $customer->get_billing_postcode(),
				'country'    => $customer->get_billing_country(),
				'phone'      => $customer->get_billing_phone(),
			];
			
			$data['shipping'] = [
				'first_name' => $customer->get_shipping_first_name(),
				'last_name'  => $customer->get_shipping_last_name(),
				'company'    => $customer->get_shipping_company(),
				'address_1'  => $customer->get_shipping_address_1(),
				'address_2'  => $customer->get_shipping_address_2(),
				'city'       => $customer->get_shipping_city(),
				'state'      => $customer->get_shipping_state(),
				'postcode'   => $customer->get_shipping_postcode(),
				'country'    => $customer->get_shipping_country(),
			];
			
			// Get order stats
			$orders = wc_get_orders([
				'customer_id' => $user->ID,
				'limit'       => -1,
				'status'      => ['wc-completed', 'wc-processing'],
			]);
			
			$total_spent = 0;
			foreach ($orders as $order) {
				$total_spent += $order->get_total();
			}
			
			$data['stats'] = [
				'total_orders' => count($orders),
				'total_spent'  => $total_spent,
			];
		}
		
		return $data;
	}
}
