<?php

namespace NinjaTables\App\Models;

use NinjaTables\Framework\Foundation\App;
use NinjaTables\Framework\Support\Arr;

class Post extends Model
{
    private static $cptName = 'ninja-table';
    protected $table = 'posts';

    public static function getPosts($args)
    {
        $orderByes = ['ID', 'post_title'];
        $orderBy   = Arr::get($args, 'orderby', 'ID');
        $postStatus = Arr::get($args, 'post_status', 'publish');
        $orderBy   = in_array($orderBy, $orderByes) ? $orderBy : 'ID';

        $posts = Post::where('post_type', self::$cptName)
                     ->where('post_status', $postStatus)
                     ->where(function ($query) use ($args) {
                         if (isset($args['s'])) {
                             $query->where('post_title', 'like', '%' . $args['s'] . '%')
                                   ->orWhere('ID', 'like', '%' . $args['s'] . '%')
                                   ->orWhere('post_content', 'like', '%' . $args['s'] . '%');
                         }
                     });
        $total = $posts->count();
        $orderByType = Arr::get($args, 'order');
        $orderByType = in_array(strtoupper($orderByType), ['ASC', 'DESC']) ? $orderByType : 'DESC';

        $posts = $posts->orderBy($orderBy, $orderByType)
                       ->skip($args['offset'])
                       ->take($args['posts_per_page'])
                       ->get();

        return [
            'total' => $total,
            'data'  => $posts,
        ];
    }

    public static function getTables($perPage, $currentPage, $tables, $total = 0)
    {
        foreach ($tables as $table) {
            $provider = get_post_meta($table->ID, '_ninja_tables_data_provider', true);
            if ($provider === 'drag_and_drop') {
                $table->preview_url = site_url('?ninjatable_builder_preview=' . $table->ID);
            } else {
                $table->preview_url = site_url('?ninjatable_preview=' . $table->ID);
            }
            $dataSourceType        = ninja_table_get_data_provider($table->ID);
            $table->dataSourceType = $dataSourceType;
            if ($dataSourceType == 'fluent-form') {
                $fluentFormFormId = get_post_meta($table->ID, '_ninja_tables_data_provider_ff_form_id', true);
                if ($fluentFormFormId) {
                    $table->fluentfrom_url = admin_url(
                        'admin.php?page=fluent_forms&route=entries&form_id=' . $fluentFormFormId
                    );
                }
            } elseif ($dataSourceType == 'csv' || $dataSourceType == 'google-csv') {
                $table->remoteURL = get_post_meta($table->ID, '_ninja_tables_data_provider_url', true);
            }
        }

        $lastPage = ceil($total / $perPage);

        return [
            'total'        => intval($total),
            'per_page'     => $perPage,
            'current_page' => $currentPage,
            'last_page'    => ($lastPage) ? $lastPage : 1,
            'data'         => $tables,
        ];
    }

    public static function saveTable($attributes, $postId = null)
    {
        if ( ! $postId) {
            $postId = wp_insert_post($attributes);
        } else {
            $attributes['ID'] = $postId;
            wp_update_post($attributes);
        }
        update_post_meta($postId, '_last_edited_by', get_current_user_id());
        update_post_meta($postId, '_last_edited_time', gmdate('Y-m-d H:i:s'));

        return $postId;
    }

    public static function destroyTable($tableId)
    {
        wp_delete_post($tableId, true);

        NinjaTableItem::where('table_id', $tableId)->delete();
    }

    public static function makeDuplicate($oldPostId, $newPostId)
    {
        global $wpdb;
        $oldPostId = (int)$oldPostId;
        $newPostId = (int)$newPostId;

        // Duplicate table settings.
        $postMetas = get_post_meta($oldPostId);

        foreach ($postMetas as $metaKey => $metaValue) {
            update_post_meta($newPostId, $metaKey, maybe_unserialize($metaValue[0]));
        }

        // Duplicate table rows.
        $itemsTable = $wpdb->prefix . esc_sql(ninja_tables_db_table_name());

        $sql = "INSERT INTO $itemsTable (`position`, `table_id`, `owner_id`, `settings`, `attribute`, `value`, `created_at`, `updated_at`)";
        $sql .= " SELECT `position`, $newPostId, `owner_id`, `settings`, `attribute`, `value`, `created_at`, `updated_at` FROM $itemsTable";
        $sql .= " WHERE `table_id` = $oldPostId";

        $wpdb->query($sql); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
    }

    public static function updatedSettings($tableId, $rawColumns, $tablePreference)
    {
        $tableColumns             = array();
        $formattedTablePreference = array();
        $provider                 = ninja_table_get_data_provider($tableId);

        if (is_array($rawColumns) && empty($rawColumns) && ! $tablePreference) {
                update_post_meta($tableId, '_ninja_table_columns', $tableColumns);
                if ($provider === 'default') {
                    NinjaTableItem::where('table_id', $tableId)->delete();
                }
        } elseif (is_array($rawColumns) && ! empty($rawColumns)) {
            foreach ($rawColumns as $column) {
                foreach ($column as $column_index => $column_value) {
                    if ($provider === 'google-csv' && gettype($column_value) === 'string') {
                        $column_value = htmlspecialchars_decode($column_value);
                    }
                    if (is_int($column_value)) {
                        $column[$column_index] = intval($column_value);
                    } else {
                        $column[$column_index] = $column_value;
                    }
                }
                $tableColumns[] = $column;
            }
            $tableColumns = apply_filters(
                'ninja_table_update_columns_' . ninja_table_get_data_provider($tableId),
                $tableColumns,
                $rawColumns,
                $tableId
            );
            do_action(
                'ninja_table_before_update_columns_' . ninja_table_get_data_provider($tableId),
                $tableColumns,
                $rawColumns,
                $tableId
            );
            do_action('ninja_table_before_update_columns', $tableColumns, $rawColumns, $tableId);
            update_post_meta($tableId, '_ninja_table_columns', $tableColumns);
        }

        if ($tablePreference && is_array($tablePreference)) {
            $formattedTablePreference = ninjaTableNormalize($tablePreference);
            update_post_meta($tableId, '_ninja_table_settings', $formattedTablePreference);
        }

        ninjaTablesClearTableDataCache($tableId);

        update_post_meta($tableId, '_last_edited_by', get_current_user_id());
        update_post_meta($tableId, '_last_edited_time', gmdate('Y-m-d H:i:s'));

        return [
            'message'  => __('Successfully updated configuration.', 'ninja-tables'),
            'columns'  => $tableColumns,
            'settings' => $formattedTablePreference,
        ];
    }
}
