<?php

namespace EstatebudConnect\Controllers;

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

use EstatebudConnect\Plugin;
use EstatebudConnect\Configs\App;
use EstatebudConnect\Utilities\Helper;
use EstatebudConnect\Traits\Singleton;
use EstatebudConnect\Controllers\Form;
use EstatebudConnect\Models\Settings;
use EstatebudConnect\Models\Property;
use EstatebudConnect\Models\Project;
use EstatebudConnect\Services\Estatebud;
use EstatebudConnect\Core\Strings;
use EstatebudConnect\Core\Cache;
use EstatebudConnect\Core\Locale;

class Listing
{
    use Singleton;

    public function __construct()
    {
        add_action('wp_ajax_estatebud_get_similar_properties', [$this, 'get_similar_properties']);
        add_action('wp_ajax_nopriv_estatebud_get_similar_properties', [$this, 'get_similar_properties']);
        add_action('wp_ajax_estatebud_get_pdf_template', [$this, 'get_pdf_template']);
        add_action('wp_ajax_nopriv_estatebud_get_pdf_template', [$this, 'get_pdf_template']);
    }

    public function render_listing($listing_id, $listing_type, $listing_slug)
    {
        if (empty($listing_id) || empty($listing_type)) {
            return;
        }

        try {
            if ($listing_type === 'project') {
                $listing_raw = Estatebud::instance()->get_project($listing_id);
                $listing = new Project($listing_raw);
            } else {
                $listing_raw = Estatebud::instance()->get_property($listing_id);
                $listing = new Property($listing_raw);
            }

            if (!$listing->is_published() || !empty($listing_slug) && $listing->get_slug() !== $listing_slug) {
                status_header(404);
                return Helper::render_markup_from_views('Public/Listing/404.php');
            }

            $settings_data = Settings::instance()->get_data();
            $listing_settings = $listing->get_settings();

            $whois = Estatebud::instance()->cache(Cache::TTL_1H)->whois();

            $this->enqueue_assets($listing);

            Helper::render_markup_from_views('Public/Listing/listing.php', [
                'listing' => $listing,
                'listing_type' => $listing_type,
                'settings_data' => $settings_data,
                'listing_settings' => $listing_settings,
                'whois' => $whois,
            ]);
        } catch (\Exception $e) {
            status_header(404);
            Helper::render_markup_from_views('Public/Listing/404.php');
        }
    }

    function enqueue_assets($listing)
    {
        wp_enqueue_style(App::SLUG . '-maps', Helper::get_url('dist/bundle-maps.css'), [], App::VERSION);

        if (Plugin::has_build_tools()) {
            wp_enqueue_script(App::SLUG . '-maps', Helper::get_url('app/Javascript/maps/index.js'), [App::SLUG . '-intltel'], uniqid());
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('app/Javascript/public/listing/index.js'), [App::SLUG . '-choices', App::SLUG . '-intltel'], uniqid());
        } else {
            wp_enqueue_script(App::SLUG . '-maps', Helper::get_url('dist/bundle-maps.js'), [App::SLUG . '-intltel'], App::VERSION);
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('dist/bundle-listing.js'), [App::SLUG . '-choices', App::SLUG . '-maps', App::SLUG . '-intltel'], App::VERSION);
        }
        
        foreach (App::SEO_TITLE_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_page_title']);
        }

        foreach (App::SEO_DESCRIPTION_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_meta_description']);
        }

        foreach (App::SEO_OG_IMAGE_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_og_image']);
        }

        foreach (App::SEO_OG_TITLE_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_og_title']);
        }

        foreach (App::SEO_OG_URL_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_og_url']);
        }

        foreach (App::OG_DESCRIPTION_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_og_description']);
        }

        add_filter('aioseo_facebook_tags', function() use ($listing) {
            return [
                'og:title' => $listing->get_og_title(),
                'og:description' => $listing->get_og_description(),
                'og:url' => $listing->get_og_url(),
                'og:image' => Helper::image_optimizer($listing->get_og_image(), ['w' => 1200, 'h' => 630, 'f' => 'cover']),
            ];
        });

        add_filter('aioseo_twitter_tags', function() use ($listing) {
            return [
                'twitter:title' => $listing->get_og_title(),
                'twitter:description' => $listing->get_og_description(),
                'twitter:url' => $listing->get_og_url(),
                'twitter:image' => Helper::image_optimizer($listing->get_og_image(), ['w' => 1200, 'h' => 675, 'f' => 'cover']),
            ];
        });

        foreach (App::SEO_CANONICAL_FILTERS as $filter) {
            add_filter($filter, [$listing, 'get_url']);
        }

        add_action(
            'wp_head',
            function () use ($listing) {
                return Helper::render_markup_from_views('Public/Listing/components/seo-tags.php', [
                    'listing' => $listing,
                ]);
            },
            1,
        );

        $languages = Locale::instance()->get_enabled_languages();

        foreach ($languages as &$language) {
            $language['url'] = $listing->get_url($language['code']);
        }

        add_filter('weglot_button_html', function($html) use ($listing, $languages) {
            return Locale::instance()->set_urls($languages, $html);
        }, 10, 1);

        add_filter('weglot_href_lang', function($html) use ($listing, $languages) {
            return Locale::instance()->set_urls($languages, $html);
        });

        add_filter('pll_translation_url', function($url, $slug) use ($languages) {
            return Locale::instance()->set_urls($languages, $slug);
        }, 10, 2);

        add_filter('icl_ls_languages', function($wpml_languages) use ($listing, $languages) {
            return Locale::instance()->set_urls($languages, $wpml_languages);
        });

        add_filter('trp_get_url_for_language', function($url, $abs_home, $language) use ($listing) {
            return $listing->get_url($language);
        }, 10, 3);

        $settings_data = Settings::instance()->get_data();
        $map_provider = $settings_data['map_provider'];
        $map_api_key = $settings_data['map_access_token'];
        $mapbox_style = $settings_data['mapbox_style'];

        $listing_settings = $listing->get_settings();

        if (!empty($listing_settings['contact_form'])) {
            Form::instance()->enqueue_assets();
        }

        $map_zoom_limit_level = !empty($listing_settings['map_zoom_limit'])
            ? $listing_settings['map_zoom_limit']
            : '10';
        $map_default_zoom_level = !empty($listing_settings['map_default_zoom'])
            ? $listing_settings['map_default_zoom']
            : '6';
        $map_zoom_limit = App::NORMALIZED_MAP_ZOOM[$map_zoom_limit_level][$map_provider];
        $map_default_zoom = App::NORMALIZED_MAP_ZOOM[$map_default_zoom_level][$map_provider];

        $images = $listing->get_images();
        $floorplans = $listing->get_floorplans();
        $videos = $listing->get_videos();
        $virtual_tours = $listing->get_virtual_tours();
        $gallery = [];

        foreach ($images as $image) {
            $gallery[] = [
                'asset' => 'image',
                'type' => 'image',
                'url' => $image['url'],
                'thumb' => Helper::image_optimizer($image['url'], ['w' => 138, 'h' => 82, 'f' => 'cover']),
            ];
        }

        foreach ($floorplans as $floorplan) {
            $gallery[] = [
                'asset' => 'floorplan',
                'type' => 'image',
                'url' => $floorplan['url'],
                'thumb' => Helper::image_optimizer($floorplan['url'], ['w' => 138, 'h' => 82, 'f' => 'cover']),
            ];
        }

        foreach ($videos as $video) {
            $gallery[] = [
                'asset' => 'video',
                'type' => 'video',
                'url' => $video['url'],
                'thumb' => Helper::image_optimizer($video['thumbnail'], ['w' => 138, 'h' => 82, 'f' => 'cover']),
            ];
        }

        foreach ($virtual_tours as $virtual_tour) {
            $gallery[] = [
                'asset' => 'virtual_tour',
                'type' => 'external',
                'url' => $virtual_tour['url'],
                'thumb' => Helper::image_optimizer($virtual_tour['thumbnail'], ['w' => 138, 'h' => 82, 'f' => 'cover']),
            ];
        }

        Strings::init_defaults();
        Strings::append('gallery', $gallery);
        Strings::append('map_info', [
            'map_provider' => $map_provider,
            'map_api_key' => $map_api_key,
            'mapbox_style' => $mapbox_style,
            'map_zoom_limit' => $map_zoom_limit,
            'map_default_zoom' => $map_default_zoom,
            'coordinates' => $listing->get_coordinates(),
            'location_accuracy' => $listing->location_accuracy,
        ]);
        Strings::complete('frontend');
    }

    public function get_similar_properties()
    {
        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,
            );
        }

        $property_id = sanitize_text_field(wp_unslash($_POST['listing_id'] ?? ''));

        $_similar_properties = Estatebud::instance()
            ->cache(Cache::TTL_5M)
            ->get_similar_properties($property_id, [
                'radius' => 10,
                'max_reduction' => 30,
                'max_increase' => 30,
                'limit' => 3
            ]);
        $similar_properties = isset($_similar_properties['results'])
            ? $_similar_properties['results']
            : [];

        if (count($similar_properties) == 0) {
            wp_send_json_error(
                [
                    'message' => 'No similar properties found',
                    'code' => 204,
                ],
                204,
            );
        }

        $settings_data = Settings::instance()->get_data();

        ob_start();

        foreach ($similar_properties as $similar_property) {
            $listing = new Property($similar_property);
            Helper::render_markup_from_views('Public/Listings/components/listing-card.php', [
                'listing' => $listing,
                'settings_data' => $settings_data,
            ]);
        }

        $html = ob_get_clean();

        wp_send_json_success(
            [
                'message' => 'Fetched similar properties',
                'code' => 200,
                'html' => $html,
            ],
            200,
        );
    }

    public function get_pdf_template()
    {
        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,
            );
        }

        $listing_id = sanitize_text_field(wp_unslash($_POST['listing_id'] ?? ''));
        $listing_type = sanitize_text_field(wp_unslash($_POST['listing_type'] ?? ''));

        try {
            if ($listing_type === 'project') {
                $listings = Estatebud::instance()->get_projects(['id' => $listing_id]);
                $listing = new Project($listings['results'][$listing_id] ?? null);
            } else {
                $listings = Estatebud::instance()->get_properties(['id' => $listing_id]);
                $listing = new Property($listings['results'][$listing_id] ?? null);
            }

            if (!$listing->is_published()) {
                wp_send_json_error(
                    [
                        'message' => 'Listing is not published',
                        'code' => 404,
                    ],
                    404,
                );
            }

            $listing_setting = $listing->get_settings();
            $template_id = $listing_setting['brochure_template_id'];
            $branding_free = $listing_setting['brochure_white_label'];
            $agent_details = $listing_setting['brochure_show_agent'];

            $result = Estatebud::instance()->get_property_pdf([
                'id' => $listing->get_id(),
                'template_id' => $template_id,
                'branding_free' => $branding_free,
                'agent_details' => $agent_details,
            ]);

            if (isset($result['file']) && isset($result['size'])) {
                wp_send_json_success(
                    [
                        'message' => 'PDF data received',
                        'code' => 200,
                        'data' => [
                            'file' => $result['file'],
                            'size' => $result['size']
                        ]
                    ],
                    200,
                );
            } else {
                wp_send_json_error(
                    [
                        'message' => 'PDF data not received',
                        'code' => 400,
                    ],
                    400,
                );
            }
        } catch (\Exception $e) {
            wp_send_json_error(
                [
                    'message' => 'Listing not found',
                    'code' => 404,
                ],
                404,
            );
        }
    }
}