<?php

namespace WC_NEXT_SYNC;

use WC_NEXT_SYNC\Common\Settings_Store as Base_Settings_Store;

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

/**
 * Plugin's settings store class.
 */
class Settings_Store extends Base_Settings_Store
{
    private const FIELD_SCHEMA = [
        'type' => 'object',
        'properties' => [
            'enabled' => ['type' => 'boolean'],
            'alias' => ['type' => 'string'],
        ],
        'additionalProperties' => false,
        'required' => ['enabled', 'alias'],
    ];

    private const DEFAULT_FIELD = [
        'enabled' => true,
        'alias' => '',
    ];

    private const ORDER_FIELDS = [
        'id',
        'name',
        'date',
        'taxes',
        'total',
        'coupon_codes',
        'payment_method',
        'billing_first_name',
        'billing_last_name',
        'billing_email',
        'billing_phone',
        'billing_address_1',
        'billing_address_2',
        'billing_city',
        'billing_postcode',
        'billing_state',
        'billing_country',
        'billing_company',
        'shipping_first_name',
        'shipping_last_name',
        'shipping_phone',
        'shipping_address_1',
        'shipping_address_2',
        'shipping_city',
        'shipping_postcode',
        'shipping_state',
        'shipping_country',
        'shipping_company',
        'shipping_method',
    ];

    private const PRODUCT_FIELDS = [
        'id',
        'name',
        'sku',
        'description',
        'short_description',
        'price',
        'regular_price',
        'sale_price',
        'date_created',
        'date_modified',
        'on_sale_from',
        'on_sale_to',
        'tax_class',
        'tax_status',
        'manage_stock',
        'stock_quantity',
        'stock_status',
        'backorders',
    ];

    private const CUSTOMER_FIELDS = [
        'id',
        'first_name',
        'last_name',
        'display_name',
        'username',
        'email',
        'date_created',
        'date_modified',
        'billing_first_name',
        'billing_last_name',
        'billing_email',
        'billing_phone',
        'billing_address_1',
        'billing_address_2',
        'billing_city',
        'billing_postcode',
        'billing_state',
        'billing_country',
        'billing_company',
        'shipping_first_name',
        'shipping_last_name',
        'shipping_phone',
        'shipping_address_1',
        'shipping_address_2',
        'shipping_city',
        'shipping_postcode',
        'shipping_state',
        'shipping_country',
        'shipping_company',
        'shipping_method',
    ];

    private const COUPON_FIELDS = [
        'id',
        'code',
        'description',
        'status',
        'amount',
        'minimum_amount',
        'maximum_amount',
        'usage_count',
        'usage_limit',
        'discount_type',
        'individual_use',
        'date_created',
        'date_expires',
        'date_modified',
    ];

    protected function construct(...$args)
    {
        parent::construct(...$args);

        self::register_setting([
            'name' => 'connection',
            'properties' => [
                'connected' => ['type' => 'boolean'],
                'nextcloud_url' => ['type' => 'string'],
                'username' => ['type' => 'string'],
                'password' => ['type' => 'string'],
                'filepath' => ['type' => 'string'],
                'schedule' => [
                    'type' => 'string',
                    'enum' => [
                        'minutly',
                        'quarterly',
                        'twicehourly',
                        'hourly',
                        'daily',
                        'weekly',
                    ],
                ],
            ],
            'default' => [
                'connected' => false,
                'nextcloud_url' => 'https://',
                'username' => '',
                'password' => '',
                'filepath' => 'woocommerce/orders.xlsx',
                'schedule' => 'hourly',
            ],
        ]);

        self::register_setting([
            'name' => 'orders',
            'properties' => [
                'sync' => ['type' => 'boolean'],
                'from_date' => ['type' => 'string'],
                'status' => [
                    'type' => 'array',
                    'items' => ['type' => 'string'],
                    'uniqueItems' => true,
                    'enum' => [
                        'completed',
                        'cancelled',
                        'pending',
                        'on-hold',
                        'processing',
                        'refunded',
                        'failed',
                    ],
                ],
                'fields' => [
                    'type' => 'object',
                    'properties' => array_reduce(
                        self::ORDER_FIELDS,
                        function ($fields, $field) {
                            $fields[$field] = self::FIELD_SCHEMA;
                            return $fields;
                        },
                        []
                    ),
                    'additionalProperties' => false,
                    'required' => self::ORDER_FIELDS,
                ],
            ],
            'default' => [
                'sync' => true,
                'from_date' => '',
                'status' => ['completed'],
                'fields' => array_reduce(
                    self::ORDER_FIELDS,
                    function ($fields, $field) {
                        $fields[$field] = self::DEFAULT_FIELD;
                        return $fields;
                    },
                    []
                ),
            ],
        ]);

        self::register_setting([
            'name' => 'products',
            'properties' => [
                'sync' => ['type' => 'boolean'],
                'fields' => [
                    'type' => 'object',
                    'properties' => array_reduce(
                        self::PRODUCT_FIELDS,
                        function ($fields, $field) {
                            $fields[$field] = self::FIELD_SCHEMA;
                            return $fields;
                        },
                        []
                    ),
                    'additionalProperties' => false,
                    'required' => self::PRODUCT_FIELDS,
                ],
            ],
            'default' => [
                'sync' => false,
                'fields' => array_reduce(
                    self::PRODUCT_FIELDS,
                    function ($fields, $field) {
                        $fields[$field] = self::DEFAULT_FIELD;
                        return $fields;
                    },
                    []
                ),
            ],
        ]);

        self::register_setting([
            'name' => 'customers',
            'properties' => [
                'sync' => ['type' => 'boolean'],
                'fields' => [
                    'type' => 'object',
                    'properties' => array_reduce(
                        self::CUSTOMER_FIELDS,
                        static function ($fields, $field) {
                            $fields[$field] = self::FIELD_SCHEMA;
                            return $fields;
                        },
                        []
                    ),
                    'additionalProperties' => false,
                    'required' => self::CUSTOMER_FIELDS,
                ],
            ],
            'default' => [
                'sync' => false,
                'fields' => array_reduce(
                    self::CUSTOMER_FIELDS,
                    static function ($fields, $field) {
                        $fields[$field] = self::DEFAULT_FIELD;
                        return $fields;
                    },
                    []
                ),
            ],
        ]);

        self::register_setting([
            'name' => 'coupons',
            'properties' => [
                'sync' => ['type' => 'boolean'],
                'fields' => [
                    'type' => 'object',
                    'properties' => array_reduce(
                        self::COUPON_FIELDS,
                        static function ($fields, $field) {
                            $fields[$field] = self::FIELD_SCHEMA;
                            return $fields;
                        },
                        []
                    ),
                    'additionalProperties' => false,
                    'required' => self::COUPON_FIELDS,
                ],
            ],
            'default' => [
                'sync' => false,
                'fields' => array_reduce(
                    self::COUPON_FIELDS,
                    static function ($fields, $field) {
                        $fields[$field] = self::DEFAULT_FIELD;
                        return $fields;
                    },
                    []
                ),
            ],
        ]);

        self::ready(static function ($store) {
            $store::use_setter('connection', [
                self::class,
                'sanitize_connection',
            ]);
        });
    }

    public static function sanitize_connection($data)
    {
        if (!filter_var($data['nextcloud_url'] ?? '', FILTER_VALIDATE_URL)) {
            $data['nextcloud_url'] = '';
        } else {
            $data['nextcloud_url'] = preg_replace(
                '/\/+$/',
                '',
                $data['nextcloud_url'] ?? ''
            );
        }

        if ($index = strpos($data['nextcloud_url'], 'remote.php')) {
            $data['nextcloud_url'] = substr($data['nextcloud_url'], 0, $index);
        }

        if ($filepath = $data['filepath'] ?? null) {
            $info = pathinfo((string) $filepath);
            $ext = $info['extension'] ?? null;

            if ($ext !== 'xlsx') {
                $dirname = preg_replace(
                    '/^(\.|\/)+/',
                    '',
                    $info['dirname'] ?? ''
                );
                $basename = $info['basename'] ?? 'orders';
                $filename = $basename . '.xlsx';
                $data['filepath'] = $dirname . '/' . $filename;
            }
        }

        if (
            $data['nextcloud_url'] &&
            $data['username'] &&
            $data['password'] &&
            $data['filepath']
        ) {
            $data['connected'] = Plugin::check_connection($data);
        }

        return $data;
    }
}
