<?php

namespace GriffinForms\Admin\Html\Elements\Submission;

class InputAddress extends \GriffinForms\Admin\Html\Elements\Submission\Format
{
    protected $address = array();
    protected $labels = array();
    protected $line2_enabled = true;
    protected $country_map = array();
    protected $subdivision_map = array();

    protected function setFieldValue()
    {
        $raw = $this->field_value;

        if (is_string($raw)) {
            $raw = json_decode($raw, true);
        }

        if (!is_array($raw)) {
            $raw = array();
        }

        $this->labels = $this->computeLabels();
        $this->line2_enabled = $this->isLine2Enabled();
        $this->bootstrapChoiceMaps();

        $defaults = $this->getEmptyAddress();
        $address = array();

        foreach ($defaults as $key => $default) {
            if (isset($raw[$key]) && is_string($raw[$key])) {
                $address[$key] = trim($raw[$key]);
            } else {
                $address[$key] = '';
            }
        }

        $country_code = strtoupper($address['country']);
        $address['country_code'] = $country_code;
        $address['country_label'] = $this->country_map[$country_code] ?? $address['country'];

        $state_value = $address['state'];
        if ($country_code && isset($this->subdivision_map[$country_code]) && isset($this->subdivision_map[$country_code][$state_value])) {
            $address['state_label'] = $this->subdivision_map[$country_code][$state_value];
        } else {
            $address['state_label'] = $state_value;
        }

        $has_content = false;
        foreach (array('line1', 'line2', 'city', 'state', 'postal', 'country') as $key) {
            if (!empty($address[$key])) {
                $has_content = true;
                break;
            }
        }

        if (!$has_content) {
            parent::setFieldValue();
            return;
        }

        $this->address = $address;
        $this->field_value = $address;
    }

    public function getHtml()
    {
        if (!is_array($this->field_value) || empty($this->address)) {
            echo '<div class="' . esc_attr($this->input_class) . '">';
            echo wp_kses_post($this->field_value);
            echo '</div>';
            return;
        }

        $display = array(
            $this->labels['line1']   => ($this->address['line1'] !== '') ? $this->address['line1'] : __('Not provided', 'griffinforms-form-builder'),
            $this->labels['line2']   => ($this->line2_enabled && $this->address['line2'] !== '') ? $this->address['line2'] : '',
            $this->labels['city']    => ($this->address['city'] !== '') ? $this->address['city'] : __('Not provided', 'griffinforms-form-builder'),
            $this->labels['state']   => ($this->address['state_label'] !== '') ? $this->address['state_label'] : __('Not provided', 'griffinforms-form-builder'),
            $this->labels['postal']  => ($this->address['postal'] !== '') ? $this->address['postal'] : __('Not provided', 'griffinforms-form-builder'),
            $this->labels['country'] => ($this->address['country_label'] !== '') ? $this->address['country_label'] : __('Not provided', 'griffinforms-form-builder'),
        );

        echo '<div class="' . esc_attr($this->input_class) . ' bg-white border rounded-1 p-3 mb-3">';
        echo '<ul class="list-unstyled mb-0">';
        foreach ($display as $label => $value) {
            if ($value === '') {
                continue;
            }
            echo '<li class="mb-2">';
            echo '<div class="fw-semibold small text-muted">' . esc_html($label) . '</div>';
            echo '<div class="text-dark">' . esc_html($value) . '</div>';
            echo '</li>';
        }
        echo '</ul>';

        $map_url = $this->getMapsUrl();
        if ($map_url) {
            echo '<div class="text-end mt-2">';
            echo '<a href="' . esc_url($map_url) . '" target="_blank" rel="noopener noreferrer" class="small text-decoration-none">';
            echo esc_html__('Open in Google Maps', 'griffinforms-form-builder');
            echo ' <span class="dashicons dashicons-external"></span>';
            echo '</a>';
            echo '</div>';
        }
        echo '</div>';
    }

    protected function computeLabels()
    {
        if (!isset($this->lang) || !is_object($this->lang)) {
            $this->setLang();
        }

        $field_settings = $this->field->getProp('field_settings');

        $defaults = array(
            'line1'   => $this->safeLabel('address_line1_default_label', __('Address Line 1', 'griffinforms-form-builder')),
            'line2'   => $this->safeLabel('address_line2_default_label', __('Address Line 2', 'griffinforms-form-builder')),
            'city'    => $this->safeLabel('address_city_default_label', __('City', 'griffinforms-form-builder')),
            'state'   => $this->safeLabel('address_state_default_label', __('State / Province', 'griffinforms-form-builder')),
            'postal'  => $this->safeLabel('address_postal_default_label', __('Postal / ZIP', 'griffinforms-form-builder')),
            'country' => $this->safeLabel('address_country_default_label', __('Country', 'griffinforms-form-builder'))
        );

        if (isset($field_settings['labels']) && is_array($field_settings['labels'])) {
            foreach ($defaults as $key => $fallback) {
                if (isset($field_settings['labels'][$key])) {
                    $label = trim((string) $field_settings['labels'][$key]);
                    $defaults[$key] = ($label === '') ? $fallback : $label;
                }
            }
        }

        return $defaults;
    }

    /**
     * Gracefully fetch a label from language with a readable fallback.
     */
    protected function safeLabel(string $key, string $fallback): string
    {
        $value = '';
        if (isset($this->lang) && is_object($this->lang)) {
            $value = (string) $this->lang->getText($key);
        }

        if ($value === '' || stripos($value, 'not found') !== false) {
            return $fallback;
        }

        return $value;
    }

    protected function isLine2Enabled()
    {
        $field_settings = $this->field->getProp('field_settings');
        if (isset($field_settings['enable_line2'])) {
            return (int) $field_settings['enable_line2'] === 1;
        }

        return true;
    }

    protected function bootstrapChoiceMaps()
    {
        $choices = \GriffinForms\Admin\Choices\Field::getInstance();
        $countries = $choices->getChoices('address_countries', false);
        $this->country_map = is_array($countries) ? $countries : array();

        $subdivisions = $choices->getChoices('address_subdivisions', false);
        $this->subdivision_map = is_array($subdivisions) ? $subdivisions : array();
    }

    protected function getEmptyAddress()
    {
        return array(
            'line1'   => '',
            'line2'   => '',
            'city'    => '',
            'state'   => '',
            'postal'  => '',
            'country' => ''
        );
    }

    protected function getMapsUrl()
    {
        $parts = array();
        foreach (array('line1', 'line2', 'city', 'state_label', 'postal', 'country_label') as $key) {
            if (!empty($this->address[$key])) {
                $parts[] = $this->address[$key];
            }
        }

        if (empty($parts)) {
            return '';
        }

        $query = implode(', ', $parts);
        return 'https://www.google.com/maps/search/?api=1&query=' . rawurlencode($query);
    }
}
