<?php

declare(strict_types=1);

namespace BadamSoft\WooProductExporter\Templates;

use BadamSoft\WooProductExporter\Helpers\Utils;

class TemplateManager {
    private const OPTION_TEMPLATES      = 'prodexfo_templates';
    private const OPTION_LAST_SETTINGS  = 'prodexfo_last_settings';
    private const USER_META_SELECTED_ID = 'prodexfo_selected_template';

    /**
     * @return array<string, array<string, mixed>>
     */
    public function get_templates(): array {
        $templates = get_option( self::OPTION_TEMPLATES, [] );

        if ( ! is_array( $templates ) ) {
            return [];
        }

        return array_filter(
            $templates,
            static function ( $template ): bool {
                return is_array( $template ) && ! empty( $template['id'] );
            }
        );
    }

    public function get_template( string $id ): ?array {
        $templates = $this->get_templates();

        return $templates[ $id ] ?? null;
    }

    public function save_template( array $template ): void {
        if ( empty( $template['id'] ) ) {
            return;
        }

        $templates               = $this->get_templates();
        $template['updated_at']  = current_time( 'mysql' );
        $templates[ $template['id'] ] = $template;

        update_option( self::OPTION_TEMPLATES, $templates, false );
    }

    public function delete_template( string $id ): bool {
        $templates = $this->get_templates();

        if ( ! isset( $templates[ $id ] ) ) {
            return false;
        }

        unset( $templates[ $id ] );
        update_option( self::OPTION_TEMPLATES, $templates, false );

        return true;
    }

    public function set_selected_template_for_user( int $user_id, ?string $template_id ): void {
        if ( $template_id ) {
            update_user_meta( $user_id, self::USER_META_SELECTED_ID, sanitize_text_field( $template_id ) );
        } else {
            delete_user_meta( $user_id, self::USER_META_SELECTED_ID );
        }
    }

    public function get_selected_template_for_user( int $user_id ): ?string {
        $value = get_user_meta( $user_id, self::USER_META_SELECTED_ID, true );

        return is_string( $value ) && '' !== $value ? $value : null;
    }

    public function get_last_settings(): array {
        $settings = get_option( self::OPTION_LAST_SETTINGS, [] );

        if ( ! is_array( $settings ) ) {
            return [];
        }

        return $this->sanitize_settings_payload( $settings );
    }

    public function remember_last_settings( array $settings ): void {
        update_option( self::OPTION_LAST_SETTINGS, $this->sanitize_settings_payload( $settings ), false );
    }

    public function sanitize_template_payload( array $payload ): array {
        $template = [
            'id'          => $payload['id'] ?? wp_generate_uuid4(),
            'name'        => sanitize_text_field( $payload['name'] ?? __( 'Untitled template', 'badamsoft-product-exporter-for-woocommerce' ) ),
            'description' => sanitize_textarea_field( $payload['description'] ?? '' ),
            'fields'      => $this->sanitizeFields( $payload['fields'] ?? [] ),
            'filters'     => isset( $payload['filters'] ) && is_array( $payload['filters'] ) ? $payload['filters'] : [],
            'format'      => sanitize_key( $payload['format'] ?? '' ),
            'settings'    => $this->sanitize_settings_payload( $payload['settings'] ?? [] ),
            'created_at'  => $payload['created_at'] ?? current_time( 'mysql' ),
            'updated_at'  => current_time( 'mysql' ),
            'version'     => 1,
        ];

        return $template;
    }

    public function sanitize_settings_payload( array $settings ): array {
        return $this->sanitizeSettings( $settings );
    }

    /**
     * @param array<int, string> $fields
     * @return array<int, string>
     */
    private function sanitizeFields( array $fields ): array {
        $clean = [];

        foreach ( $fields as $field ) {
            $key = Utils::sanitize_field_key( $field );

            if ( '' === $key ) {
                continue;
            }

            $clean[] = $key;
        }

        return array_values( array_unique( $clean ) );
    }

    private function sanitizeSettings( array $settings ): array {
        $defaults = [
            'delimiter'          => ',',
            'encoding'           => 'UTF-8',
            'filename'           => 'wc-products-export-{{date}}',
            'attach_images_zip'  => false,
        ];

        $allowed_delimiters = [ ',', ';', "\t", '|' ];
        $allowed_encodings  = [ 'UTF-8', 'Windows-1251', 'ISO-8859-1' ];

        $delimiter = isset( $settings['delimiter'] ) ? (string) $settings['delimiter'] : $defaults['delimiter'];
        if ( ! in_array( $delimiter, $allowed_delimiters, true ) ) {
            $delimiter = $defaults['delimiter'];
        }

        $encoding = isset( $settings['encoding'] ) ? strtoupper( (string) $settings['encoding'] ) : $defaults['encoding'];
        if ( ! in_array( $encoding, $allowed_encodings, true ) ) {
            $encoding = $defaults['encoding'];
        }

        $filename_raw = isset( $settings['filename'] ) ? (string) $settings['filename'] : $defaults['filename'];
        $token        = '__WCPCE_DATE__';
        $filename_tmp = str_replace( '{{date}}', $token, $filename_raw );
        $filename_tmp = sanitize_file_name( $filename_tmp );
        $filename     = str_ireplace( $token, '{{date}}', $filename_tmp );

        if ( false === stripos( $filename, '{{date}}' ) ) {
            $token_core = trim( $token, '_' );
            $variants   = [
                '__' . $token_core,
                '__' . strtolower( $token_core ),
                '__' . strtoupper( $token_core ),
                '_' . $token_core,
                '_' . strtolower( $token_core ),
                '_' . strtoupper( $token_core ),
                $token_core,
                strtolower( $token_core ),
                strtoupper( $token_core ),
                str_replace( '_', '-', strtolower( $token_core ) ),
                str_replace( '_', '-', strtoupper( $token_core ) ),
            ];

            $filename = str_ireplace( $variants, '{{date}}', $filename );
        }

        if ( '' === $filename ) {
            $filename = $defaults['filename'];
        } elseif ( 'wc-products-export-{{date}}.csv' === $filename ) {
            $filename = 'wc-products-export-{{date}}';
        }

        $attach_zip = ! empty( $settings['attach_images_zip'] );

        $field_labels = [];
        $raw_labels   = $settings['field_labels'] ?? null;

        if ( is_array( $raw_labels ) ) {
            foreach ( $raw_labels as $field_key => $label ) {
                if ( ! is_string( $field_key ) ) {
                    continue;
                }

                $sanitized_key = Utils::sanitize_field_key( $field_key );
                $sanitized_label = is_string( $label ) ? sanitize_text_field( $label ) : '';
                $sanitized_label = trim( $sanitized_label );

                if ( '' === $sanitized_key || '' === $sanitized_label ) {
                    continue;
                }

                $field_labels[ $sanitized_key ] = $sanitized_label;
            }
        }

        $result = [
            'delimiter'         => $delimiter,
            'encoding'          => $encoding,
            'filename'          => $filename,
            'attach_images_zip' => $attach_zip ? 1 : 0,
        ];

        if ( ! empty( $field_labels ) ) {
            $result['field_labels'] = $field_labels;
        }

        return $result;
    }
}

