<?php

namespace KirilKirkov\WpInvoices;

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

/**
 * Create clients
 * Validation and CRUD
 */
class CreateClient
{
    private static $validation_errors = [];

    /**
     * Create clients page
     */
    public function create_client_page()
    {
        $success = null;
        $client = [];

        // if submit form
        if ( 
            isset( $_SERVER['REQUEST_METHOD'] ) && 
            $_SERVER['REQUEST_METHOD'] === 'POST'
            && isset( $_POST['kkwi_create_client_nonce'] )
            && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['kkwi_create_client_nonce'] ) ), 'kkwi_create_client_action' )
        ) {
            $_client = self::create_client($_POST);
            if($_client === false) {
                $errors = self::get_validation_errors();
                $success = false;
                $client = array_map('sanitize_text_field', wp_unslash($_POST));
            } else {
                $success = true;
            }
        }

        // if edit
        if(isset($_GET['edit'])) {
            $_client = Clients::get_client(sanitize_text_field(wp_unslash($_GET['edit'])), true);
            if($_client === false) {
                require plugin_dir_path( __FILE__ ) . '../../Views/404.php';                
                return;
            }
            if(!count($client)) {
                $client = $_client;
            }
        }

        $Config = Config::class;

        require plugin_dir_path( __FILE__ ) . '../../Views/Clients/CreateClient.php';
    }

    /**
     * @return bool
     */
    public static function create_client($post)
    {
        if(
            !isset( $_POST['kkwi_create_client_nonce'] )
            || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['kkwi_create_client_nonce'] ) ), 'kkwi_create_client_action' )
        ) {
            return false;
        }

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

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

        $w = new Clients(false);
        $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');

            // No need cache for insert. Direct insert query with prepare.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->query( 
                $wpdb->prepare(
                    "INSERT INTO ".esc_sql($w->table_name)." 
                    ( client, is_individual, identification_number, has_vat_registration, 
                    vat_number, accountable_person, city, address, country, beneficiary, zip_code,
                    created_from, created_at, updated_at )
                    VALUES ( %s, %d, %s, %d, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s )",
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'client']), 0, 255),
                    (int)$post[Config::INPUTS_PREFIX.'is_individual'],
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'identification_number']), 0, 255),
                    (int)$post[Config::INPUTS_PREFIX.'has_vat_registration'],
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'vat_number']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'accountable_person']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'city']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'address']), 0, 300),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'country']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'beneficiary']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'zip_code']), 0, 200),
                    $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');

            // No need cache for update. Direct safe query with prepare.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE ".esc_sql($w->table_name)." 
                    SET client = %s, is_individual = %d, identification_number = %s, has_vat_registration = %d, vat_number = %s, accountable_person = %s, 
                    city = %s, address = %s, country = %s, beneficiary = %s, zip_code = %s, updated_at = %s 
                    WHERE id = %d LIMIT 1",
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'client']), 0, 255),
                    (int)$post[Config::INPUTS_PREFIX.'is_individual'],
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'identification_number']), 0, 255),
                    (int)$post[Config::INPUTS_PREFIX.'has_vat_registration'],
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'vat_number']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'accountable_person']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'city']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'address']), 0, 300),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'country']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'beneficiary']), 0, 255),
                    mb_substr(trim($post[Config::INPUTS_PREFIX.'zip_code']), 0, 200),
                    $updated_at,
                    (int)$post['id']
                )
            );
            return ['id' => (int)$post['id']];
        }

        return false;
    }

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

        if(isset($post[Config::INPUTS_PREFIX.'is_individual']) && (int)$post[Config::INPUTS_PREFIX.'is_individual'] === 1) {
            if(!isset($post[Config::INPUTS_PREFIX.'identification_number']) || trim($post[Config::INPUTS_PREFIX.'identification_number']) === '') {
                self::set_validation_error(Config::INPUTS_PREFIX.'identification_number', esc_html__('Please enter identification 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;
    }
}