<?php

namespace Booktics\Cart;

/**
 * Class Cart_Session
 * Handles cart session management for the Booktics plugin
 *
 * @package Booktics\Cart
 */
class Cart_Session {

    /**
     * Session key used to store cart data in a PHP session
     *
     * @var string
     */
    const SESSION_KEY = 'booktics_cart';

    /**
     * Get cart data from session
     *
     * @return array{items: array, total: float}
     */
    public static function get() {
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via sanitize_session_data() on next line.
        $raw_data       = ! empty( $_SESSION[ self::SESSION_KEY ] ) ? wp_unslash( $_SESSION[ self::SESSION_KEY ] ) : null;
        $session_data   = self::sanitize_session_data( $raw_data );

        if ( ! is_array( $session_data ) ) {
            return array(
                'items'  => array(),
                'total'  => 0.00,
                'coupon' => '',
            );
        }

        return $session_data;
    }

    /**
     * Sanitize raw cart session data
     *
     * @param mixed $data Raw data retrieved from the session.
     *
     * @return mixed Sanitized array or null if input is not an array.
     */
    private static function sanitize_session_data( $data ) {
        if ( ! is_array( $data ) ) {
            return null;
        }

        $sanitized_items = array();

        if ( ! empty( $data['items'] ) && is_array( $data['items'] ) ) {
            foreach ( $data['items'] as $item ) {
                if ( ! is_array( $item ) ) {
                    continue;
                }

                $sanitized_item = array(
                    'uuid'           => sanitize_text_field( $item['uuid'] ?? '' ),
                    'service_id'     => absint( $item['service_id'] ?? 0 ),
                    'team_member_id' => absint( $item['team_member_id'] ?? 0 ),
                    'date'           => sanitize_text_field( $item['date'] ?? '' ),
                    'start_time'     => sanitize_text_field( $item['start_time'] ?? '' ),
                    'end_time'       => sanitize_text_field( $item['end_time'] ?? '' ),
                    'price'          => floatval( $item['price'] ?? 0 ),
                    'subtotal'       => floatval( $item['subtotal'] ?? 0 ),
                    'total'          => floatval( $item['total'] ?? 0 ),
                );

                $sanitized_item = apply_filters( 'booktics_pro_sanitize_cart_item', $sanitized_item, $item );

                $sanitized_items[] = $sanitized_item;
            }
        }

        return array(
            'items'  => $sanitized_items,
            'total'  => floatval( $data['total'] ?? 0.00 ),
            'coupon' => sanitize_text_field( $data['coupon'] ?? '' ),
        );
    }

    /**
     * Set cart data in session
     *
     * @param array $cart Cart data to store in session
     *
     * @return void
     */
    public static function set( array $cart ) {
        $_SESSION[ self::SESSION_KEY ] = $cart;
    }

    /**
     * Clear cart data from session
     *
     * @return void
     */
    public static function clear() {
        unset( $_SESSION[ self::SESSION_KEY ] );
    }

    /**
     * Add an item to the cart session
     *
     * @param array $item
     *
     * @return array
     */
    public static function add_item( array $item ): array {
        $cart            = self::get();
        $cart['items'][] = $item;
        $cart['total']   += $item['subtotal'];
        $cart            = apply_filters( 'booktics_pro_cart_session', $cart );

        self::set( $cart );

        return end( $cart['items'] );
    }

    /**
     * Delete an item from the cart session
     *
     * @param string $id
     *
     * @return void
     */
    public static function delete_item( string $id ) {
        $cart          = self::get();
        $cart['items'] = array_values(
            array_filter(
                $cart['items'],
                function ( $item ) use ( $id ) {
                    return $item['uuid'] != $id;
                }
            )
        );
        $cart['total'] = array_reduce(
            $cart['items'], function ( $total, $item ) {
				return $total + $item['price'];
			}, 0.00
        );

        self::set( $cart );
    }

    /**
     * Edit an item in the cart session
     *
     * @param string $uuid UUID of the item to edit
     * @param array $new_data New data to update the item with
     *
     * @return void
     */
    public static function edit_item( string $uuid, array $new_data ) {
        $cart          = self::get();
        $cart['total'] = 0;

        $cart['items'] = array_map(
            function ( $item ) use ( $uuid, $new_data, &$cart ) {
                if ( $item['uuid'] === $uuid ) {
                        $item = array_merge( $item, $new_data );
                }
                $cart['total'] += $item['subtotal'];

                return $item;
            }, $cart['items']
        );
        $cart          = apply_filters( 'booktics_pro_cart_session', $cart );
        self::set( $cart );
    }
}
