<?php

declare(strict_types=1);

namespace FormConnector\API\Endpoints;

use FormConnector\Features\Homes\Homes;
use FormConnector\Features\License\License;

/**
 * Homes management REST API endpoints.
 */
class HomesEndpoints {

	private const NAMESPACE = 'fc/v1';

	/**
	 * Register homes routes.
	 */
	public static function register(): void {
		register_rest_route(self::NAMESPACE, '/homes', [
			'methods' => \WP_REST_Server::READABLE,
			'callback' => [self::class, 'get_homes'],
			'permission_callback' => [self::class, 'permission_check'],
		]);

		register_rest_route(self::NAMESPACE, '/homes/add', [
			'methods' => \WP_REST_Server::CREATABLE,
			'callback' => [self::class, 'add_home'],
			'permission_callback' => [self::class, 'permission_check'],
			'args' => [
				'homeId' => [
					'required' => true,
					'type' => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				],
				'name' => [
					'required' => true,
					'type' => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				],
				'provider' => [
					'required' => false,
					'type' => 'string',
					'sanitize_callback' => 'sanitize_text_field',
					'default' => 'CareHQ',
				],
			],
		]);

		register_rest_route(self::NAMESPACE, '/homes/remove', [
			'methods' => \WP_REST_Server::CREATABLE,
			'callback' => [self::class, 'remove_home'],
			'permission_callback' => [self::class, 'permission_check'],
			'args' => [
				'homeId' => [
					'required' => true,
					'type' => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				],
			],
		]);

		register_rest_route(self::NAMESPACE, '/homes/sync', [
			'methods' => \WP_REST_Server::CREATABLE,
			'callback' => [self::class, 'sync_homes'],
			'permission_callback' => [self::class, 'permission_check'],
		]);

		register_rest_route(self::NAMESPACE, '/homes/refresh', [
			'methods' => \WP_REST_Server::CREATABLE,
			'callback' => [self::class, 'refresh_homes'],
			'permission_callback' => [self::class, 'permission_check'],
		]);

		register_rest_route(self::NAMESPACE, '/homes/reorder', [
			'methods' => \WP_REST_Server::CREATABLE,
			'callback' => [self::class, 'reorder_homes'],
			'permission_callback' => [self::class, 'permission_check'],
		]);
	}

	/**
	 * Permission check for admin-only endpoints.
	 */
	public static function permission_check(): bool {
		return current_user_can('manage_options');
	}

	/**
	 * Get all homes.
	 */
	public static function get_homes(\WP_REST_Request $request): \WP_REST_Response {
		$homes = new Homes();
		$result = $homes->get_homes();

		// Enrich with active/over-limit seat info and sort by priority
		if ($result['success']) {
			self::normalize_result_data($result, $homes);
		}

		$status = $result['success'] ? 200 : (($result['license_error'] ?? false) ? 403 : 400);
		return new \WP_REST_Response($result, $status);
	}

	/**
	 * Normalize subscription fields, add seat status, and sort by local priority.
	 */
	private static function normalize_result_data(array &$result, Homes $homes): void {
		$homes_list = $result['data']['homes'] ?? [];
		$result['data']['subscription'] = Homes::normalize_subscription($result['data']['subscription'] ?? null, count($homes_list));

		$seat_info = $homes->get_active_home_ids();
		$result['data']['seatStatus'] = [
			'isOverLimit' => $seat_info['is_over_limit'],
			'overLimitCount' => $seat_info['over_limit_count'],
			'activeHomeIds' => $seat_info['active_home_ids'],
			'isUnlimited' => $seat_info['is_unlimited'],
		];

		// Sort homes by user priority order
		$result['data']['homes'] = self::sort_homes_by_priority($homes_list, $homes);
	}

	/**
	 * Sort homes array by saved priority order.
	 */
	private static function sort_homes_by_priority(array $homes_list, Homes $homes_manager): array {
		$priority = $homes_manager->get_home_priority();

		if (empty($priority)) {
			return $homes_list;
		}

		// Build lookup: homeId => home object
		$lookup = [];
		foreach ($homes_list as $home) {
			$lookup[$home['homeId'] ?? ''] = $home;
		}

		$ordered = [];
		// First: homes in priority order
		foreach ($priority as $home_id) {
			if (isset($lookup[$home_id])) {
				$ordered[] = $lookup[$home_id];
				unset($lookup[$home_id]);
			}
		}
		// Then: remaining homes not in priority list
		foreach ($lookup as $home) {
			$ordered[] = $home;
		}

		return $ordered;
	}

	/**
	 * Add a new home.
	 */
	public static function add_home(\WP_REST_Request $request): \WP_REST_Response {
		// Require valid license for this operation
		$license = new License();
		$license_error = $license->require_license();
		if ($license_error !== null) {
			return $license_error;
		}

		$homes = new Homes();
		$result = $homes->add_home([
			'homeId' => $request->get_param('homeId'),
			'name' => $request->get_param('name'),
			'provider' => $request->get_param('provider') ?? 'CareHQ',
		]);

		// Return refreshed homes + seat status so Frontend updates in one round trip
		if ($result['success']) {
			$refreshed = $homes->get_homes(true);
			if ($refreshed['success']) {
				$result['data'] = $refreshed['data'];
				self::normalize_result_data($result, $homes);
			}
		}

		$status = $result['success'] ? 200 : (($result['license_error'] ?? false) ? 403 : 400);
		return new \WP_REST_Response($result, $status);
	}

	/**
	 * Remove a home.
	 */
	public static function remove_home(\WP_REST_Request $request): \WP_REST_Response {
		$homes = new Homes();
		$result = $homes->remove_home($request->get_param('homeId'));

		// Return refreshed homes + seat status so frontend updates in one round trip
		if ($result['success']) {
			$refreshed = $homes->get_homes(true);
			if ($refreshed['success']) {
				$result['data'] = $refreshed['data'];
				self::normalize_result_data($result, $homes);
			}
		}

		$status = $result['success'] ? 200 : (($result['license_error'] ?? false) ? 403 : 400);
		return new \WP_REST_Response($result, $status);
	}

	/**
	 * Sync all homes.
	 */
	public static function sync_homes(\WP_REST_Request $request): \WP_REST_Response {
		$homes_manager = new Homes();
		$homes_data = $request->get_param('homes');
		
		if (empty($homes_data) || !is_array($homes_data)) {
			return new \WP_REST_Response([
				'success' => false,
				'error' => 'invalid_data',
				'message' => __('No homes data provided.', 'form-connector'),
			], 400);
		}

		$result = $homes_manager->sync_homes($homes_data);
		
		$status = $result['success'] ? 200 : (($result['license_error'] ?? false) ? 403 : 400);
		return new \WP_REST_Response($result, $status);
	}

	/**
	 * Force refresh homes from API.
	 */
	public static function refresh_homes(\WP_REST_Request $request): \WP_REST_Response {
		$homes = new Homes();
		$result = $homes->get_homes(true);

		// Enrich with active/over-limit seat info and sort by priority
		if ($result['success']) {
			self::normalize_result_data($result, $homes);
		}

		$status = $result['success'] ? 200 : (($result['license_error'] ?? false) ? 403 : 400);
		return new \WP_REST_Response($result, $status);
	}

	/**
	 * Reorder homes priority (determines which homes stay active when over seat limit).
	 */
	public static function reorder_homes(\WP_REST_Request $request): \WP_REST_Response {
		$home_ids = $request->get_param('homeIds');

		if (empty($home_ids) || !is_array($home_ids)) {
			return new \WP_REST_Response([
				'success' => false,
				'error' => 'invalid_data',
				'message' => __('No home IDs provided.', 'form-connector'),
			], 400);
		}

		$homes = new Homes();
		$result = $homes->save_home_priority($home_ids);

		if ($result['success']) {
			// Re-fetch to return updated data with new priority
			$homes_result = $homes->get_homes(true);
			if ($homes_result['success']) {
				$result['data'] = $homes_result['data'];
				self::normalize_result_data($result, $homes);
			}
		}

		$status = $result['success'] ? 200 : 400;
		return new \WP_REST_Response($result, $status);
	}
}
