<?php

namespace EstatebudConnect\Controllers;

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

use EstatebudConnect\Plugin;
use EstatebudConnect\Configs\App;
use EstatebudConnect\Core\Strings;
use EstatebudConnect\Core\Cache;
use EstatebudConnect\Core\Log;
use EstatebudConnect\Models\Forms;
use EstatebudConnect\Models\Field;
use EstatebudConnect\Models\Settings;
use EstatebudConnect\Services\Captcha;
use EstatebudConnect\Traits\Singleton;
use EstatebudConnect\Utilities\Helper;
use EstatebudConnect\Models\SearchExperience;
use EstatebudConnect\Services\Estatebud;

class Form
{
    use Singleton;

    public function __construct()
    {
        add_action('wp_ajax_estatebud_submit_contact_form_data', [$this, 'submit_contact_form_data']);
        add_action('wp_ajax_nopriv_estatebud_submit_contact_form_data', [$this, 'submit_contact_form_data']);
        add_action('wp_ajax_estatebud_get_share_agent_modal', [$this, 'get_share_agent_modal']);
        add_action('wp_ajax_nopriv_estatebud_get_share_agent_modal', [$this, 'get_share_agent_modal']);
    }

    public function enqueue_assets()
    {
        $settings_data = Settings::instance()->get_data();
        $captcha_provider = $settings_data['captcha_provider'];
        $captcha_site_key = $settings_data['captcha_site_key'] ?? '';

        if (Plugin::has_build_tools()) {
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('app/Javascript/public/index.js'), [App::SLUG . '-choices', App::SLUG . '-intltel'], uniqid());
        } else {
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('dist/bundle-main.js'), [App::SLUG . '-choices', App::SLUG . '-intltel'], App::VERSION);
        }

        if (!empty($captcha_provider) && !empty($captcha_site_key)) {
            if ($captcha_provider === 'recaptcha') {
                wp_enqueue_script(
                    App::SLUG . '-recaptcha',
                    'https://recaptcha.net/recaptcha/api.js?render=' . esc_attr($captcha_site_key),
                    [],
                    null,
                );
            } elseif ($captcha_provider === 'hcaptcha') {
                wp_enqueue_script(SLUG . '-hcaptcha', 'https://js.hcaptcha.com/1/api.js', [], null);
            } elseif ($captcha_provider === 'turnstile') {
                wp_enqueue_script(
                    App::SLUG . '-turnstile',
                    'https://challenges.cloudflare.com/turnstile/v0/api.js',
                    [],
                    null,
                );
            }
        }

        Strings::init_defaults('frontend');
    }

    public function render_form($form_id, $context = [])
    {
        $settings_data = Settings::instance()->get_data();
        $form_data = Forms::instance()->get_form($form_id);

        if (!$form_data) {
            return '<div class="estatebud-form-not-found-message">Form "' . esc_html($form_id) . '" not found</div>';
        }

        $form_type = $form_data['type'] ?? '';

        if ($form_type === 'contact') {
            $field_options = Estatebud::instance()
                ->cache(Cache::TTL_1MO)
                ->get_fields(['component' => 'property']);

            $this->enqueue_assets();

            ob_start();
            Helper::render_markup_from_views('Public/Form/form.php', [
                'form_id' => $form_id,
                'settings_data' => $settings_data,
                'form_data' => $form_data,
                'field_options' => $field_options,
            ]);

            return ob_get_clean();
        }

        $this->enqueue_assets();

        $filter_vars = $this->get_filter_header_vars($form_id, $form_data, $context);

        ob_start();
        Helper::render_markup_from_views('Public/Form/filter-header.php', $filter_vars);
        $html = ob_get_clean();

        return '<div class="estatebud-form">'.$html.'</div>';
    }

    private function get_filter_header_vars($form_id, $form_data, $context)
    {
        $shortcode_id = $context['shortcode_id'] ?? uniqid();
        $search_id = $context['search_id'] ?? '';
        $listing_type = ($form_data['type'] ?? '') === 'project-search' ? 'project' : 'property';

        return [
            'form_id' => $form_id,
            'form_data' => $form_data,
            'shortcode_id' => $shortcode_id,
            'search_id' => $search_id,
            'query_from_link' => $context['query_from_link'] ?? [],
            'settings_data' => Settings::instance()->get_data(),
            'field_options' => Estatebud::instance()->cache(Cache::TTL_1MO)->get_fields(['component' => $listing_type]),
            'location_options' => Estatebud::instance()->cache(Cache::TTL_5M)->get_property_areas(),
            'search_exp_data' => !empty($search_id) ? SearchExperience::instance()->get_search_exp($search_id) : null,
        ];
    }

    public function submit_contact_form_data()
    {
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'estatebud-nonce')) {
            wp_send_json_error(
                [
                    'message' => 'Nonce verification failed',
                    'code' => 403,
                ],
                403,
            );
        }

        Log::write('Form: Processing submission', $_POST);

        $form_id = sanitize_text_field(wp_unslash($_POST['form_id'] ?? ''));
        $form_data = Forms::instance()->get_form($form_id);

        Log::write('Form: Configuration', $form_data);

        if (!$form_data) {
            wp_send_json_error(
                [
                    'message' => sprintf('Form with "%s" not found', $form_id),
                    'code' => 404,
                ],
                404,
            );
        }

        $email_to = $form_data['email_to'];
        $email_subject = $form_data['email_subject'];
        $email_message = $form_data['email_message'];
        $email_from = $form_data['email_from'];
        $email_from_name = $form_data['email_from_name'];
        $email_reply_to = $form_data['email_reply_to'];
        $email_cc = $form_data['email_cc'];
        $email_bcc = $form_data['email_bcc'];
        $email_meta_data = $form_data['email_meta_data'];

        $confirmation_email_subject = $form_data['confirmation_email_subject'];
        $confirmation_email_message = $form_data['confirmation_email_message'];
        $confirmation_email_from = $form_data['confirmation_email_from'];
        $confirmation_email_from_name = $form_data['confirmation_email_from_name'];
        $confirmation_email_reply_to = $form_data['confirmation_email_reply_to'];
        $confirmation_email_cc = $form_data['confirmation_email_cc'];
        $confirmation_email_bcc = $form_data['confirmation_email_bcc'];

        $fields = $form_data['fields'];
        $field_values = [];
        $field_validation = [];

        foreach ($fields as $field) {
            $field_obj = new Field($field);
            $name = $field_obj->get_name();
            $options = $field_obj->get_options();
            $raw_value = wp_unslash($_POST[$name] ?? '');

            $validation_result = $field_obj->validate_value($raw_value);
            if ($validation_result !== true) {
                $field_validation[$name] = $validation_result;
            }

            if ($field_obj->is_type('phone') && isset($_POST[$field_obj->get_name() . '_dial_code'])) {
                $raw_value = '+' . $_POST[$field_obj->get_name() . '_dial_code'] . ' ' . $raw_value;
            }

            if (count($options)) {
                $raw_value_array = explode('|', $raw_value);
                $selected_options = [];

                foreach ($options as $option) {
                    if (in_array($option['value'], $raw_value_array)) {
                        $selected_options[] = $option['label'];
                    }
                }
                
                $raw_value = $selected_options;
            }

            $value = $field_obj->sanitize_value($raw_value);

            if ($value) {
                if ($field_obj->is_type('email')) {
                    $submitter_email = $value;
                }

                $label = $field_obj->get_display_name();

                $field_values[$name] = [
                    'id' => $field_obj->get_id(),
                    'name' => $name,
                    'value' => is_array($value) ? implode(', ', $value) : $value,
                    'label' => $label,
                ];
            }
        }

        if (count($field_validation)) {
            Log::write('Form: Validation failed', $field_validation);

            wp_send_json_error(
                [
                    'message' => 'Form validation failed',
                    'code' => 400,
                    'data' => $field_validation,
                ],
                400,
            );
        }

        $captcha_result = Captcha::instance()->post_captcha_response();

        Log::write('Form: Captcha', $captcha_result);

        if ($captcha_result['success'] === false) {
            wp_send_json_error(
                [
                    'message' => 'Captcha verification failed',
                    'code' => 400,
                    'data' => 'captcha',
                ],
                400,
            );
        }

        $fields_placeholder = '{{ form.fields }}';

        if (empty($email_message)) {
            $email_message = $fields_placeholder;
        }

        if (str_contains($email_message, $fields_placeholder)) {
            $all_fields = [];

            foreach ($field_values as $field) {
                $all_fields[] = '<strong>' . esc_html($field['label']) . ':</strong> ' . esc_html($field['value']);
            }

            $all_fields = implode("\r\n", $all_fields);

            $email_message = str_replace($fields_placeholder, $all_fields, $email_message);
            $confirmation_email_message = str_replace($fields_placeholder, $all_fields, $confirmation_email_message);
        }

        foreach ($field_values as $field) {
            $field_placeholder = sprintf('{{ field.%s }}', $field['id']);
            $field_value = esc_html($field['value']);

            $email_subject = str_replace($field_placeholder, $field_value, $email_subject);
            $email_message = str_replace($field_placeholder, $field_value, $email_message);
            $confirmation_email_subject = str_replace($field_placeholder, $field_value, $confirmation_email_subject);
            $confirmation_email_message = str_replace($field_placeholder, $field_value, $confirmation_email_message);
        }

        $meta_data_values = [];

        foreach ($email_meta_data as $meta_data) {
            if ($meta_data === 'date') {
                $datetime = gmdate('j F Y');
                $meta_data_values[] = '<strong>Date:</strong> ' . $datetime;
            }
            if ($meta_data === 'time') {
                $time = gmdate('H:i');
                $meta_data_values[] = '<strong>Time:</strong> ' . $time;
            }
            if ($meta_data === 'ip') {
                $user_ip = Helper::get_user_ip();
                $meta_data_values[] = '<strong>IP:</strong> ' . esc_html($user_ip);
            }
            if ($meta_data === 'browser') {
                $meta_data_values[] = '<strong>Browser:</strong> ' . esc_html(sanitize_text_field(wp_unslash($_POST['browser_info'] ?? 'Unknown')));
            }
            if ($meta_data === 'page_url') {
                $meta_data_values[] = '<strong>Page URL:</strong> ' . esc_html(sanitize_text_field(wp_unslash($_POST['page_url'] ?? 'Unknown')));
            }
        }

        if (count($meta_data_values)) {
            $meta_data_values = implode("\r\n", $meta_data_values);
            $email_message .= "\r\n\r\n<strong>Meta data</strong>\r\n" . $meta_data_values;
        }

        $email_headers = ['Content-Type: text/html; charset=UTF-8', "From: $email_from_name <$email_from>"];

        if (!empty($email_reply_to)) {
            $email_headers[] = "Reply-To: $email_reply_to";
        }

        $email_cc_recipients = Helper::email_addresses_to_array($email_cc);
        foreach ($email_cc_recipients as $email_cc_recipient) {
            $email_headers[] = "CC: $email_cc_recipient";
        }

        $email_bcc_recipients = Helper::email_addresses_to_array($email_bcc);
        foreach ($email_bcc_recipients as $email_bcc_recipient) {
            $email_headers[] = "BCC: $email_bcc_recipient";
        }

        $confirmation_email_headers = [
            'Content-Type: text/html; charset=UTF-8',
            "From: $confirmation_email_from_name <$confirmation_email_from>",
        ];

        if (!empty($confirmation_email_reply_to)) {
            $confirmation_email_headers[] = "Reply-To: $confirmation_email_reply_to";
        }

        $confirmation_email_cc_recipients = Helper::email_addresses_to_array($confirmation_email_cc);
        foreach ($confirmation_email_cc_recipients as $confirmation_email_cc_recipient) {
            $confirmation_email_headers[] = "CC: $confirmation_email_cc_recipient";
        }

        $confirmation_email_bcc_recipients = Helper::email_addresses_to_array($confirmation_email_bcc);
        foreach ($confirmation_email_bcc_recipients as $confirmation_email_bcc_recipient) {
            $confirmation_email_headers[] = "BCC: $confirmation_email_bcc_recipient";
        }

        $result_admin_mail = false;
        $result_user_mail = false;

        $email_to_recipients = Helper::email_addresses_to_array($email_to);

        if (count($email_to_recipients) == 0) {
            $admin_users = get_users('role=Administrator');
            foreach ($admin_users as $admin_user) {
                $email_to_recipients[] = $admin_user->user_email;
            }
        }

        if (count($email_to_recipients) > 0) {
            $result_admin_mail = wp_mail($email_to_recipients, $email_subject, nl2br($email_message), $email_headers);
        }

        if (isset($submitter_email)) {
            $result_user_mail = wp_mail(
                $submitter_email,
                $confirmation_email_subject,
                nl2br($confirmation_email_message),
                $confirmation_email_headers,
            );
        }

        if ($result_admin_mail) {
            Log::write('Form: Successfully submitted', [
                'to' => $email_to,
                'result' => $result_admin_mail,
                'form_data' => $form_data,
            ]);

            wp_send_json_success(
                [
                    'message' => 'Form submission successful',
                    'code' => 200,
                    'data' => 'success',
                ],
                200,
            );
        } else {
            Log::write('Form: Submission failed', [
                'to' => $email_to,
                'result' => $result_admin_mail,
                'form_data' => $form_data,
            ]);

            wp_send_json_error(
                [
                    'message' => 'Form submission failed',
                    'code' => 500,
                    'data' => 'submit',
                ],
                500,
            );
        }
    }

    public function get_share_agent_modal()
    {
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'estatebud-nonce')) {
            wp_send_json_error(
                [
                    'message' => 'Nonce verification failed',
                    'code' => 403,
                ],
                403,
            );
        }

        $form_id = sanitize_text_field(wp_unslash($_POST['form_id'] ?? ''));
        $form_data = Forms::instance()->get_form($form_id);

        if (!$form_data) {
            wp_send_json_error(
                [
                    'message' => 'Form "' . esc_html($form_id) . '" not found',
                    'code' => 404
                ],
                404,
            );
        }

        $settings_data = Settings::instance()->get_data();
        $field_options = Estatebud::instance()
            ->cache(Cache::TTL_1MO)
            ->get_fields(['component' => 'property']);
        
        ob_start();

        Helper::render_markup_from_views('Public/Form/form-modal.php', [
            'form_id' => $form_id,
            'settings_data' => $settings_data,
            'form_data' => $form_data,
            'field_options' => $field_options,
        ]);

        $rendered_html = ob_get_clean();

        wp_send_json_success(
            [
                'message' => 'Fetched share agent modal',
                'code' => 200,
                'data' => $rendered_html,
            ],
            200,
        );
    }
}
