<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * Canonical settings schema shared by activation, settings UI, onboarding,
 * runtime email attachment logic, and automatic document generation.
 */
class PBUAIV_Settings_Schema {

    public static function automation_rules() : array {
        return [
            'invoice' => [
                'label'   => __( 'Tax Invoice', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_auto_invoice_status',
                'default' => [ 'processing' ],
            ],
            'receipt' => [
                'label'   => __( 'Payment Receipt', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_auto_receipt_status',
                'default' => [ 'completed' ],
            ],
            'credit_note' => [
                'label'   => __( 'Credit Note', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_auto_credit_note_status',
                'default' => [ 'refunded' ],
            ],
        ];
    }

    public static function attachment_rules() : array {
        return [
            'invoice' => [
                'label'   => __( 'Tax Invoice', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_attach_invoice_emails',
                'default' => [ 'customer_processing_order', 'customer_invoice' ],
            ],
            'receipt' => [
                'label'   => __( 'Payment Receipt', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_attach_receipt_emails',
                'default' => [ 'customer_completed_order' ],
            ],
            'credit_note' => [
                'label'   => __( 'Credit Note', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_attach_credit_note_emails',
                'default' => [ 'customer_refunded_order' ],
            ],
            'proforma' => [
                'label'   => __( 'Proforma Invoice', 'pb-invoicing-system' ),
                'option'  => 'pbuaiv_attach_proforma_emails',
                'default' => [],
            ],
        ];
    }

    /** @return array<string,string> */
    public static function customer_emails() : array {
        $choices = [];
        if ( ! function_exists( 'WC' ) || ! WC() || ! WC()->mailer() ) {
            return $choices;
        }
        foreach ( WC()->mailer()->get_emails() as $email_obj ) {
            if ( ! is_object( $email_obj ) || ! method_exists( $email_obj, 'is_customer_email' ) || ! $email_obj->is_customer_email() ) {
                continue;
            }

            // WC()->mailer()->get_emails() is commonly keyed by class name
            // (for example WC_Email_Customer_Completed_Order), while the
            // woocommerce_email_attachments filter supplies the email object's
            // canonical ID (customer_completed_order). Always save the latter.
            $email_id = isset( $email_obj->id ) ? sanitize_key( (string) $email_obj->id ) : '';
            if ( '' !== $email_id ) {
                $choices[ $email_id ] = $email_obj->get_title();
            }
        }
        return $choices;
    }


    /**
     * Read and normalize a saved array option from the canonical schema.
     * Handles stale scalar or nested values left by older wizard versions.
     *
     * @return array<int,string>
     */
    public static function get_array_option( string $option ) : array {
        $value = get_option( $option, self::option_default( $option ) );

        if ( is_string( $value ) ) {
            $value = '' === $value ? [] : [ $value ];
        }
        if ( ! is_array( $value ) ) {
            return self::option_default( $option );
        }

        $flat = [];
        array_walk_recursive( $value, static function( $item ) use ( &$flat ) : void {
            if ( is_scalar( $item ) && '' !== (string) $item ) {
                $flat[] = sanitize_key( (string) $item );
            }
        } );

        // Versions up to 1.7.4 saved WooCommerce mailer array keys such
        // as wc_email_customer_completed_order instead of the actual email ID.
        // Normalize those legacy values transparently so existing settings work
        // immediately after updating, without requiring the wizard to be rerun.
        if ( false !== strpos( $option, 'pbuaiv_attach_' ) ) {
            $flat = array_map( [ __CLASS__, 'normalize_email_id' ], $flat );
            $flat = array_values( array_filter( $flat ) );
        }

        return array_values( array_unique( $flat ) );
    }

    public static function normalize_email_id( string $email_id ) : string {
        $email_id = sanitize_key( $email_id );

        if ( 0 === strpos( $email_id, 'wc_email_' ) ) {
            $email_id = substr( $email_id, strlen( 'wc_email_' ) );
        } elseif ( 0 === strpos( $email_id, 'wcemail_' ) ) {
            $email_id = substr( $email_id, strlen( 'wcemail_' ) );
        }

        return sanitize_key( $email_id );
    }

    public static function option_default( string $option ) : array {
        foreach ( array_merge( self::automation_rules(), self::attachment_rules() ) as $rule ) {
            if ( $rule['option'] === $option ) {
                return $rule['default'];
            }
        }
        return [];
    }
}
