<?php
namespace AcademyProMeeting\Integration;

use AcademyPro\Google\Client as Google_Client;
use AcademyPro\Google\Service\Calendar as Google_Service_Calendar;
use AcademyPro\Google\Service\Calendar\Event as Google_Service_Calendar_Event;



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

class GoogleMeet {

	public static function init() {
		$self = new self();
		add_action( 'wp_ajax_academy_pro_meeting/fetch_meet_credential', array( $self, 'fetch_meet_credential' ) );
		add_action( 'wp_ajax_academy_pro_meeting/save_meeting_credentials', array( $self, 'save_meeting_credentials' ) );
		add_action( 'wp_ajax_academy_pro_meeting/get_auth_code', array( $self, 'get_access_token' ) );
		add_action( 'wp_ajax_academy_pro_meeting/create_google_meet_meeting', array( $self, 'create_meeting' ) );
		add_action( 'wp_ajax_academy_pro_meeting/update_google_meet_meeting', array( $self, 'update_meeting' ) );
	}

	public function __construct() {
	}

	public function fetch_meet_credential() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		if ( ! isset( $_FILES['upload_file'] ) ) {
			wp_send_json_error( __( 'Upload File is empty.', 'academy-pro' ) );
		}
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$file = $_FILES['upload_file'];
		if ( 'json' !== pathinfo( $file['name'] )['extension'] ) {
			wp_send_json_error( __( 'Wrong File Format! Please import JSON file.', 'academy-pro' ) );
		}

		$upload_dir = wp_upload_dir();
		$target_dir = $upload_dir['path'] . '/meet_credential.json';
		// phpcs:ignore Generic.PHP.ForbiddenFunctions.Found
		if ( move_uploaded_file( $file['tmp_name'], $target_dir ) ) {
			$file_path = str_replace( $upload_dir['basedir'], '', $target_dir );
			update_user_meta( get_current_user_id(), 'academy_pro_google_meet_credential_filepath', $file_path );
			wp_send_json_success( __( 'Google Meet Credential File uploaded successfully.', 'academy-pro' ) );
		} else {
			wp_send_json_error( __( 'Failed to upload the file.', 'academy-pro' ) );
		}
	}

	private function get_google_api_client() {
		$redirect_url = get_option( 'academy_pro_google_meet_redirect_url' );
		$client = new Google_Client();

		$upload_dir = wp_upload_dir();
		$credential_path = get_user_meta( get_current_user_id(), 'academy_pro_google_meet_credential_filepath', true );
		$credential_file = $upload_dir['basedir'] . '/' . $credential_path;

		$client->setApplicationName( 'Academy LMS Google Meet' );
		$client->setAuthConfig( $credential_file );
		$client->setRedirectUri( $redirect_url );
		$client->addScope(
			Google_Service_Calendar::CALENDAR,
			Google_Service_Calendar::CALENDAR_EVENTS,
		);
		$client->setAccessType( 'offline' );
		$client->setApprovalPrompt( 'force' );

		return $client;
	}

	public function save_meeting_credentials() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$is_admin = sanitize_text_field( $_POST['is_admin'] ?? '' );

		$redirect_url = admin_url( 'admin.php?page=academy-meeting' );

		if ( ! $is_admin ) {
			$redirect_url = \Academy\Helper::get_frontend_dashboard_endpoint_url( 'meeting' );
		}

		update_option( 'academy_pro_google_meet_redirect_url', $redirect_url );

		$auth_url = $this->get_authorization_url( $redirect_url );

		if ( $auth_url ) {
			wp_send_json_success( $auth_url );
		} else {
			wp_send_json_error( 'Failed to generate authorization URL' );
		}
	}

	private function get_authorization_url( $redirect_url ) {
		$client = $this->get_google_api_client();
		$googleCalendar = new Google_Service_Calendar( $client );

		$client->setRedirectUri( $redirect_url );

		$client->addScope([
			Google_Service_Calendar::CALENDAR,
			Google_Service_Calendar::CALENDAR_EVENTS,
		]);

		$authUrl = $client->createAuthUrl();

		return $authUrl;
	}

	public function get_access_token( $authorizationCode ) {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		$client = $this->get_google_api_client();

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$authorizationCode = sanitize_text_field( isset( $_POST['authCode'] ) ? $_POST['authCode'] : '' );

		if ( ! empty( $authorizationCode ) ) {
			$accessToken = $client->fetchAccessTokenWithAuthCode( $authorizationCode );

			if ( isset( $accessToken['error'] ) ) {
				wp_send_json_error( 'Error fetching access token: ' . $accessToken['error_description'] );
				return false;
			}

			update_user_meta( get_current_user_id(), 'academy_pro_google_calendar_access_token', $accessToken );

			$client->setAccessToken( $accessToken );

			return true;
		} else {
			return false;
		}
	}

	public function check_permission() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		$accessToken = get_user_meta( get_current_user_id(), 'academy_pro_google_calendar_access_token', true );

		if ( $accessToken ) {
			$client = $this->get_google_api_client();
			$client->setAccessToken( $accessToken );
			return $client;
		} else {
			return false;
		}
	}

	public function create_meeting() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}
		$client = $this->check_permission();
		$googleCalendar = new Google_Service_Calendar( $client );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$meeting_title = ( isset( $_POST['title'] ) ? sanitize_text_field( $_POST['title'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$meeting_description = ( isset( $_POST['content'] ) ? sanitize_text_field( $_POST['content'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$start_date = ( isset( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$end_date = ( isset( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$timezone = ( isset( $_POST['timezone'] ) ? sanitize_text_field( $_POST['timezone'] ) : '' );

		try {
			$meeting_start_time = new \DateTime( $start_date, new \DateTimeZone( $timezone ) );
			$meeting_end_time = new \DateTime( $end_date, new \DateTimeZone( $timezone ) );
		} catch ( \Exception $e ) {
			wp_send_json_error( 'Error parsing date/time: ' . $e->getMessage() );
			return;
		}

		$event = new Google_Service_Calendar_Event(array(
			'summary' => $meeting_title,
			'location' => 'Google Meet',
			'description' => $meeting_description,
			'start' => array(
				'dateTime' => $meeting_start_time->format( \DateTime::ATOM ),
				'timeZone' => $timezone,
			),
			'end' => array(
				'dateTime' => $meeting_end_time->format( \DateTime::ATOM ),
				'timeZone' => $timezone,
			),
			'conferenceData' => [
				'createRequest' => [
					'requestId'             => uniqid(),
					'conferenceSolutionKey' => [
						'type' => 'hangoutsMeet'
					]
				]
			],
		));

		$calendarId = 'primary';

		try {
			$createdEvent = $googleCalendar->events->insert(
				$calendarId,
				$event,
				array( 'conferenceDataVersion' => 1 )
			);

			$response = array(
				'meetingId' => $createdEvent->id,
				'meetingLink' => $createdEvent->hangoutLink, //phpcs:ignore
				'meetingTitle' => $createdEvent->summary,
				'meetingDescription' => $createdEvent->getDescription(),
				'meetingDate' => $createdEvent->start->dateTime,
				'meetingDuration' => $createdEvent->end->dateTime,
				'meetingTimezone' => $createdEvent->getStart()->getTimeZone(),
				'meetingStatus' => $createdEvent->status,
			);
			$this->create_academy_meeting_callback( $response );
			wp_send_json_success( $response );
		} catch ( \Exception $e ) {
			wp_send_json_error( 'Error creating Google Meet meeting: ' . $e->getMessage() );
		}//end try
	}

	public function create_academy_meeting_callback( $data ) {
		$args = array(
			'post_title'  => sanitize_text_field( $data['meetingTitle'] ),
			'post_content'  => sanitize_text_field( $data['meetingDescription'] ),
			'post_status'   => 'publish',
			'post_author'   => get_current_user_id(),
			'post_type'     => 'academy_meeting',
			'meta_input'    => array(
				'academy_meeting_type'     => 'google_meet',
				'academy_meeting_request'  => wp_json_encode( $data ),
				'academy_meeting_response' => wp_json_encode( $data ),
			)
		);
		$is_post = wp_insert_post( $args );
		wp_send_json_success( [ 'post_id' => $is_post ] );
	}

	public function update_meeting() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		$client = $this->check_permission();
		$googleCalendar = new Google_Service_Calendar( $client );

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$post_id = (int) ( isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : 0 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$meeting_id = sanitize_text_field( isset( $_POST['meeting_id'] ) ? $_POST['meeting_id'] : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$meeting_title = ( isset( $_POST['title'] ) ? sanitize_text_field( $_POST['title'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$meeting_description = ( isset( $_POST['content'] ) ? sanitize_text_field( $_POST['content'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$start_date = ( isset( $_POST['start_date'] ) ? sanitize_text_field( $_POST['start_date'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$end_date = ( isset( $_POST['end_date'] ) ? sanitize_text_field( $_POST['end_date'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash 
		$timezone = ( isset( $_POST['timezone'] ) ? sanitize_text_field( $_POST['timezone'] ) : '' );

		$meeting_start_time = new \DateTime( $start_date, new \DateTimeZone( $timezone ) );
		$meeting_end_time = new \DateTime( $end_date, new \DateTimeZone( $timezone ) );

		$event = $googleCalendar->events->get( 'primary', $meeting_id );

		$event->setSummary( $meeting_title );
		$event->setDescription( $meeting_description );
		$event->getStart()->setDateTime( $meeting_start_time->format( \DateTime::ATOM ) );
		$event->getStart()->setTimeZone( $timezone );
		$event->getEnd()->setDateTime( $meeting_end_time->format( \DateTime::ATOM ) );
		$event->getEnd()->setTimeZone( $timezone );

		try {
			$updatedEvent = $googleCalendar->events->update( 'primary', $event->getId(), $event );

			$response = array(
				'meetingId' => $updatedEvent->getId(),
				'meetingLink' => $updatedEvent->getHangoutLink(),
				'meetingTitle' => $updatedEvent->getSummary(),
				'meetingDescription' => $updatedEvent->getDescription(),
				'meetingDate' => $updatedEvent->getStart()->getDateTime(),
				'meetingDuration' => $updatedEvent->getEnd()->getDateTime(),
				'meetingTimezone' => $updatedEvent->getStart()->getTimeZone(),
				'meetingStatus' => $updatedEvent->getStatus(),
			);

			$this->update_academy_meeting_callback( $post_id, $response );

			wp_send_json_success( $response );
		} catch ( \Exception $e ) {
			wp_send_json_error( 'Error updating Google Calendar event: ' . $e->getMessage() );
		}//end try
	}

	public function update_academy_meeting_callback( $post_id, $data ) {
		$args = array(
			'ID' => $post_id,
			'post_title'  => sanitize_text_field( $data['meetingTitle'] ),
			'post_content'  => sanitize_text_field( $data['meetingDescription'] ),
			'post_status'   => 'publish',
			'post_author'   => get_current_user_id(),
			'post_type'     => 'academy_meeting',
			'meta_input'    => array(
				'academy_meeting_type'     => 'google_meet',
				'academy_meeting_request'  => wp_json_encode( $data ),
				'academy_meeting_response' => wp_json_encode( $data ),
			)
		);
		$is_post = wp_update_post( $args );
		wp_send_json_success( [ 'post_id' => $is_post ] );
	}

	public function delete_google_meet_meeting( $meeting_id, $post_id ) {
		$client = $this->check_permission();
		$googleCalendar = new Google_Service_Calendar( $client );

		try {
			$googleCalendar->events->delete( 'primary', $meeting_id );
			wp_delete_post( $post_id, true );
			wp_send_json_success( [ 'post_id' => $post_id ] );
		} catch ( \Exception $e ) {
			wp_send_json_error( 'Error deleting Google Calendar event: ' . $e->getMessage() );
		}
	}
}
