<?php

namespace EstatebudConnect\Models;

if (!defined('WPINC')) {
    die();
}

use EstatebudConnect\Configs\Defaults;
use EstatebudConnect\Core\OptionsAPI;
use EstatebudConnect\Utilities\Helper;
use EstatebudConnect\Traits\Singleton;

class SearchExperience
{
    private const OPTIONS_KEY = 'search_experiences';

    use Singleton;

    public function __construct() {}

    public function get_all_search_exps()
    {
        $data = OptionsAPI::instance()->get(self::OPTIONS_KEY, []);
        return $data ?? [];
    }

    public function get_search_exp($id)
    {
        $search_exps = $this->get_all_search_exps();
        foreach ($search_exps as $search_exp) {
            if ($search_exp['id'] === $id) {
                return array_merge(Defaults::SEARCH_EXPERIENCE, $search_exp);
            }
        }

        return null;
    }

    public function add_search_exp($search_exp_data)
    {
        $parsed_data = $this->parse_input_data($search_exp_data);

        $search_exps = $this->get_all_search_exps();
        $id = Helper::get_random_string();
        $parsed_data['id'] = $id;
        foreach ($search_exps as $search_exp) {
            if (isset($parsed_data['id']) && $search_exp['id'] === $parsed_data['id']) {
                return false;
            }
        }
        $search_exps[] = $parsed_data;
        return OptionsAPI::instance()->update(self::OPTIONS_KEY, $search_exps, true);
    }

    public function update_search_exp($id, $new_data)
    {
        $parsed_data = $this->parse_input_data($new_data);

        $search_exps = $this->get_all_search_exps();
        foreach ($search_exps as &$search_exp) {
            if ($search_exp['id'] === $id) {
                $search_exp = $parsed_data;
                OptionsAPI::instance()->update(self::OPTIONS_KEY, $search_exps, true);
                return true;
            }
        }

        return false;
    }

    public function delete_search_exp($ids)
    {
        if (!is_array($ids) || empty($ids)) {
            return false;
        }

        $search_exps = $this->get_all_search_exps();

        $new_search_exps = array_values(
            array_filter($search_exps, function ($search_exp) use ($ids) {
                return !in_array($search_exp['id'], $ids);
            }),
        );

        $result = OptionsAPI::instance()->update(self::OPTIONS_KEY, array_values($new_search_exps), true);
        return $result;
    }

    public function clone_search_exp($id)
    {
        $search_exps = $this->get_all_search_exps();
        $search_exp_to_clone = null;

        foreach ($search_exps as $search_exp) {
            if ($search_exp['id'] === $id) {
                $search_exp_to_clone = $search_exp;
                break;
            }
        }

        if (!$search_exp_to_clone) {
            return false;
        }

        $cloned_search_exp = $search_exp_to_clone;
        $cloned_search_exp['id'] = Helper::get_random_string();
        $cloned_search_exp['name'] = $search_exp_to_clone['name'] . ' (Copy)';

        $search_exps[] = $cloned_search_exp;

        $result = OptionsAPI::instance()->update(self::OPTIONS_KEY, $search_exps, true);
        return $result ? $search_exps : false;
    }

    protected function parse_input_data($form_data)
    {
        $defaults = Defaults::SEARCH_EXPERIENCE;
        $parsed_form_data = [];

        foreach ($form_data as $index_1 => $data_1) {
            $index_1 = sanitize_text_field(wp_unslash($index_1));
            $data_1 = wp_unslash($data_1);

            if (!isset($defaults[$index_1])) {
                continue;
            }

            if (is_array($data_1)) {
                $textareas = [];
                $booleans = [];

                if (!isset($parsed_form_data[$index_1])) {
                    $parsed_form_data[$index_1] = [];
                }

                foreach ($data_1 as $index_2 => $data_2) {
                    $index_2 = sanitize_text_field(wp_unslash($index_2));
                    $data_2 = wp_unslash($data_2);

                    if (is_array($data_2)) {
                        $textareas = [];
                        $booleans = [];

                        if (!isset($parsed_form_data[$index_1][$index_2])) {
                            $parsed_form_data[$index_1][$index_2] = [];
                        }

                        foreach ($data_2 as $index_3 => $data_3) {
                            $index_3 = sanitize_text_field(wp_unslash($index_3));
                            $data_3 = wp_unslash($data_3);
                            
                            if (is_array($data_3)) {
                                $value = array_map('sanitize_text_field', $data_3);
                                $value = array_filter($value, fn($v) => $v !== '');
                                $value = empty($value) ? null : array_values($value);
                            } else if (in_array($index_3, $booleans)) {
                                $value = filter_var($data_3, FILTER_VALIDATE_BOOLEAN);
                            } else if (in_array($index_3, $textareas)) {
                                $value = sanitize_textarea_field($data_3);
                            } else {
                                $value = sanitize_text_field($data_3);
                            }

                            $parsed_form_data[$index_1][$index_2][$index_3] = $value;
                        }
                        
                        if ($index_1 === 'fields' && empty($parsed_form_data[$index_1][$index_2]['name'])) {
                            $parsed_form_data[$index_1][$index_2]['name'] = Helper::generate_field_name($parsed_form_data[$index_1][$index_2]);
                        }
                    } else {
                        if (in_array($index_2, $booleans)) {
                            $value = filter_var($data_2, FILTER_VALIDATE_BOOLEAN);
                        } else if (in_array($index_2, $textareas)) {
                            $value = sanitize_textarea_field($data_2);
                        } else {
                            $value = sanitize_text_field($data_2);
                        }

                        $parsed_form_data[$index_1][$index_2] = $value;
                    }
                }
            } else {
                $textareas = [];
                $booleans = [];

                if (in_array($index_1, $booleans)) {
                    $value = filter_var($data_1, FILTER_VALIDATE_BOOLEAN);
                } else if (in_array($index_1, $textareas)) {
                    $value = sanitize_textarea_field($data_1);
                } else {
                    $value = sanitize_text_field($data_1);
                }

                $parsed_form_data[$index_1] = $value;
            }
        }
        
        return $parsed_form_data;
    }
}
