<?php
namespace Formipay;
use Formipay\Traits\SingletonTrait;

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

class Access {

    use SingletonTrait;

	/**
	 * Initializes the plugin by setting filters and administration functions.
	 */
    
    protected function __construct() {

        add_action( 'init',                                 [$this, 'cpt'] );
        add_action( 'admin_menu',                           [$this, 'add_submenu'] );
        add_action( 'admin_enqueue_scripts',                [$this, 'enqueue_admin'] );

        add_filter( 'stm_wpcfto_boxes',                     [$this, 'cpt_post_fields_box'] );
        add_filter( 'stm_wpcfto_fields',                    [$this, 'cpt_post_fields_content'] );
        add_filter( 'formipay/product-config',              [$this, 'product_config'], 50 );
        add_filter( 'formipay/access-config',               [$this, 'source_config'] );
        add_filter( 'formipay/access-config',               [$this, 'details_config'] );

        // Admin Page
        add_action( 'wp_ajax_formipay_access_items_get_products',   [$this, 'formipay_access_items_get_products'] );
        add_action( 'wp_ajax_formipay-tabledata-access-items',      [$this, 'formipay_tabledata_access_items'] );
        add_action( 'wp_ajax_formipay-create-access-item-post',     [$this, 'formipay_create_access_item_post'] );
        add_action( 'wp_ajax_formipay-delete-access-item',          [$this, 'formipay_delete_access_item'] );
        add_action( 'wp_ajax_formipay-bulk-delete-access-item',     [$this, 'formipay_bulk_delete_access_item'] );
        add_action( 'wp_ajax_formipay-duplicate-access-item',       [$this, 'formipay_duplicate_access_item'] );

    }

    public function cpt() {

        $labels = array(
            'name'                  => __('Access Items', 'formipay'),
            'singular_name'         => __('Access Item', 'formipay'),
            'add_new'               => __('Add New', 'formipay'),
            'add_new_item'          => __('Add New Access Item', 'formipay'),
            'edit'                  => __('Edit', 'formipay'),
            'edit_item'             => __('Edit Access Item', 'formipay'),
            'new_item'              => __('New Access Item', 'formipay'),
            'view'                  => __('View', 'formipay'),
            'view_item'             => __('View Access Item', 'formipay'),
            'search_items'          => __('Search Access Item', 'formipay'),
            'not_found'             => __('No access items found', 'formipay'),
            'not_found_in_trash'    => __('No access items found in trash', 'formipay'),
            'parent'                => __('Access Item Parent', 'formipay')
        );
    
        $args = array(
            'label'                 => 'Formipay Access',
            'description'           => __('The items your buyer will get after purchase.', 'formipay'),
            'labels'                => $labels,
            'public'                => false,
            'supports'              => array( 'title' ),
            'hierarchical'          => false,
            'has_archive'           => false,
            'show_ui'               => true,
            'show_in_menu'          => false,
            'show_in_rest'          => false,
            'query_var'             => true
        );
    
        register_post_type( 'formipay-access', $args );

    }

    public function add_submenu() {

        add_submenu_page( 
            'formipay', 
            __( 'Access Items', 'formipay' ), 
            __( 'Access Items', 'formipay' ), 
            'manage_options', 
            'formipay-access-items',
            [$this, 'formipay_access_items']
        );

    }

    public function formipay_access_items() {
        include_once FORMIPAY_PATH . 'admin/page-access-items.php';
    }

    public function enqueue_admin() {

        global $current_screen;

        $screen = get_current_screen();

        // Check that we are on the 'Checker' post editor screen
        if ( $screen->post_type === 'formipay-access' && $screen->base === 'post' ) {
            
            wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION );
            wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
            wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);

            wp_localize_script( 'sweetalert2', 'formipay_admin', [
                'ajax_url' => admin_url('admin-ajax.php'),
                'site_url' => site_url(),
            ] );

        }

        if($current_screen->id == 'formipay_page_formipay-access-items') {
            
            wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], 'all');
            wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
            wp_enqueue_style( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.mermaid.min.css', [], '6.2.0', 'all' );
            wp_enqueue_style( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.css', [], FORMIPAY_VERSION, 'all' );
            wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
            wp_enqueue_style( 'page-access-items', FORMIPAY_URL . 'admin/assets/css/page-access-items.css', [], FORMIPAY_VERSION, 'all' );

            wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
            wp_enqueue_script( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/js/admin-pages.js', ['jquery'], FORMIPAY_VERSION, true );
            wp_enqueue_script( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.production.min.js', ['jquery'], '6.2.0', true );
            wp_enqueue_script( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.js', [], FORMIPAY_VERSION, true );
            wp_enqueue_script( 'page-access-items', FORMIPAY_URL . 'admin/assets/js/page-access-items.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );

            wp_localize_script( 'page-access-items', 'formipay_access_page', [
                'ajax_url' => admin_url('admin-ajax.php'),
                'site_url' => site_url(),
                'columns' => [
                    'id' => esc_html__( 'ID', 'formipay' ),
                    'title' => esc_html__( 'Title', 'formipay' ),
                    'type' => esc_html__( 'Type', 'formipay' ),
                    'products' => esc_html__( 'Product Relation', 'formipay' ),
                    'status' => esc_html__( 'Status', 'formipay' ),
                ],
                'filter_form' => [
                    'products' => [
                        'placeholder' => esc_html__( 'Filter by Product', 'formipay' ),
                        'noresult_text' => esc_html__( 'No results found', 'formipay' )
                    ]
                ],
                'modal' => [
                    'add' => [
                        'title' => esc_html__( 'Your New Item Title', 'formipay' ),
                        'validation' => esc_html__( 'Item\'s title is still empty. Please input the title before continue', 'formipay' ),
                        'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
                        'confirmButton' => esc_html__( 'Create New Item', 'formipay' )
                    ],
                    'delete' => [
                        'question' => esc_html__( 'Do you want to delete the item?', 'formipay' ),
                        'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
                        'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
                    ],
                    'bulk_delete' => [
                        'question' => esc_html__( 'Do you want to delete the selected the form(s)?', 'formipay' ),
                        'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
                        'confirmButton' => esc_html__( 'Confirm', 'formipay' )
                    ],
                    'duplicate' => [
                        'question' => esc_html__( 'Do you want to duplicate the item?', 'formipay' ),
                        'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
                        'confirmButton' => esc_html__( 'Confirm', 'formipay' )
                    ],
                ],
                'nonce' => wp_create_nonce('formipay-admin-access-nonce')
            ] );
        }

    }

    public function cpt_post_fields_box($boxes) {
        $boxes['formipay_access_settings'] = array(
            'post_type' => array('formipay-access'),
            'label' => __('Details', 'formipay'),
        );
    
        return $boxes;
    }

    public function cpt_post_fields_content($fields) {

        $fields['formipay_access_settings'] = array();

        $fields = apply_filters( 'formipay/access-config', $fields );
    
        return $fields;

    }

    public function product_config($fields){

        // Product Access Group

        $product_access_group = array(
            'setting_product_access' => array(
                'type'          => 'group_title',
                'label'         => __( 'Digital Accesses', 'formipay' ),
                'description'   => __( 'List files & URLs that buyer can get after complete the transaction', 'formipay' ),
                'group'         => 'started'
            ),
            'product_accesses'  => array(
                'type'      => 'autocomplete',
                'label'     => __( 'Accesses', 'formipay' ),
                'post_type' => array('formipay-access'),
                'limit'     => 10
            ),
            'product_access_to_email' => array(
                'type' => 'checkbox',
                'label' => __( 'Send Access Magic Link to Email', 'formipay' ),
            )
        );

        $product_access_group = apply_filters( 'formipay/product-settings/tab:access/group:product-access', $product_access_group );

        $last_product_access_group = array_key_last($product_access_group);
        $product_access_group[$last_product_access_group]['group'] = 'ended';

        $product_access_group = apply_filters( 'formipay/product-settings/tab:access', $product_access_group );

        $fields['formipay_product_settings']['access'] = array(
            'name'      => __( 'Access', 'formipay' ),
            'fields'    => $product_access_group
        );

        return $fields;

    }
    
    public function source_config($fields) {

        $get_attachments = get_posts([
            'post_type' => 'attachment',
            'posts_per_page' => -1    
        ]);

        $attachments = [];
        if(!empty($get_attachments)){
            foreach($get_attachments as $attachment){
                $attachments[$attachment->ID] = get_the_title($attachment->ID) . ' (' . $attachment->post_mime_type . ')';
            }
        }

        // Group : Fields
        $field_group = array(
            'file_url_group' => array(
                'type'  => 'group_title',
                'label' => __( 'Source', 'formipay' ),
                'description' => __( 'Define the source of this access.', 'formipay' ),
                'group' => 'started'
            ),
            'access_type' => array(
                'type' => 'select',
                'label' => __( 'Type', 'formipay' ),
                'options' => array(
                    'document' => __( 'Document', 'formipay' ),
                    'redirect'  => __( 'Redirect URL', 'formipay' ),
                    'download'  => __( 'File', 'formipay' )
                ),
                'value' => 'document'
            ),
            'access_document' => array(
                'type' => 'tinymce',
                'label' => __( 'Document', 'formipay' ),
                'dependency' => array(
                    'key'   => 'access_type',
                    'value' => 'document'
                ),
            ),
            'access_redirect_url' => array(
                'type' => 'text',
                'label' => __( 'URL', 'formipay' ),
                'dependency' => array(
                    'key'   => 'access_type',
                    'value' => 'redirect'
                ),
                'value' => 'https://'
            ),
            'access_download_source' => array(
                'type'      => 'select',
                'label'     => __( 'File Source', 'formipay' ),
                'options'   => array(
                    'wp_media' => __( 'WP Media', 'formipay' ),
                    'external' => __( 'External', 'formipay' )
                ),
                'dependency' => array(
                    'key'   => 'access_type',
                    'value' => 'download'
                ),
                'value' => 'wp_media'
            ),
            'access_attachment' => array(
                'type' => 'select',
                'label' => __( 'Select File', 'formipay' ),
                'options' => $attachments,
                'dependency' => array(
                    array(
                        'key'   => 'access_type',
                        'value' => 'download'
                    ),
                    array(
                        'key'   => 'access_download_source',
                        'value' => 'wp_media'
                    )
                ),
                'dependencies' => '&&'
            ),
            'access_url' => array(
                'type' => 'text',
                'label' => __( 'File URL', 'formipay' ),
                'dependency' => array(
                    array(
                        'key'   => 'access_type',
                        'value' => 'download'
                    ),
                    array(
                        'key'   => 'access_download_source',
                        'value' => 'external'
                    )
                ),
                'dependencies' => '&&',
                'value' => 'https://'
            )
        );

        $field_group = apply_filters( 'formipay/access-settings/tab:source/group:source', $field_group );

        $last_field_group = array_key_last($field_group);
        $field_group[$last_field_group]['group'] = 'ended';

        $button_group = array(
            'button_group' => array(
                'type' => 'group_title',
                'label' => __( 'Action Button', 'formipay' ),
                'description' => __( 'Set your action button for this access', 'formipay' ),
                'group' => 'started'
            ),
            'button_text' => array(
                'type' => 'text',
                'label' => __( 'Button Text', 'formipay' ),
                'value' => __( 'Download', 'formipay' ),
            )
        );

        $button_group = apply_filters( 'formipay/access-settings/tab:source/group:source', $button_group );

        $last_button_group = array_key_last($button_group);
        $button_group[$last_button_group]['group'] = 'ended';

        $all_group_merged = array_merge($field_group, $button_group);

        $settings_all_fields = apply_filters( 'formipay/access-settings/tab:source', $all_group_merged );

        $fields['formipay_access_settings']['source'] = array(
            'name' => __('Source', 'formipay'),
            'fields' => $settings_all_fields
        );

        return $fields;

    }
    
    public function details_config($fields) {

        // Group : Fields
        $field_group = array(
            'details_access_group' => array(
                'type'  => 'group_title',
                'label' => __( 'Details', 'formipay' ),
                'group' => 'started'
            ),
            'details_icon' => array(
                'type' => 'image',
                'label' => __( 'Custom Thumbnail', 'formipay' ),
                'description' => __( 'Please note this will be displayed in approx. 36x36 pixels', 'formipay' ),
            ),
            'details_filetype' => array(
                'type' => 'text',
                'label' => __( 'File Type', 'formipay' ),
                'description' => __( 'Example: zip for yourfile.zip.', 'formipay' ),
                'dependency' => array(
                    array(
                        'key' => 'access_type',
                        'value' => 'download',
                        'section' => 'source'
                    ),
                    array(
                        'key' => 'access_download_source',
                        'value' => 'external',
                        'section' => 'source'
                    ),
                ),
                'dependencies' => '&&'
            ),
            'details_filesize' => array(
                'type' => 'text',
                'label' => __('File Size', 'formipay'),
                'dependency' => array(
                    array(
                        'key' => 'access_type',
                        'value' => 'download',
                        'section' => 'source'
                    ),
                    array(
                        'key' => 'access_download_source',
                        'value' => 'external',
                        'section' => 'source'
                    ),
                ),
                'dependencies' => '&&'
            ),
            'details_short_description' => array(
                'type' => 'text',
                'label' => __( 'Short Description', 'formipay' ),
                'description' => __( 'You may put some important note to your buyer about this access', 'formipay' )
            )
        );

        $field_group = apply_filters( 'formipay/access-settings/tab:details/group:file-information', $field_group );

        $last_field_group = array_key_last($field_group);
        $field_group[$last_field_group]['group'] = 'ended';

        $details_all_fields = apply_filters( 'formipay/access-settings/tab:details', $field_group );

        $fields['formipay_access_settings']['details'] = array(
            'name' => __('Details', 'formipay'),
            'fields' => $details_all_fields
        );

        return $fields;

    }

    public function formipay_tabledata_access_items() {

        check_ajax_referer( 'formipay-admin-access-nonce', '_wpnonce' );

        $args = [
            'post_type' => 'formipay-access',
            'posts_per_page' => -1,
            'post_status' => array( 'pending', 'draft', 'publish' )
        ];

        if(!empty($_REQUEST['post_status']) && 'all' !== $_REQUEST['post_status']){
            $args['post_status'] = [ sanitize_text_field( wp_unslash( $_REQUEST['post_status'] ) ) ];
        }

        if(!empty($_REQUEST['product'])){
            $product_id = intval($_REQUEST['product']);
            $access_items_ids = formipay_get_post_meta($product_id, 'product_accesses');
            $access_items_ids = explode(',', $access_items_ids);
            $args['post__in'] = $access_items_ids;
        }

        $get_total_access_items = get_posts($args);

        if(isset($_REQUEST['limit'])){
            $args['posts_per_page'] = intval($_REQUEST['limit']);
        }

        if(isset($_REQUEST['offset'])){
            $args['offset'] = intval($_REQUEST['offset']);
        }

        if(!empty($_REQUEST['search'])){
            $args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
        }

        if(!empty($_REQUEST['sort']) && !empty($_REQUEST['orderby'])){
            $args['order'] = sanitize_text_field( wp_unslash($_REQUEST['sort']) );
            $args['orderby'] = sanitize_text_field( wp_unslash($_REQUEST['orderby']) );
        }

        $get_access_items = get_posts($args);

        // All Forms
        $forms = get_posts([
            'post_type' => 'formipay-form',
            'posts_per_page' => -1,
        ]);

        $access_items = [];
        if(!empty($get_access_items)){
            foreach($get_access_items as $access){

                $product_titles = [];
                if(!empty($forms)){
                    foreach($forms as $form){
                        $form_id = $form->ID;
                        $accesses = explode(',', formipay_get_post_meta($form_id, 'product_accesses'));
                        if(in_array($access->ID, $accesses)){
                            $product_titles[] = get_the_title($form_id);
                        }
                    }
                }

                $access_items[] = [
                    'ID' => $access->ID,
                    'title' => get_the_title($access->ID),
                    'type' => ucfirst(formipay_get_post_meta($access->ID, 'access_type')),
                    'products' => $product_titles,
                    'status' => $access->post_status
                ];
            }
        }

        // Get status counts using WordPress API
        $counts = wp_count_posts('formipay-access');
        $status_counts = [];
        foreach ($counts as $status => $count) {
            $status_counts[$status] = $count;
        }
        $status_counts['all'] = array_sum($status_counts);

        $response = [
            'results' => $access_items,
            'total' => count($get_total_access_items), // Total number of forms
            'posts_report' =>  array_map('intval', (array)$status_counts)
        ];

        wp_send_json($response);
    }

    public function formipay_access_items_get_products() {

        check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );

        if (!isset($_POST['search']) || empty($_POST['search'])) {
            wp_send_json_error( __('No search term provided.', 'formipay') );
        }

        $search_term = sanitize_text_field( wp_unslash( $_POST['search'] ));

        $query = get_posts([
            'post_type' => 'formipay-form',
            's'         => $search_term,
            'posts_per_page' => -1,
        ]);

        $results = [];
        if(!empty($query)){
            foreach($query as $post){
                $results[] = [
                    'value'   => $post->ID,
                    'label' => $post->post_title,
                ];
            }
        }

        wp_send_json($results);

    }

    public function formipay_create_access_item_post() {

        check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );

        if( !empty($_REQUEST['title']) ){
            $title = sanitize_text_field( wp_unslash($_REQUEST['title']) );
            $post_id = wp_insert_post( [
                'post_title' => $title,
                'post_type' => 'formipay-access',
            ], true );

            if(is_wp_error($post_id)){
                wp_send_json_error( [
                    'message' => $post_id->get_error_message()
                ] );
            }

            wp_send_json_success( [
                'edit_post_url' => admin_url('post.php?post='.$post_id.'&action=edit')
            ] );
        }

        wp_send_json_error( [
            'message' => esc_html__( 'Item\'s title is empty.', 'formipay' )
        ] );
        
    }

    public function formipay_delete_access_item() {

        check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );

        if( empty($_REQUEST['id']) ){
            wp_send_json_error( [
                'title' => esc_html__( 'Failed', 'formipay' ),
                'message' => esc_html__( 'Failed to delete item. Please try again.', 'formipay' ),
                'icon' => 'error'
            ] );
        }

        $post_id = intval($_REQUEST['id']);
        $delete = wp_delete_post($post_id, true);

        if(is_wp_error( $delete )){
            wp_send_json_error( [
                'title' => esc_html__( 'Failed', 'formipay' ),
                'message' => esc_html__( 'Failed to delete item. Please try again.', 'formipay' ),
                'icon' => 'error'
            ] );
        }

        wp_send_json_success( [
            'title' => esc_html__( 'Deleted', 'formipay' ),
            'message' => esc_html__( 'Item is deleted permanently.', 'formipay' ),
            'icon' => 'success'
        ] );

    }

    public function formipay_bulk_delete_access_item() {

        check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );

        if( empty($_REQUEST['ids']) ){
            wp_send_json_error( [
                'title' => esc_html__( 'Failed', 'formipay' ),
                'message' => esc_html__( 'There is no access item selected. Please try again.', 'formipay' ),
                'icon' => 'error'
            ] );
        }

        $ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : [];

        $success = 0;
        $failed = 0;
        $report = __( 'Done.', 'formipay' );
        if(!empty($ids)){
            foreach($ids as $id){
                $delete = wp_delete_post($id, true);
                if(is_wp_error( $delete )){
                    $failed++;
                }else{
                    $success++;
                }
            }
        }

        if($success > 0){
            $report .= sprintf( __( ' Deleted %d item(s).', 'formipay' ), $success);
        }
        if($failed > 0){
            $report .= sprintf( __( ' Failed %d item(s).', 'formipay' ), $failed);
        }

        wp_send_json_success( [
            'title' => esc_html__( 'Done!', 'formipay' ),
            'message' => $report,
            'icon' => 'info'
        ] );

    }

    public function formipay_duplicate_access_item() {

        check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );

        if( empty($_REQUEST['id']) ){
            wp_send_json_error( [
                'title' => esc_html__('Failed', 'formipay'),
                'message' => esc_html__( 'Item is not defined.', 'formipay' ),
                'icon' => 'error'
            ] );
        }
        
        $post_id = intval($_REQUEST['id']);
        $post = get_post($post_id);
        if (!$post) {
            wp_send_json_error( [
                'title' => esc_html__('Failed', 'formipay'),
                'message' => esc_html__( 'Item is not defined.', 'formipay' ),
                'icon' => 'error'
            ] );
        }
    
        // Pastikan hanya tipe posting yang bisa diduplikasi
        if (!in_array($post->post_type, ['formipay-access'])) {
            wp_send_json_error( [
                'title' => esc_html__('Failed', 'formipay'),
                'message' => esc_html__( 'Wrong Post Type.', 'formipay' ),
                'icon' => 'error'
            ] );
        }
    
        // Buat duplikat post
        $duplicate_post = [
            'post_title'   => $post->post_title . ' (Copy)',
            'post_content' => $post->post_content,
            'post_status'  => 'draft', // Set sebagai draft
            'post_type'    => $post->post_type,
            'post_author'  => $post->post_author,
        ];
    
        // Masukkan duplikat ke database
        $new_post_id = wp_insert_post($duplicate_post);
    
        if (is_wp_error($new_post_id)) {
            wp_send_json_error( [
                'title' => esc_html__('Failed', 'formipay'),
                'message' => esc_html__( 'Something happened. Please try again.', 'formipay' ),
                'icon' => 'error'
            ] );
        }
    
        // Salin semua meta data
        $meta_data = get_post_meta($post_id);
        foreach ($meta_data as $key => $values) {
            foreach ($values as $value) {
                update_post_meta($new_post_id, $key, maybe_unserialize($value));
            }
        }
    
        wp_send_json_success( [
            'title' => esc_html__('Duplicated!', 'formipay'),
            'message' => esc_html__( 'Form is successfully duplicated.', 'formipay' ),
            'icon' => 'success'
        ] );
    }

}