<?php

namespace Dreamfox\DeliveryDate\Site;

use Dreamfox\DeliveryDate\Abstracts\AbstractWebApplication;
use Dreamfox\DeliveryDate\Facades\SystemFacade;
use Dreamfox\DeliveryDate\Helpers\DeliveryDateHelper;
use Dreamfox\DeliveryDate\OrderData;
use Dreamfox\DeliveryDate\Repositories\OrderRepository;
use Dreamfox\DeliveryDate\Views\DeliveryDateView;
use Dreamfox\DeliveryDate\Views\EmailView;
use Dreamfox\DeliveryDate\Views\OrderView;
class Frontend extends AbstractWebApplication {
    public function __construct() {
        $assetsManager = new AssetsManager();
        parent::__construct( $assetsManager );
    }

    public function bootstrap() {
        parent::bootstrap();
        $this->_init();
    }

    protected function _init() {
        add_action( 'woocommerce_checkout_billing', array($this, 'outputDeliveryDate'), 2000 );
        add_filter( 'woocommerce_checkout_fields', array($this, 'checkoutFields') );
        add_action( 'woocommerce_checkout_process', array($this, 'validateDeliveryDate') );
        add_action( 'woocommerce_checkout_process', array($this, 'validateTimeslot') );
        add_action(
            'woocommerce_checkout_update_order_meta',
            array($this, 'updateOrderMeta'),
            10,
            2
        );
        add_action(
            'woocommerce_email_after_order_table',
            array($this, 'renderEmailWithDeliveryDate'),
            15,
            2
        );
        add_action( 'woocommerce_order_details_after_order_table', array($this, 'renderOrderView'), 20 );
        add_action( 'woocommerce_thankyou', array($this, 'renderOrderView'), 20 );
    }

    public function outputDeliveryDate() {
        $view = new DeliveryDateView($this);
        echo wp_kses_post( $view->render() );
    }

    public function checkoutFields( $fields ) {
        $fieldManager = new CheckoutFieldManager($fields);
        $fieldManager->process();
        return $fieldManager->getFields();
    }

    /**
     * Block checkout when the delivery date violates lead time or blackout rules.
     */
    public function validateDeliveryDate() {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $dateField = ( isset( $_POST[DREAMFOX_WDD_FIELD_NAME] ) ? sanitize_text_field( wp_unslash( $_POST[DREAMFOX_WDD_FIELD_NAME] ) ) : '' );
        if ( '' === $dateField ) {
            return;
        }
        $context = DeliveryDateHelper::buildFreeValidationContext();
        if ( null === $context ) {
            return;
        }
        $error = DeliveryDateHelper::validateSubmittedDate( $dateField, $context );
        if ( $error ) {
            wc_add_notice( $error, 'error' );
        }
    }

    /**
     * Block checkout if timeslots are enabled and none (or an invalid/full) slot was selected.
     */
    public function validateTimeslot() {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $dateField = ( isset( $_POST[DREAMFOX_WDD_FIELD_NAME] ) ? sanitize_text_field( wp_unslash( $_POST[DREAMFOX_WDD_FIELD_NAME] ) ) : '' );
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $timeslotField = ( isset( $_POST[DREAMFOX_WDD_TIMESLOT_FIELD_NAME] ) ? sanitize_text_field( wp_unslash( $_POST[DREAMFOX_WDD_TIMESLOT_FIELD_NAME] ) ) : '' );
        if ( '' === $dateField ) {
            return;
            // No delivery date chosen; let the date field's own validation handle it.
        }
        $settings = SystemFacade::getInstance()->loadTimeslotSettings();
        if ( !$settings->getEnabled() ) {
            return;
        }
        $error = \Dreamfox\DeliveryDate\Helpers\TimeslotHelper::validateSubmittedSlot( $dateField, $timeslotField, $settings );
        if ( $error ) {
            wc_add_notice( $error, 'error' );
        }
    }

    public function updateOrderMeta( $orderId ) {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified by WooCommerce checkout process
        if ( !empty( $_POST[DREAMFOX_WDD_FIELD_NAME] ) && DeliveryDateHelper::isDeliveryAvailableForCart() ) {
            $repository = new OrderRepository($orderId);
            $data = new OrderData();
            $data->setDeliveryDate( sanitize_text_field( wp_unslash( $_POST[DREAMFOX_WDD_FIELD_NAME] ) ) );
            if ( !empty( $_POST[DREAMFOX_WDD_TIMESLOT_FIELD_NAME] ) ) {
                $data->setTimeslot( sanitize_text_field( wp_unslash( $_POST[DREAMFOX_WDD_TIMESLOT_FIELD_NAME] ) ) );
            }
            $repository->save( $data );
        }
    }

    public function renderEmailWithDeliveryDate( $order, $is_admin_email ) {
        $view = new EmailView($this, $order);
        echo wp_kses_post( $view->render() );
    }

    public function renderOrderView( $order ) {
        $view = new OrderView($this, $order);
        echo wp_kses_post( $view->render() );
    }

}
