<?php

namespace FluentBooking\App\Services;

use FluentBooking\App\Models\Booking;
use FluentBooking\App\Models\CalendarSlot;
use FluentBooking\App\Services\Integrations\PaymentMethods\PaymentHelper;
use FluentBooking\App\Services\Integrations\PaymentMethods\CurrenciesHelper;
use FluentBooking\Framework\Support\Arr;

class BookingFieldService
{
    public static function getCustomFieldsData($postedData, CalendarSlot $slot)
    {
        $customFields = self::getCustomFields($slot, true);

        $errors = [];

        $formattedValues = [];

        foreach ($customFields as $fieldKey => $customField) {
            $value = wp_unslash(Arr::get($postedData, $fieldKey));
            if (!$value && Arr::isTrue($customField, 'required')) {
                $errors[$fieldKey . '.required'] = sprintf(__('%s is required', 'fluent-booking-pro'), $customField['label']);
                continue;
            }

            if (is_array($value)) {
                if ($customField['type'] === 'multi-select') {
                    $value = array_map(
                        function ($item) {
                            return sanitize_text_field(Arr::get($item, 'value'));
                        },
                        $value
                    );
                } else {
                    $value = array_map('sanitize_text_field', $value);
                }
            } else if ($customField['type'] == 'textarea') {
                $value = sanitize_textarea_field($value);
            } else {
                $value = sanitize_text_field($value);
            }

            $formattedValues[$fieldKey] = $value;
        }

        if ($errors) {
            return new \WP_Error('required_field', __('Please fill up the required data', 'fluent-booking-pro'), $errors);
        }

        return $formattedValues;
    }

    public static function getBookingFields(CalendarSlot $calendarSlot)
    {
        $requiredIndexes = ['name', 'email', 'message'];

        $defaultFields = [
            'name' => [
                'index'          => 1,
                'type'           => 'text',
                'name'           => 'name',
                'label'          => __('Your Name', 'fluent-booking-pro'),
                'required'       => true,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => true,
                'is_visible'     => true,
                'placeholder'    => __('Your Name', 'fluent-booking-pro'),
            ],
            'email' => [
                'index'          => 2,
                'type'           => 'email',
                'name'           => 'email',
                'label'          => __('Your Email', 'fluent-booking-pro'),
                'required'       => true,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => true,
                'is_visible'     => true,
                'placeholder'    => __('Your Email', 'fluent-booking-pro'),
            ],
            'message' => [
                'index'          => 3,
                'type'           => 'textarea',
                'name'           => 'message',
                'label'          => __('What is this meeting about?', 'fluent-booking-pro'),
                'required'       => false,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => false,
            ]
        ];

        if ($calendarSlot->isGuestFieldRequired()) {
            $requiredIndexes[] = 'guests';
            $defaultFields['guests'] = [
                'type'           => 'multi-guests',
                'name'           => 'guests',
                'label'          => __('Additional Guests', 'fluent-booking-pro'),
                'limit'          => 10,
                'required'       => false,
                'enabled'        => false,
                'system_defined' => true,
                'disable_alter'  => false
            ];
        }
        if ($calendarSlot->isLocationFieldRequired()) {
            $requiredIndexes[] = 'location';
            $defaultFields['location'] = [
                'index'          => 4,
                'type'           => 'radio',
                'name'           => 'location',
                'label'          => __('Location', 'fluent-booking-pro'),
                'options'        => LocationService::getLocationOptions($calendarSlot),
                'required'       => true,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => true,
                'placeholder'    => esc_attr__('Location', 'fluent-booking-pro'),
            ];
        } else if ($calendarSlot->isPhoneRequired()) {
            $requiredIndexes[] = 'phone_number';
            $defaultFields['phone_number'] = [
                'index'          => 5,
                'type'           => 'phone',
                'name'           => 'phone_number',
                'label'          => __('Your Phone Number', 'fluent-booking-pro'),
                'required'       => true,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => true
            ];
        } else if ($calendarSlot->isAddressRequired()) {
            $requiredIndexes[] = 'address';
            $defaultFields['address'] = [
                'index'          => 6,
                'type'           => 'text',
                'name'           => 'address',
                'label'          => __('Your Address', 'fluent-booking-pro'),
                'required'       => true,
                'enabled'        => true,
                'system_defined' => true,
                'disable_alter'  => true,
                'placeholder'    => esc_attr__('Address', 'fluent-booking-pro'),
            ];
        }

        $dbFields = $calendarSlot->getMeta('booking_fields', []);

        if (!$dbFields) {
            $dbFields = array_values($defaultFields);
        }

        $existingFields = [];
        foreach ($dbFields as $dbField) {
            $name = $dbField['name'];
            $existingFields[$name] = $dbField;
        }

        if (empty($defaultFields['location'])) {
            unset($existingFields['location']);
        } else {
            if (empty($existingFields['location'])) {
                $existingFields['location'] = $defaultFields['location'];
            } else {
                $existingFields['location']['options'] = $defaultFields['location']['options'];
            }
        }

        if (empty($defaultFields['phone_number'])) {
            unset($existingFields['phone_number']);
        }

        if (empty($defaultFields['address'])) {
            unset($existingFields['address']);
        }

        foreach ($requiredIndexes as $index) {
            if (empty($existingFields[$index]) && !empty($defaultFields[$index])) {
                $existingFields[$index] = $defaultFields[$index];
            }
        }

        if ($calendarSlot->type == 'paid' && Helper::isPaymentEnabled()) {
            $paymentSettings = $calendarSlot->getMeta('payment_settings', []);
            $isEnables = Arr::get($paymentSettings, 'enabled') === 'yes';
            if ($isEnables) {
                $exist = Arr::get($existingFields, 'payment_method', []);
                if (!$exist) {
                    $exist = [
                        'index'          => 20,
                        'type'           => 'payment',
                        'name'           => 'payment_method',
                        'required'       => false,
                        'enabled'        => true,
                        'system_defined' => true,
                        'payment_items'  => PaymentHelper::getReceiptTemplate(Arr::get($paymentSettings, 'items')),
                        'label'          => __('Payment Summary', 'fluent-booking-pro'),
                        'currency_sign'  => CurrenciesHelper::getGlobalCurrencySign(),
                    ];
                } else {
                    $exist['currency_sign'] = CurrenciesHelper::getGlobalCurrencySign();
                    $exist['payment_items'] = PaymentHelper::getReceiptTemplate(Arr::get($paymentSettings, 'items'));
                }
                $existingFields['payment_method'] = $exist;
            } else {
                unset($existingFields['payment_method']);
            }
        } else {
            unset($existingFields['payment_method']);
        }

        $existingFields['email']['disabled'] = false;

        return array_values($existingFields);
    }

    public static function getBookingFieldLabels(CalendarSlot $calendarSlot, $enabledOnly = false)
    {
        $fields = self::getBookingFields($calendarSlot);
        $labels = [];

        foreach ($fields as $field) {
            if ($enabledOnly && !Arr::isTrue($field, 'enabled')) {
                continue;
            }

            $labels[$field['name']] = $field['label'];
        }

        return $labels;
    }

    public static function generateFieldName($calendarEvent, $fieldLabel)
    {
        $fieldName     = 'custom_' . sanitize_title($fieldLabel);
        $bookingFields = self::getBookingFields($calendarEvent);
        
        $matched = 0;
        foreach ($bookingFields as $field) {
            if (strpos($field['name'], $fieldName) !== false) {
                $matched++;
            }
        }

        if ($matched) {
            $fieldName .= '_' . $matched;
        }
        return $fieldName;
    }

    public static function getFormattedCustomBookingData(Booking $booking)
    {
        $customFormData = $booking->getMeta('custom_fields_data', []);
        if (!$customFormData) {
            return [];
        }

        $labels = self::getBookingFieldLabels($booking->calendar_event);

        $formattedData = [];

        foreach ($customFormData as $dataKey => $value) {
            if (isset($labels[$dataKey])) {
                $label = $labels[$dataKey];
            } else {
                $label = $dataKey;
            }
            $formattedData[$dataKey] = [
                'label' => $label,
                'value' => is_array($value) ? implode(', ', $value) : $value
            ];
        }

        return $formattedData;
    }

    public static function getCustomFields($calendarEvent, $withConfig = false)
    {
        $existingFields = $calendarEvent->getMeta('booking_fields', []);

        if (!$existingFields) {
            return [];
        }

        $customFields = [];

        foreach ($existingFields as $existingField) {
            if (Arr::get($existingField, 'system_defined') || !Arr::isTrue($existingField, 'enabled')) {
                continue;
            }
            if ($withConfig) {
                $customFields[$existingField['name']] = $existingField;
            } else {
                $customFields[$existingField['name']] = $existingField['label'];
            }
        }

        return $customFields;
    }

    public static function getBookingFieldByName($calendarEvent, $name)
    {
        $fields = self::getBookingFields($calendarEvent);

        foreach ($fields as $field) {
            if (Arr::get($field, 'name') == $name) {
                return $field;
            }
        }

        return [];
    }

    public static function hasPhoneNumberField($fields)
    {
        if(!$fields) {
            return false;
        }

        foreach ($fields as $field) {
            if ($field['type'] == 'phone') {
                return true;
            } else if ($field['name'] == 'location') {
                if (!empty($field['options'])) {
                    foreach ($field['options'] as $option) {
                        if (Arr::get($option, 'type') == 'phone_guest') {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
}
