<?php
namespace Softech_Addons_for_Elementor\Includes\Dynamic_Tags\Tags\Post_Tags;

use Elementor\Controls_Manager;
use Elementor\Core\DynamicTags\Tag;
use Elementor\Modules\DynamicTags\Module;
use Softech_Addons_for_Elementor\Includes\Dynamic_Tags\Groups\Softech_Post_Group;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Softech_Acf_Post_Object_Url extends Tag {

    public function get_name() {
        return 'softech-acf-post-object-url';
    }

    public function get_title() {
        return esc_html__( 'ACF URL Field', 'softech-addons-for-elementor' );
    }

    public function get_group() {
        return Softech_Post_Group::get_name();
    }

    public function get_categories() {
        return [ Module::URL_CATEGORY ];
    }

    public function get_panel_template_setting_key() {
        return 'key';
    }

    public function get_supported_fields() {
        return [
            'text',
            'email',
            'image',
            'file',
            'page_link',
            'post_object',
            'relationship',
            'taxonomy',
            'url',
        ];
    }

    protected function register_controls() {
        $this->add_control(
            'key',
            [
                'label'   => esc_html__( 'Key', 'softech-addons-for-elementor' ),
                'type'    => Controls_Manager::SELECT,
                'groups'  => $this->get_control_options(),
            ]
        );

        $this->add_control(
            'fallback',
            [
                'label' => esc_html__( 'Fallback', 'softech-addons-for-elementor' ),
                'type'  => Controls_Manager::TEXT,
            ]
        );
    }

    public function render() {
        echo esc_url( $this->get_value() );
    }

    public function get_value( array $options = [] ) {
        list( $field, $meta_key ) = $this->get_tag_value_field();

        if ( $field ) {
            $value = $field['value'];

            if ( is_array( $value ) && isset( $value[0] ) ) {
                $value = $value[0];
            }

            if ( $value ) {
                if ( ! isset( $field['return_format'] ) ) {
                    $field['return_format'] = isset( $field['save_format'] ) ? $field['save_format'] : '';
                }

                switch ( $field['type'] ) {
                    case 'email':
                        $value = 'mailto:' . $value;
                        break;

                    case 'image':
                    case 'file':
                        switch ( $field['return_format'] ) {
                            case 'array':
                            case 'object':
                                $value = $value['url'];
                                break;
                            case 'id':
                                if ( 'image' === $field['type'] ) {
                                    $src   = wp_get_attachment_image_src( $value, 'full' );
                                    $value = $src[0];
                                } else {
                                    $value = wp_get_attachment_url( $value );
                                }
                                break;
                        }
                        break;

                    case 'post_object':
                    case 'relationship':
                        // $value is a WP_Post object — get its permalink
                        $value = get_permalink( $value );
                        break;

                    case 'taxonomy':
                        $value = get_term_link( $value, $field['taxonomy'] );
                        break;
                }
            }
        } else {
            // Field config not found — read raw by meta key
            $value = get_field( $meta_key );
        }

        if ( empty( $value ) && $this->get_settings( 'fallback' ) ) {
            $value = $this->get_settings( 'fallback' );
        }

        return wp_kses_post( $value );
    }

    /**
     * Exact replication of Elementor Pro's Dynamic_Value_Provider::get_value().
     *
     * Key format stored in control: "field_XXXXX:field_name"
     *   - Split on ":"
     *   - [0] = ACF internal field key  e.g. field_5f2a3b4c
     *   - [1] = ACF field name/meta key e.g. elementor_template_id
     *
     * Context detection — mirrors Elementor Pro exactly:
     *   - Inside Loop Builder template → get_field_object( $field_key, get_the_ID() )
     *     get_the_ID() here returns the CURRENT LOOP ITEM id because Elementor's
     *     loop renderer calls setup_postdata() before rendering each item template.
     *   - Outside loop → get_field_object( $field_key, get_queried_object() )
     */
    private function get_tag_value_field(): array {
        $key = $this->get_settings( 'key' );

        if ( empty( $key ) ) {
            return [ null, '' ];
        }

        // Split "field_XXXXX:field_name" — colon separator (Elementor Pro format)
        $parts     = explode( ':', $key, 2 );
        $field_key = $parts[0];
        $meta_key  = $parts[1] ?? $field_key;

        if ( ! function_exists( 'get_field_object' ) ) {
            return [ null, $meta_key ];
        }

        // Detect if we are inside an Elementor Loop Builder template
        // Mirrors: LoopBuilderModule::TEMPLATE_LIBRARY_TYPE_SLUG === $document::get_type()
        $in_loop = false;

        if ( class_exists( '\Elementor\Plugin' ) ) {
            $document = \Elementor\Plugin::$instance->documents->get_current();

            if ( $document ) {
                $type = $document::get_type();
                // Elementor Pro loop template type slug is 'loop-template'
                // but we check both the Pro slug and common variations
                if ( in_array( $type, [ 'loop-template', 'loop_template', 'loop' ], true ) ) {
                    $in_loop = true;
                }
            }
        }

        if ( $in_loop ) {
            // Inside loop: use get_the_ID() — Elementor has called setup_postdata()
            // so this correctly returns the current loop ITEM post ID
            $field = get_field_object( $field_key, get_the_ID() );
        } else {
            // Outside loop: use queried object (post, term, user, etc.)
            $field = get_field_object( $field_key, get_queried_object() );
        }

        return [ $field, $meta_key ];
    }

    /**
     * Build grouped SELECT options. Key format: "field_XXXXX:field_name"
     * Mirrors Elementor Pro's Module::get_control_options().
     */
    private function get_control_options(): array {
        $groups = [];

        if ( ! function_exists( 'acf_get_field_groups' ) || ! function_exists( 'acf_get_fields' ) ) {
            return $groups;
        }

        $supported = $this->get_supported_fields();

        foreach ( acf_get_field_groups() as $acf_group ) {
            if ( isset( $acf_group['ID'] ) && ! empty( $acf_group['ID'] ) ) {
                $fields = acf_get_fields( $acf_group['ID'] );
            } else {
                $fields = acf_get_fields( $acf_group );
            }

            if ( ! is_array( $fields ) ) {
                continue;
            }

            $options = [];

            foreach ( $fields as $field ) {
                if ( ! in_array( $field['type'], $supported, true ) ) {
                    continue;
                }

                // Same key format as Elementor Pro: "field_XXXXX:field_name"
                $option_key             = $field['key'] . ':' . $field['name'];
                $options[ $option_key ] = $field['label'];
            }

            if ( empty( $options ) ) {
                continue;
            }

            $groups[] = [
                'label'   => $acf_group['title'],
                'options' => $options,
            ];
        }

        return $groups;
    }
}