<?php

namespace YayMail\Controllers;

use YayMail\Abstracts\BaseController;
use YayMail\Models\PatternTemplateModel;
use YayMail\Utils\SingletonTrait;
use YayMail\Models\TemplateModel;
use YayMail\Integrations\TranslationModule;
use YayMail\YayMailTemplate;
use YayMail\Utils\TemplateHelpers;

/**
 * Pattern Template Controller
 *
 * @method static PatternTemplateController get_instance()
 */
class PatternTemplateController extends BaseController {
    use SingletonTrait;

    private $model = null;

    protected function __construct() {
        $this->model = PatternTemplateModel::get_instance();
        $this->init_hooks();
    }

    protected function init_hooks() {
        $template_id_args = [
            'template_id' => [
                'type'     => 'string',
                'required' => true,
            ],
        ];

        // Get all patterns templates
        register_rest_route(
            YAYMAIL_REST_NAMESPACE,
            '/pattern-templates',
            [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'exec_get_all_pattern_templates' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => [
                        'filter' => [
                            'type'     => 'string',
                            'required' => false,
                            'enum'     => [ 'most_uses', 'date_created' ],
                        ],
                    ],
                ],
                [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'exec_create_pattern_template' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => [
                        'name'     => [
                            'type'     => 'string',
                            'required' => true,
                        ],
                        'elements' => [
                            'type'     => 'array',
                            'required' => false,
                        ],
                        'status'   => [
                            'type'     => 'string',
                            'required' => false,
                        ],
                    ],
                ],
            ]
        );

        // Get, update, delete patterns template by ID
        register_rest_route(
            YAYMAIL_REST_NAMESPACE,
            '/pattern-templates/(?P<template_id>\d+)',
            [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'exec_get_pattern_template_by_id' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => $template_id_args,
                ],
                [
                    'methods'             => \WP_REST_Server::EDITABLE,
                    'callback'            => [ $this, 'exec_update_pattern_template' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => array_merge(
                        $template_id_args,
                        [
                            'name'     => [
                                'type'     => 'string',
                                'required' => false,
                            ],
                            'elements' => [
                                'type'     => 'array',
                                'required' => false,
                            ],
                            'status'   => [
                                'type'     => 'string',
                                'required' => false,
                            ],
                        ]
                    ),
                ],
                [
                    'methods'             => \WP_REST_Server::DELETABLE,
                    'callback'            => [ $this, 'exec_delete_pattern_template' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => $template_id_args,
                ],
            ]
        );

        // Change status of patterns templates
        register_rest_route(
            YAYMAIL_REST_NAMESPACE,
            '/pattern-templates/change-status',
            [
                [
                    'methods'             => \WP_REST_Server::EDITABLE,
                    'callback'            => [ $this, 'exec_change_pattern_status' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => [
                        'list_id' => [
                            'type'     => 'array',
                            'required' => true,
                        ],
                        'status'  => [
                            'type'     => 'string',
                            'required' => true,
                        ],
                    ],
                ],
            ]
        );

        // Copy patterns template
        register_rest_route(
            YAYMAIL_REST_NAMESPACE,
            '/pattern-templates/copy-template',
            [
                [
                    'methods'             => \WP_REST_Server::EDITABLE,
                    'callback'            => [ $this, 'exec_copy_pattern_template' ],
                    'permission_callback' => [ $this, 'permission_callback' ],
                    'args'                => [
                        'template_id'   => [
                            'type'     => 'string',
                            'required' => true,
                        ],
                        'from_template' => [
                            'type'     => 'string',
                            'required' => true,
                        ],
                    ],
                ],
            ]
        );
    }

    // CREATE
    public function exec_create_pattern_template( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'create_pattern_template' ], $request );
    }

    public function create_pattern_template( \WP_REST_Request $request ) {
        $name     = sanitize_text_field( $request->get_param( 'name' ) );
        $elements = $request->get_param( 'elements' ) ?? [];
        $status   = sanitize_text_field( $request->get_param( 'status' ) ) ?? 'active';

        if ( empty( $name ) ) {
            return [
                'success' => false,
                'message' => 'Template name is required',
            ];
        }

        $insert_data = [
            'name'     => $name,
            'elements' => $elements,
            'status'   => $status,
        ];

        $template_data = $this->model::insert( $insert_data );
        return [
            'success' => true,
            'data'    => $template_data,
        ];
    }

    // READ
    public function exec_get_all_pattern_templates( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'get_all_pattern_templates' ], $request );
    }

    public function get_all_pattern_templates( \WP_REST_Request $request ) {
        $filter = sanitize_text_field( $request->get_param( 'filter' ) ) ?? 'date_created';

        $templates = $this->model->find_all();

        switch ( $filter ) {
            case 'date_created':
                usort(
                    $templates,
                    function( $a, $b ) {
                        $date_a = get_post_field( 'post_date', $a['id'] );
                        $date_b = get_post_field( 'post_date', $b['id'] );
                        return strtotime( $date_b ) - strtotime( $date_a );
                    }
                );
                break;
            case 'most_uses':
            default:
                // Cache usage counts to avoid recalculating
                $usage_counts = [];
                foreach ( $templates as $template ) {
                    $usage_counts[ $template['id'] ] = $this->count_pattern_usage( $template['id'] );
                }

                usort(
                    $templates,
                    function( $a, $b ) use ( $usage_counts ) {
                        $usage_a = $usage_counts[ $a['id'] ] ?? 0;
                        $usage_b = $usage_counts[ $b['id'] ] ?? 0;

                        if ( $usage_a !== $usage_b ) {
                            return $usage_b - $usage_a;
                        }

                        $date_a = strtotime( get_post_field( 'post_date', $a['id'] ) );
                        $date_b = strtotime( get_post_field( 'post_date', $b['id'] ) );

                        return $date_b - $date_a;
                    }
                );
                break;
        }//end switch

        return apply_filters( 'yaymail_get_all_pattern_templates', $templates );
    }

    /**
     * Count how many templates use a specific pattern
     *
     * @param string $pattern_id Pattern ID to count usage for
     * @return int Number of templates using this pattern
     */
    private function count_pattern_usage( $pattern_id ) {
        $list_templates = TemplateModel::find_all();
        $language       = TranslationModule::get_instance()->get_active_language();
        $usage_count    = 0;

        foreach ( $list_templates as $template_data ) {
            $template = new YayMailTemplate( $template_data['name'], $language );
            $elements = $template->get_elements();

            foreach ( $elements as $element ) {
                if ( $element['type'] === 'synced_pattern' &&
                    isset( $element['data']['pattern_id'] ) &&
                    $element['data']['pattern_id'] === (string) $pattern_id ) {
                    ++$usage_count;
                    break;
                }
            }
        }

        return $usage_count;
    }

    public function exec_get_pattern_template_by_id( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'get_pattern_template_by_id' ], $request );
    }

    public function get_pattern_template_by_id( \WP_REST_Request $request ) {
        $id            = sanitize_text_field( $request->get_param( 'template_id' ) );
        $template_data = $this->model::find_by_id( $id );

        if ( ! $template_data ) {
            return [
                'success' => false,
                'message' => 'Pattern template not found',
            ];
        }

        return $template_data;
    }



    // UPDATE
    public function exec_update_pattern_template( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'update_pattern_template' ], $request );
    }

    public function update_pattern_template( \WP_REST_Request $request ) {
        $id       = sanitize_text_field( $request->get_param( 'template_id' ) );
        $name     = sanitize_text_field( $request->get_param( 'name' ) );
        $elements = $request->get_param( 'template_elements' );
        $status   = sanitize_text_field( $request->get_param( 'status' ) );

        $update_data = [];

        if ( ! is_null( $name ) ) {
            $update_data['name'] = $name;
        }

        if ( ! is_null( $elements ) ) {
            $update_data['elements'] = $elements;
        }

        if ( ! empty( $status ) ) {
            $update_data['status'] = $status;
        }

        if ( empty( $update_data ) ) {
            return [
                'success' => false,
                'message' => 'No data to update',
            ];
        }

        $updated_data = $this->model::update( $id, $update_data, true );
        return [
            'success' => true,
            'data'    => $updated_data,
        ];
    }

    public function exec_change_pattern_status( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'change_pattern_status' ], $request );
    }

    public function change_pattern_status( \WP_REST_Request $request ) {
        $list_id = is_array( $request->get_param( 'list_id' ) ) ? array_map( 'sanitize_text_field', wp_unslash( $request->get_param( 'list_id' ) ) ) : [];
        $status  = sanitize_text_field( $request->get_param( 'status' ) );

        if ( empty( $list_id ) ) {
            return [
                'success' => false,
                'message' => 'No templates selected',
            ];
        }

        foreach ( $list_id as $id ) {
            $this->model::update(
                $id,
                [
                    'status' => $status,
                ]
            );
        }

        return [ 'success' => true ];
    }

    public function exec_copy_pattern_template( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'copy_pattern_template' ], $request );
    }

    public function copy_pattern_template( \WP_REST_Request $request ) {
        $template_id   = sanitize_text_field( $request->get_param( 'template_id' ) );
        $from_template = sanitize_text_field( $request->get_param( 'from_template' ) );

        $copy_template_data = $this->model::find_by_name( $from_template );

        if ( empty( $copy_template_data ) || empty( $copy_template_data['id'] ) ) {
            return [
                'success' => false,
                'message' => 'Source template not found',
            ];
        }

        $update_data = [
            'elements' => ! empty( $copy_template_data['elements'] ) ? $copy_template_data['elements'] : [],
            'status'   => $copy_template_data['status'] ?? 'inactive',
        ];

        $this->model::update( $template_id, $update_data, true );
        return [
            'success' => true,
        ];
    }

    // DELETE
    public function exec_delete_pattern_template( \WP_REST_Request $request ) {
        return $this->exec( [ $this, 'delete_pattern_template' ], $request );
    }

    public function delete_pattern_template( \WP_REST_Request $request ) {
        $id = sanitize_text_field( $request->get_param( 'template_id' ) );

        try {
            $template_data = $this->model::find_by_id( $id );
            if ( ! $template_data ) {
                return [
                    'success' => false,
                    'message' => 'Pattern template not found',
                ];
            }

            $this->model::delete( $id );

            $list_templates = TemplateModel::find_all();
            $language       = TranslationModule::get_instance()->get_active_language();

            foreach ( $list_templates as $template_data ) {
                try {
                    $template              = new YayMailTemplate( $template_data['name'], $language );
                    $elements              = $template->get_elements();
                    $remove_pattern_result = TemplateHelpers::remove_pattern_from_template( $elements, $id );
                    $new_elements          = $remove_pattern_result['elements'];
                    $removed_pattern_count = $remove_pattern_result['count'];
                    if ( $removed_pattern_count > 0 ) {
                        TemplateModel::update(
                            $template->get_id(),
                            [ 'elements' => $new_elements ],
                            false
                        );
                    }
                } catch ( \Exception $e ) {
                    yaymail_get_logger( 'Error updating template ' . $template_data['name'] . ': ' . $e->getMessage() );
                    continue;
                }//end try
            }//end foreach
            return [ 'success' => true ];
        } catch ( \Error $error ) {
            yaymail_get_logger( $error );
        } catch ( \Exception $exception ) {
            yaymail_get_logger( $exception );
        }//end try
    }
}
