<?php
/**
 * Dashboard Shortcode
 *
 * Handles the [nemtly_booking_dashboard] shortcode and authentication flow.
 *
 * @since   PBOOKING_SINCE
 * @package Nemtly_Booking
 */

namespace NemtlyBooking\Shortcodes;

use NemtlyBooking\Services\Token_Service;
use NemtlyBooking\Repositories\Booking_Repository;

/**
 * Dashboard Shortcode class
 *
 * @since PBOOKING_SINCE
 */
class Dashboard_Shortcode {
    /**
     * Token Service instance
     *
     * @var Token_Service
     */
    private $token_service;
    /**
     * Booking Repository instance
     *
     * @var Booking_Repository
     */
    private $booking_repository;
    /**
     * Cookie name for the session
     *
     * @var string
     */
    private $cookie_name = 'nemtly_magic_session';

    /**
     * Constructor
     *
     * @since PBOOKING_SINCE
     *
     * @param Token_Service      $token_service      Token Service instance.
     * @param Booking_Repository $booking_repository Booking Repository instance.
     */
    public function __construct( Token_Service $token_service, Booking_Repository $booking_repository ) {
        $this->token_service      = $token_service;
        $this->booking_repository = $booking_repository;
        $this->init_hooks();
    }

    /**
     * Initialize hooks
     *
     * @since PBOOKING_SINCE
     */
    private function init_hooks() {
        add_shortcode( 'nemtly_booking_dashboard', [ $this, 'render_dashboard_shortcode' ] );
        add_action( 'template_redirect', [ $this, 'handle_magic_login' ] );
        add_action( 'admin_post_nemtly_send_magic_link', [ $this, 'handle_magic_link_request' ] );
        add_action( 'admin_post_nopriv_nemtly_send_magic_link', [ $this, 'handle_magic_link_request' ] );
    }

    /**
     * Handle incoming Magic Link click (token validation)
     *
     * @since PBOOKING_SINCE
     */
    public function handle_magic_login() {
        if ( ! isset( $_GET['token'] ) || ! isset( $_GET['nemtly_action'] ) || 'login' !== $_GET['nemtly_action'] ) {
            return;
        }
        $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
        $email = $this->token_service->validate_token( $token );
        if ( $email ) {
            // Valid token. Set session cookie.
            // Expiry: 24 hours
            $expiry = time() + ( DAY_IN_SECONDS );
            // Simple hash for this MVP (In production, use a more secure session manager)
            // We store email|hash to verify integrity
            $hash         = hash_hmac( 'sha256', $email . '|' . $expiry, wp_salt( 'auth' ) );
            $cookie_value = base64_encode( $email . '|' . $expiry . '|' . $hash );
            setcookie( $this->cookie_name, $cookie_value, $expiry, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true );
            // Invalidate the one-time token
            $this->token_service->invalidate_token( $token );
            // Redirect to remove query args
            $redirect_url = remove_query_arg( [ 'token', 'nemtly_action' ] );
            wp_safe_redirect( $redirect_url );
            exit;
        } else {
            // Invalid or expired token
            // Ideally verify if we need to show an error message.
            // For now, redirect to dashboard which will show login form with error if we passed one, or just the form.
            $redirect_url = remove_query_arg( [ 'token', 'nemtly_action' ] );
            wp_safe_redirect( add_query_arg( 'magic_error', 'invalid', $redirect_url ) );
            exit;
        }
    }

    /**
     * Render the shortcode content
     *
     * @since PBOOKING_SINCE
     *
     * @param array $atts Shortcode attributes.
     * @return string HTML output.
     */
    public function render_dashboard_shortcode( $atts ) {
        $user_email = $this->get_current_user_email();
        ob_start();
        if ( $user_email ) {
            $this->render_dashboard_view( $user_email );
        } else {
            $error = isset( $_GET['magic_error'] ) ? sanitize_text_field( wp_unslash( $_GET['magic_error'] ) ) : '';
            $sent  = isset( $_GET['magic_sent'] );
            $this->render_login_view( $error, $sent );
        }
        return ob_get_clean();
    }

    /**
     * Get the authenticated user email from cookie
     *
     * @since PBOOKING_SINCE
     *
     * @return string|false Email if authenticated, false otherwise.
     */
    private function get_current_user_email() {
        if ( ! isset( $_COOKIE[ $this->cookie_name ] ) ) {
            return false;
        }
        $value = base64_decode( sanitize_text_field( wp_unslash( $_COOKIE[ $this->cookie_name ] ) ) );
        $parts = explode( '|', $value );
        if ( count( $parts ) !== 3 ) {
            return false;
        }
        list( $email, $expiry, $hash ) = $parts;
        if ( $expiry < time() ) {
            return false;
        }
        $expected_hash = hash_hmac( 'sha256', $email . '|' . $expiry, wp_salt( 'auth' ) );
        if ( ! hash_equals( $expected_hash, $hash ) ) {
            return false;
        }
        return $email;
    }

    /**
     * Handle the request to send a magic link
     *
     * @since PBOOKING_SINCE
     */
    public function handle_magic_link_request() {
        $nonce = ! empty( $_POST['nemtly_booking_dashboard_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nemtly_booking_dashboard_nonce'] ) ) : '';
        if ( ! wp_verify_nonce( $nonce, 'nemtly_magic_link' ) ) {
            wp_die( esc_html__( 'Security check failed.', 'nemtly-booking' ) );
        }
        $email = ! empty( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
        if ( is_email( $email ) ) {
            $token = $this->token_service->generate_token( $email );
            if ( $token ) {
                // Trigger action for email service
                do_action( 'nemtly_booking_send_magic_link', $email, $token );
            }
        }
        // Redirect back
        $referer = wp_get_referer();
        if ( $referer ) {
            wp_safe_redirect( add_query_arg( 'magic_sent', '1', $referer ) );
        } else {
            wp_safe_redirect( home_url() );
        }
        exit;
    }

    /**
     * Render Login View
     *
     * @param string $error Error code.
     * @param bool   $sent  Whether link was sent.
     */
    private function render_login_view( $error, $sent ) {
        // Variables needed in template: $error, $sent
        $template = NEMTLY_BOOKING_PATH . 'templates/dashboard-login.php';
        if ( file_exists( $template ) ) {
            include $template;
        } else {
            echo '<p>' . esc_html__( 'Error: Template not found.', 'nemtly-booking' ) . '</p>';
        }
    }

    /**
     * Render Dashboard View
     *
     * @param string $email User email.
     */
    private function render_dashboard_view( $email ) {
        $bookings    = $this->booking_repository->find_all(
            [
                'attendee_email' => $email,
                'orderby'        => 'booking_date',
                'order'          => 'DESC',
            ]
        );
        $current_url = remove_query_arg( [ 'booking_cancelled' ] );
        // Variables needed in template: $email, $bookings, $current_url
        $template = NEMTLY_BOOKING_PATH . 'templates/dashboard-list.php';
        if ( file_exists( $template ) ) {
            include $template;
        }
    }
}
