<?php
declare(strict_types=1);

namespace Itdatex\Ausgangsrechnung\Admin\Pages;

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

use Itdatex\Ausgangsrechnung\Numbering;
use Itdatex\Ausgangsrechnung\Plugin;
use Itdatex\Ausgangsrechnung\Settings as SettingsStore;

/**
 * Settings-Seite — Verkaeufer-Daten + Default-Zahlungsdaten.
 */
final class SettingsPage
{
    public const ACTION = 'ausrg_save_settings';
    public const NONCE  = 'ausrg_settings_nonce';

    public static function render(): void
    {
        if ( ! current_user_can( Plugin::CAPABILITY ) ) {
            wp_die( esc_html__( 'Keine Berechtigung.', 'itdatex-e-invoice-output' ), '', [ 'response' => 403 ] );
        }

        $notice = self::handle_save();

        $seller    = SettingsStore::sellerRaw();
        $payment   = SettingsStore::paymentRaw();
        $missing   = SettingsStore::missingSellerFields();
        $numbering = [
            'pattern'       => Numbering::pattern(),
            'counter'       => Numbering::counter(),
            'yearly_reset'  => Numbering::yearlyReset(),
            'next_preview'  => Numbering::nextSuggestion(),
        ];

        $action_url = admin_url( 'admin.php?page=ausrg-settings' );
        include AUSRG_DIR . 'admin/views/page-settings.php';
    }

    private static function handle_save(): string
    {
        $method = isset( $_SERVER['REQUEST_METHOD'] )
            ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) )
            : '';
        if ( $method !== 'POST' ) {
            return '';
        }
        check_admin_referer( self::ACTION, self::NONCE );

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array wird pro-Key sanitized in $seller/$payment unten (sanitize_text_field / sanitize_email / sanitize_textarea_field bzw. plugin-eigene Sanitizer).
        $rawSeller  = ( isset( $_POST['seller']  ) && is_array( $_POST['seller']  ) ) ? wp_unslash( $_POST['seller']  ) : [];
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array wird pro-Key sanitized in $payment unten.
        $rawPayment = ( isset( $_POST['payment'] ) && is_array( $_POST['payment'] ) ) ? wp_unslash( $_POST['payment'] ) : [];
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array wird pro-Key sanitized in self::save_numbering() unten.
        $rawNumbering = ( isset( $_POST['numbering'] ) && is_array( $_POST['numbering'] ) ) ? wp_unslash( $_POST['numbering'] ) : [];

        $seller = [
            'name'                      => sanitize_text_field( (string) ( $rawSeller['name']          ?? '' ) ),
            'vat_number'                => self::sanitize_vat( (string) ( $rawSeller['vat_number']    ?? '' ) ),
            'address'                   => sanitize_textarea_field( (string) ( $rawSeller['address']  ?? '' ) ),
            'city'                      => sanitize_text_field( (string) ( $rawSeller['city']         ?? '' ) ),
            'postal_code'               => sanitize_text_field( (string) ( $rawSeller['postal_code']  ?? '' ) ),
            'country_code'              => self::sanitize_country( (string) ( $rawSeller['country_code'] ?? '' ) ),
            'contact_name'              => sanitize_text_field( (string) ( $rawSeller['contact_name']  ?? '' ) ),
            'contact_email'             => sanitize_email( (string) ( $rawSeller['contact_email']     ?? '' ) ),
            'contact_phone'             => self::sanitize_phone( (string) ( $rawSeller['contact_phone'] ?? '' ) ),
            'electronic_address_scheme' => self::sanitize_eas_scheme( (string) ( $rawSeller['electronic_address_scheme'] ?? '' ) ),
            'electronic_address_value'  => sanitize_text_field( (string) ( $rawSeller['electronic_address_value']  ?? '' ) ),
        ];

        $payment = [
            'iban'  => self::sanitize_iban( (string) ( $rawPayment['iban']  ?? '' ) ),
            'bic'   => self::sanitize_bic(  (string) ( $rawPayment['bic']   ?? '' ) ),
            'terms' => sanitize_textarea_field( (string) ( $rawPayment['terms'] ?? '' ) ),
        ];

        update_option( SettingsStore::OPTION_SELLER,  $seller );
        update_option( SettingsStore::OPTION_PAYMENT, $payment );
        self::save_numbering( $rawNumbering );

        return __( 'Einstellungen gespeichert.', 'itdatex-e-invoice-output' );
    }

    /**
     * @param array<string, mixed> $raw
     */
    private static function save_numbering( array $raw ): void
    {
        $pattern = sanitize_text_field( (string) ( $raw['pattern'] ?? '' ) );
        if ( $pattern === '' ) {
            $pattern = Numbering::DEFAULT_PATTERN;
        }
        update_option( Numbering::OPTION_PATTERN, $pattern );
        update_option( Numbering::OPTION_YEARLY_RESET, ! empty( $raw['yearly_reset'] ) );

        // Counter darf per Hand justiert werden (typischer Fall: Umstieg
        // von einem bestehenden System mit laufender Nummer).
        if ( isset( $raw['counter'] ) && $raw['counter'] !== '' ) {
            $counter = max( 1, (int) $raw['counter'] );
            update_option( Numbering::OPTION_COUNTER, $counter );
        }
    }

    private static function sanitize_phone( string $value ): string
    {
        // Erlaube Ziffern + " +-/()" — typische Telefonzeichen
        $value = preg_replace( '/[^0-9+\-\/() ]/', '', $value ) ?? '';
        return trim( $value );
    }

    private static function sanitize_eas_scheme( string $value ): string
    {
        // EAS-Codes sind 2 (z.B. "EM") oder 4 Zeichen (z.B. "0204"). Buchstaben + Ziffern.
        $value = strtoupper( preg_replace( '/[^A-Za-z0-9]/', '', $value ) ?? '' );
        return substr( $value, 0, 4 );
    }

    private static function sanitize_country( string $value ): string
    {
        $value = strtoupper( preg_replace( '/[^A-Za-z]/', '', $value ) ?? '' );
        return strlen( $value ) === 2 ? $value : '';
    }

    private static function sanitize_vat( string $value ): string
    {
        // Erlaubt Buchstaben + Ziffern; alles andere raus
        return strtoupper( preg_replace( '/[^A-Za-z0-9]/', '', $value ) ?? '' );
    }

    private static function sanitize_iban( string $value ): string
    {
        return strtoupper( preg_replace( '/[^A-Za-z0-9]/', '', $value ) ?? '' );
    }

    private static function sanitize_bic( string $value ): string
    {
        return strtoupper( preg_replace( '/[^A-Za-z0-9]/', '', $value ) ?? '' );
    }
}
