<?php

namespace KirilKirkov\WpInvoices;

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

/**
 * Add items
 * Validation and CRUD
 */
class CreateItem
{
    private static $validation_errors = [];

    public function create_item_page()
    {
        $success = null;
        $item = [];

        // if submit form
        if (
            isset( $_SERVER['REQUEST_METHOD'] ) && 
            $_SERVER['REQUEST_METHOD'] === 'POST' &&
            isset($_POST['kkwi_create_item_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['kkwi_create_item_nonce'])), 'kkwi_create_item_action')) {
              
            $_item = CreateItem::create_item($_POST);
            if($_item === false) {
                $errors = CreateItem::get_validation_errors();
                $success = false;
                $item = array_map('sanitize_text_field', wp_unslash($_POST));
            } else {
                $success = true;
            }
        }

        // if edit
        if(isset($_GET['edit'])) {
            if(!isset($_GET['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['nonce'])), 'edit_item_' . sanitize_text_field(wp_unslash($_GET['edit'])))) {
                wp_die( esc_html__('Invalid nonce', 'kirilkirkov-pdf-invoice-manager') );
            }
            
            $_item = Items::get_item(sanitize_text_field(wp_unslash($_GET['edit'])), true);
            if($_item === false) {
                require plugin_dir_path( __FILE__ ) . '../../Views/404.php';
                return;
            }
            if(!count($item)) {
                $item = $_item;
            }
        }

        $Config = Config::class;

        require plugin_dir_path( __FILE__ ) . '../../Views/Items/Create.php';
    }

    /**
     * @return bool
     */
    public static function create_item($post)
    {
        if (
            isset( $_SERVER['REQUEST_METHOD'] ) && 
            $_SERVER['REQUEST_METHOD'] === 'POST' &&
            (!isset($_POST['kkwi_create_item_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['kkwi_create_item_nonce'])), 'kkwi_create_item_action'))
        ) {
            wp_die( esc_html__('Invalid nonce', 'kirilkirkov-pdf-invoice-manager') );
        }

        $post = array_map('stripslashes_deep', $post);

        // validate
        if(!self::validate($post)) {
            return false;
        }

        $w = new Items();
        $current_user_id = get_current_user_id();
        global $wpdb;

        // if is insert
        if(!isset($post['id'])) {
            $dt = new \DateTime();
            $created_at = $dt->format('Y-m-d H:i:s');

            // Performing insert, do not need cache here. Using $wpdb->query() with prepare() – the standard and safe approach for this operation.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->query(
                $wpdb->prepare(
                    "INSERT INTO ".esc_sql($w->table_name)." 
                    ( name, price, available_quantity, created_from, created_at, updated_at )
                    VALUES ( %s, %s, %s, %d, %s, %s )",
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'name']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'price']), 0, 100),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'available_quantity']), 0, 100),
                    $current_user_id,
                    $created_at,
                    $created_at
                )
            );
            return ['id' => $wpdb->insert_id];
        }
        
        // if is update
        if(isset($post['id']) && (int)$post['id'] > 0) {
            $dt = new \DateTime();
            $updated_at = $dt->format('Y-m-d H:i:s');
            // Performing update, do not need cache here. Using $wpdb->query() with prepare() – the standard and safe approach for this operation.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE ".esc_sql($w->table_name)." 
                    SET name = %s, price = %s, available_quantity = %s, updated_at = %s 
                    WHERE id = %d LIMIT 1",
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'name']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'price']), 0, 100),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'available_quantity']), 0, 100),
                    $updated_at,
                    (int)$post['id']
                )
            );
            return ['id' => (int)$post['id']];
        }

        return false;
    }

    private static function validate($post)
    {
        if(!isset($post[Config::INPUTS_PREFIX.'name']) || trim($post[Config::INPUTS_PREFIX.'name']) === '') {
            self::set_validation_error(Config::INPUTS_PREFIX.'name', esc_html__('Please enter name', 'kirilkirkov-pdf-invoice-manager'));
        }

        if(isset($post[Config::INPUTS_PREFIX.'available_quantity']) 
         && trim($post[Config::INPUTS_PREFIX.'available_quantity']) !== '' && !is_numeric(trim($post[Config::INPUTS_PREFIX.'available_quantity']))) {
            self::set_validation_error(Config::INPUTS_PREFIX.'available_quantity', esc_html__('Available Quantity is not valid number', 'kirilkirkov-pdf-invoice-manager'));
        }

        return (bool)!count(self::get_validation_errors());
    }

    /**
     * Set error to validation errors
     */
    private static function set_validation_error($key, $err)
    {
        self::$validation_errors[$key] = $err;
    }

    /**
     * @param bool $remove_prefix - remove input prefixes. Mostly used trought Rest Api
     * 
     * @return array
     */
    public static function get_validation_errors($remove_prefix = false)
    {
        if($remove_prefix === true) {
            return array_map(function($key, $value) {
                return [str_replace(Config::INPUTS_PREFIX, '', $key) => $value];
            }, array_keys(self::$validation_errors), self::$validation_errors);
        }

        return self::$validation_errors;
    }
}