<?php
/**
 * DESCRIPTION: REST controller for the setup wizard — per-step save endpoint
 * and a finalize endpoint that creates pages and seeds a sample event.
 *
 * @package Nemtly_Booking
 */

namespace NemtlyBooking\API;

use NemtlyBooking\API\Nemtly_API;
use NemtlyBooking\Core\Telemetry_Manager;
use NemtlyBooking\Services\Setup_Service;
use NemtlyBooking\Services\Settings_Service;
use WP_REST_Server;
use WP_REST_Response;
use WP_Error;

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

/**
 * Setup Controller — namespace nemtly-booking/v1/setup.
 *
 * @since PBOOKING_SINCE
 */
class Setup_Controller extends Nemtly_API {

    /**
     * Constructor.
     *
     * @since PBOOKING_SINCE
     */
    public function __construct() {
        parent::__construct();
        $this->rest_base = 'setup';
    }

    /**
     * Register REST routes.
     *
     * @since PBOOKING_SINCE
     *
     * @return void
     */
    public function register_routes() {
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/save',
            [
                [
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'save_step' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/finalize',
            [
                [
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'finalize' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );
    }

    /**
     * Capability check — only admins can run the wizard.
     *
     * @since PBOOKING_SINCE
     *
     * @return bool
     */
    public function permissions_check() {
        return current_user_can( 'manage_options' );
    }

    /**
     * Save a single step's data.
     *
     * Body: { step: 'persona'|'identity'|'availability'|'notifications'|'payments', data: {...} }
     *
     * @since PBOOKING_SINCE
     *
     * @param \WP_REST_Request $request The request.
     *
     * @return WP_REST_Response|WP_Error
     */
    public function save_step( $request ) {
        $params = $request->get_json_params();
        $step   = isset( $params['step'] ) ? sanitize_key( $params['step'] ) : '';
        $data   = isset( $params['data'] ) && is_array( $params['data'] ) ? $params['data'] : [];

        switch ( $step ) {
            case 'persona':
                $this->save_persona( $data );
                break;
            case 'identity':
                $this->save_identity( $data );
                break;
            case 'availability':
                $this->save_availability( $data );
                break;
            case 'notifications':
                $this->save_notifications( $data );
                break;
            case 'payments':
                $this->save_payments( $data );
                break;
            default:
                return new WP_Error(
                    'invalid_step',
                    __( 'Unknown setup step.', 'nemtly-booking' ),
                    [ 'status' => 400 ]
                );
        }

        return new WP_REST_Response( [ 'success' => true ], 200 );
    }

    /**
     * Finalize the wizard — create pages, seed a sample event, mark complete.
     *
     * @since PBOOKING_SINCE
     *
     * @return WP_REST_Response
     */
    public function finalize() {
        $persona = get_option( 'nemtly_booking_business_persona', 'other' );

        $service = new Setup_Service();
        $summary = $service->finalize( $persona );

        return new WP_REST_Response(
            [
                'success'         => true,
                'pages'           => $summary['pages'],
                'sample_event_id' => $summary['sample_event_id'],
            ],
            200
        );
    }

    /**
     * Persist Step 1 — business type.
     *
     * @since PBOOKING_SINCE
     *
     * @param array $data Step data.
     *
     * @return void
     */
    private function save_persona( $data ) {
        $allowed = [ 'tutor', 'studio', 'professional', 'other' ];
        $persona = isset( $data['business_persona'] ) ? sanitize_key( $data['business_persona'] ) : 'other';

        if ( ! in_array( $persona, $allowed, true ) ) {
            $persona = 'other';
        }

        update_option( 'nemtly_booking_business_persona', $persona );
    }

    /**
     * Persist Step 2 — business identity.
     *
     * @since PBOOKING_SINCE
     *
     * @param array $data Step data.
     *
     * @return void
     */
    private function save_identity( $data ) {
        if ( ! empty( $data['business_name'] ) ) {
            update_option( 'blogname', sanitize_text_field( $data['business_name'] ) );
        }

        if ( ! empty( $data['timezone'] ) ) {
            update_option( 'timezone_string', sanitize_text_field( $data['timezone'] ) );
        }

        if ( ! empty( $data['currency'] ) ) {
            $settings_service = new Settings_Service();
            $settings_service->update_setting( 'currency', sanitize_text_field( $data['currency'] ) );
        }

        if ( ! empty( $data['logo_id'] ) ) {
            update_option( 'nemtly_booking_logo_id', absint( $data['logo_id'] ) );
        }
    }

    /**
     * Persist Step 3 — weekly availability.
     *
     * @since PBOOKING_SINCE
     *
     * @param array $data Step data.
     *
     * @return void
     */
    private function save_availability( $data ) {
        $days = [ 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun' ];

        $sanitized = [];
        foreach ( $days as $day ) {
            $blocks = isset( $data[ $day ] ) && is_array( $data[ $day ] ) ? $data[ $day ] : [];

            $sanitized[ $day ] = [];
            foreach ( $blocks as $block ) {
                if ( ! is_array( $block ) ) {
                    continue;
                }

                $sanitized[ $day ][] = [
                    'start' => $this->sanitize_time( $block['start'] ?? '09:00' ),
                    'end'   => $this->sanitize_time( $block['end'] ?? '17:00' ),
                ];
            }
        }

        update_option( 'nemtly_booking_availability', $sanitized );
    }

    /**
     * Persist Step 4 — notification toggles and telemetry consent.
     *
     * @since PBOOKING_SINCE
     *
     * @param array $data Step data.
     *
     * @return void
     */
    private function save_notifications( $data ) {
        $admin_notify     = ! empty( $data['admin_notify'] );
        $customer_confirm = ! empty( $data['customer_confirm'] );
        $reminder         = ! empty( $data['reminder'] );

        $settings_service = new Settings_Service();
        $settings_service->update_settings(
            [
                'email_notifications_enabled' => $admin_notify || $customer_confirm || $reminder,
                'reminder_enabled'            => $reminder,
                'reminder_hours'              => 24,
            ]
        );

        update_option( 'nemtly_booking_admin_notify_enabled', $admin_notify );
        update_option( 'nemtly_booking_customer_confirm_enabled', $customer_confirm );

        // Record the telemetry choice. Both paths dismiss the standalone opt-in
        // admin notice so the user is not asked twice.
        if ( ! empty( $data['telemetry'] ) ) {
            Telemetry_Manager::opt_in();
        } else {
            Telemetry_Manager::opt_out();
        }
    }

    /**
     * Persist Step 5 — payment method.
     *
     * @since PBOOKING_SINCE
     *
     * @param array $data Step data.
     *
     * @return void
     */
    private function save_payments( $data ) {
        $method = isset( $data['method'] ) ? sanitize_key( $data['method'] ) : 'offline';

        $settings_service = new Settings_Service();

        if ( 'stripe' === $method ) {
            $pk = isset( $data['stripe_publishable_key'] ) ? sanitize_text_field( $data['stripe_publishable_key'] ) : '';
            $sk = isset( $data['stripe_secret_key'] ) ? sanitize_text_field( $data['stripe_secret_key'] ) : '';

            $settings_service->update_settings(
                [
                    'stripe_publishable_key' => $pk,
                    'stripe_secret_key'      => $sk,
                    'accept_stripe'          => true,
                    'accept_manual_payment'  => false,
                ]
            );
            return;
        }

        // Offline / manual payment path.
        $settings_service->update_settings(
            [
                'accept_stripe'         => false,
                'accept_manual_payment' => true,
                'manual_payment_label'  => __( 'Pay on arrival', 'nemtly-booking' ),
            ]
        );
    }

    /**
     * Sanitize an H:i time string. Falls back to '09:00' if invalid.
     *
     * @since PBOOKING_SINCE
     *
     * @param string $time Raw time string.
     *
     * @return string
     */
    private function sanitize_time( $time ) {
        $time = is_string( $time ) ? trim( $time ) : '';

        if ( preg_match( '/^([01]\d|2[0-3]):[0-5]\d$/', $time ) ) {
            return $time;
        }

        return '09:00';
    }
}
