<?php

namespace YayMail\Models;

use YayMail\YayMailPatternTemplate;
use YayMail\Utils\SingletonTrait;

/**
 * Patterns Template Model
 *
 * @method static PatternTemplateModel get_instance()
 */
class PatternTemplateModel extends TemplateModel {
    use SingletonTrait;

    /**
     * Override meta keys to use YayMailPatternTemplate
     */
    private static $meta_keys = YayMailPatternTemplate::META_KEYS;

    /**
     * Override find_all to only return patterns templates
     *
     * @param string $language Language code (not used for patterns).
     */
    public static function find_all( $language = '' ) {
        // Query only patterns templates directly
        $args = [
            'post_type'      => \YayMail\PostTypes\PatternTemplatePostType::POST_TYPE,
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'orderby'        => 'post_modified',
            'order'          => 'DESC',
        ];

        $posts              = get_posts( $args );
        $patterns_templates = [];

        foreach ( $posts as $post ) {
            $pattern_data = self::get_meta_data( $post->ID );
            if ( ! empty( $pattern_data ) ) {
                $patterns_templates[] = $pattern_data;
            }
        }

        return $patterns_templates;
    }

    /**
     * Find template by post id
     * Returns null if not found
     *
     * @param number $id
     */
    public static function find_by_id( $id ) {
        if ( ! empty( $id ) && ! is_null( get_post( $id ) ) ) {
            return self::get_meta_data( $id );
        }
        return null;
        // Returns null on failure
    }

    /**
     * Override find_by_name to only handle patterns template without language
     *
     * @param string $name Template name.
     * @param string $language Language code (not used for patterns).
     * @return array|null Template data.
     */
    public static function find_by_name( $name, $language = '' ) {
        // Query only patterns templates directly
        $args = [
            'post_type'      => \YayMail\PostTypes\PatternTemplatePostType::POST_TYPE,
            'post_status'    => 'publish',
            'posts_per_page' => 1,
            'meta_query'     => [
                [
                    'key'     => self::$meta_keys['name'],
                    'value'   => $name,
                    'compare' => '=',
                ],
            ],
        ];

        $posts = get_posts( $args );

        if ( empty( $posts ) ) {
            return null;
        }

        return self::get_meta_data( $posts[0]->ID, $name );
    }

    /**
     * Override insert to only handle patterns template fields
     *
     * @param array $args Template data.
     * @return array Template data.
     */
    public static function insert( $args = false ) {
        // Insert template data to posts table
        $template_args   = [
            'post_content' => '',
            'post_type'    => \YayMail\PostTypes\PatternTemplatePostType::POST_TYPE,
            'post_title'   => '',
            'post_status'  => 'publish',
        ];
        $new_template_id = wp_insert_post( $template_args );

        // Insert data to post meta table - only patterns template fields
        update_post_meta( $new_template_id, self::$meta_keys['name'], $args['name'] );
        update_post_meta( $new_template_id, self::$meta_keys['elements'], $args['elements'] );
        update_post_meta( $new_template_id, self::$meta_keys['status'], 'active' );

        return self::get_meta_data( $new_template_id );
    }

    /**
     * Override update to only handle patterns template fields
     *
     * @param int   $template_id Template ID.
     * @param array $data Template data.
     * @param bool  $is_save_revision Whether to save revision.
     * @return array Template data.
     */
    public static function update( $template_id, $data, $is_save_revision = false ) {
        if ( isset( $data['elements'] ) && is_array( $data['elements'] ) && isset( self::$meta_keys['elements'] ) ) {
            update_post_meta( $template_id, self::$meta_keys['elements'], $data['elements'] );
        }

        if ( isset( $data['status'] ) && isset( self::$meta_keys['status'] ) ) {
            update_post_meta( $template_id, self::$meta_keys['status'], $data['status'] );
        }

        if ( ! empty( $data['name'] ) && isset( self::$meta_keys['name'] ) ) {
            update_post_meta( $template_id, self::$meta_keys['name'], $data['name'] );
        }

        // Update post_modified
        $post_data = [
            'ID'                => $template_id,
            'post_modified'     => current_time( 'mysql' ),
            'post_modified_gmt' => current_time( 'mysql', 1 ),
        ];
        wp_update_post( $post_data, true );

        if ( $is_save_revision ) {
            try {
                $revision_model = RevisionModel::get_instance();
                $new_revision   = $revision_model->save( $template_id, $data );
            } catch ( \Throwable $th ) {
                $new_revision = null;
            }

            return [
                'updated_data' => self::get_meta_data( $template_id ),
                'new_revision' => $new_revision,
            ];
        }

        return self::get_meta_data( $template_id );
    }

    /**
     * Override get_meta_data to only return patterns template fields
     *
     * @param int    $template_post_id Template ID.
     * @param string $template_name Template name.
     * @return array Template data.
     */
    private static function get_meta_data( $template_post_id, $template_name = null ) {
        if ( empty( $template_name ) ) {
            $template_name = self::query_meta_data( $template_post_id, self::$meta_keys['name'], '' );
        }
        $status = self::query_meta_data( $template_post_id, self::$meta_keys['status'], 'inactive' );

        // /** For editable templates */
        $template_elements = self::query_meta_data( $template_post_id, self::$meta_keys['elements'], [] );
        $created_at        = get_the_date( 'Y-m-d H:i:s', $template_post_id );
        return [
            'id'             => $template_post_id,
            'key'            => 'pattern_' . $template_post_id,
            'name'           => $template_name,
            'elements'       => $template_elements,
            'status'         => $status,
            'created_at'     => $created_at,
            'support_status' => 'already_supported',
        ];
    }

    /**
     * Override query_meta_data to use patterns meta keys
     *
     * @param int    $post_id Post ID.
     * @param string $meta_name Meta name.
     * @param mixed  $default Default value.
     * @return mixed Meta value.
     */
    protected static function query_meta_data( $post_id, $meta_name, $default ) {
        if ( ! isset( $post_id ) ) {
            return $default;
        }

        $meta_value = get_post_meta( $post_id, $meta_name, true );

        if ( empty( $meta_value ) ) {
            return $default;
        }
        return $meta_value;
    }

    public static function get_pattern_template_shortcodes() {
        $common_shortcodes          =
            \YayMail\Shortcodes\CommonShortcodes::get_instance()->get_shortcodes();
        $order_details_shortcodes   =
            \YayMail\Shortcodes\OrderDetails\OrderDetailsShortcodes::get_instance()->get_shortcodes();
        $hook_shortcodes            =
            \YayMail\Shortcodes\HookShortcodes::get_instance()->get_shortcodes();
        $shipping_shortcodes        =
            \YayMail\Shortcodes\ShippingShortcodes::get_instance()->get_shortcodes();
        $billing_shortcodes         =
            \YayMail\Shortcodes\BillingShortcodes::get_instance()->get_shortcodes();
        $payments_shortcodes        =
            \YayMail\Shortcodes\PaymentsShortcodes::get_instance()->get_shortcodes();
        $new_users_shortcodes       =
            \YayMail\Shortcodes\NewUsersShortcodes::get_instance()->get_shortcodes();
        $reset_passwords_shortcodes =
            \YayMail\Shortcodes\ResetPasswordsShortcodes::get_instance()->get_shortcodes();
        $refund_shortcodes          =
            \YayMail\Shortcodes\RefundShortcodes::get_instance()->get_shortcodes();

        $shortcodes    = array_merge(
            $common_shortcodes,
            $order_details_shortcodes,
            $hook_shortcodes,
            $shipping_shortcodes,
            $billing_shortcodes,
            $payments_shortcodes,
            $new_users_shortcodes,
            $reset_passwords_shortcodes,
            $refund_shortcodes,
        );
        $shortcodes    = apply_filters( 'yaymail_extra_shortcodes', $shortcodes, [] );
        $executor_data = self::get_shortcode_executor_data( 'pattern_template', null );
        $executor      = new \YayMail\Shortcodes\ShortcodesExecutor( $shortcodes, $executor_data );
        return $executor->get_shortcodes_content();
    }
}
