<?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;

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 = get_query_var('estatebud_listing_id');
        $listing_type = get_query_var('estatebud_listing_type');

        if (empty($listing_id) || empty($listing_type)) {
            return;
        }

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

            if (!$listing->is_published()) {
                status_header(404);
                return Helper::render_markup_from_views('Public/templates/404.php');
            }

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

            $is_similar_listing_enable = (int) ($listing_settings['similar_properties'] ?? 0);

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

            $this->enqueue_assets($listing);

            Helper::render_markup_from_views('Public/templates/listing.php', [
                'listing' => $listing,
                'listing_type' => $listing_type,
                'settings_data' => $settings_data,
                'listing_settings' => $listing_settings,
                'is_similar_listing_enable' => $is_similar_listing_enable,
                'whois' => $whois,
            ]);
        } catch (\Exception $e) {
            status_header(404);
            Helper::render_markup_from_views('Public/templates/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 . '-choices', App::SLUG . '-intltel'], uniqid());
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('app/Javascript/public/pages/listing.js'), [App::SLUG . '-choices', App::SLUG . '-intltel'], uniqid());
        } else {
            wp_enqueue_script(App::SLUG . '-maps', Helper::get_url('dist/bundle-maps.js'), [App::SLUG . '-choices', App::SLUG . '-intltel'], App::VERSION);
            wp_enqueue_script(App::SLUG . '-frontend', Helper::get_url('dist/bundle-listing.js'), [App::SLUG . '-maps', App::SLUG . '-choices', 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', [$listing, 'get_aioseo_facebook_tags']);
        add_filter('aioseo_twitter_tags', [$listing, 'get_aioseo_twitter_tags']);

        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/partials/components/listing-seo-tags.php', [
                    'listing' => $listing,
                ]);
            },
            1,
        );

        add_filter('icl_ls_languages', [$listing, 'get_alternate_urls']);

        $user_session = Helper::get_user_session();
        $favorites = $user_session['favorites'] ?? [];

        $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();
        $gallery_images = [];

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

        Strings::init_defaults();
        Strings::append('gallery_images', $gallery_images);
        Strings::append('favorites', $favorites);
        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,
            'latLng' => $listing->get_lat_lng(),
            '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['propertyId'] ?? ''));

        $_similar_properties = Estatebud::instance()
            ->cache(Cache::TTL_5M)
            ->get_similar_properties($property_id, ['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/partials/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['propertyId'] ?? ''));

        try {
            $listing_data = Estatebud::instance()->get_property($listing_id);
            $listing = new Property($listing_data);
            
            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,
            );
        }
    }
}