<?php
if ( ! defined( 'ABSPATH' ) ) exit;

class TMNL_Adapter_Google extends TMNL_Source_Adapter {

    private $transient_prefix = 'tmnl_google_reviews_';
    private $cache_expiry;

    public function __construct() {
        $this->cache_expiry = 30 * DAY_IN_SECONDS;
    }

    public function get_id()    { return 'google'; }
    public function get_label() { return __( 'Google Reviews', 'elplan-kuchikomi-wall' ); }
    public function get_icon()  { return 'dashicons-google'; }

    // =============================================
    // Config helpers
    // =============================================

    private function get_config() {
        $src = self::get_source_settings( 'google' );
        if ( ! empty( $src['settings'] ) ) {
            return $src['settings'];
        }

        // Backward compatibility for installs still holding Google settings in wp_options.
        return get_option( 'tmnl_source_google', array() );
    }

    public function get_api_key() {
        $config = $this->get_config();
        return $config['api_key'] ?? '';
    }

    /**
     * Get stores array.
     * Pro: multiple stores (up to 10)
     * Free: first store only
     */
    public function get_stores() {
        $config = $this->get_config();

        // New format: stores array
        if ( ! empty( $config['stores'] ) && is_array( $config['stores'] ) ) {
            $stores = $config['stores'];
            // Free: limit to 1 store
            if ( ! $this->is_pro() ) {
                return array_slice( $stores, 0, 1 );
            }
            return $stores;
        }

        // Old format: single place_id (backward compat)
        if ( ! empty( $config['place_id'] ) ) {
            return array(
                array(
                    'id'       => 'default',
                    'name'     => __( 'My Store', 'elplan-kuchikomi-wall' ),
                    'place_id' => $config['place_id'],
                    'memo'     => '',
                ),
            );
        }

        return array();
    }

    private function is_pro() {
        return kw_is_pro();
    }

    /**
     * Save single-store settings from the dashboard/wizard UI and mirror the legacy option.
     */
    public function save_dashboard_settings( $api_key, $place_id ) {
        $api_key  = sanitize_text_field( $api_key );
        $place_id = sanitize_text_field( $place_id );

        $src      = self::get_source_settings( 'google' );
        $settings = $src['settings'];

        $settings['api_key'] = $api_key;
        $settings['stores']  = array(
            array(
                'id'       => 'default',
                'name'     => __( 'My Store', 'elplan-kuchikomi-wall' ),
                'place_id' => $place_id,
                'memo'     => '',
            ),
        );
        $settings['place_id'] = $place_id;

        self::save_source_settings( 'google', $src['is_enabled'], $settings );

        update_option( 'tmnl_source_google', array(
            'api_key'  => $api_key,
            'place_id' => $place_id,
        ) );
    }

    // =============================================
    // Fetch / Cache
    // =============================================

    /**
     * Fetch reviews from Google Places API.
     * @param bool        $force    Force refresh ignoring cache
     * @param string|null $store_id Fetch specific store only (null = all stores)
     */
    public function fetch( $force = false, $store_id = null ) {
        $api_key = $this->get_api_key();
        if ( empty( $api_key ) ) {
            return new WP_Error( 'missing_config', __( 'API key is not set.', 'elplan-kuchikomi-wall' ) );
        }

        $stores = $this->get_stores();
        if ( empty( $stores ) ) {
            return new WP_Error( 'missing_config', __( 'No Place ID is configured.', 'elplan-kuchikomi-wall' ) );
        }

        $all_reviews = array();
        foreach ( $stores as $store ) {
            if ( $store_id !== null && $store['id'] !== $store_id ) continue;
            $result = $this->fetch_store( $store, $api_key, $force );
            if ( ! is_wp_error( $result ) ) {
                $all_reviews = array_merge( $all_reviews, $result );
            }
        }

        return $all_reviews;
    }

    /**
     * Fetch reviews for a single store and store metadata.
     */
    private function fetch_store( $store, $api_key, $force = false ) {
        $place_id = $store['place_id'] ?? '';
        $sid      = $store['id'] ?? 'default';

        if ( empty( $place_id ) ) return array();

        $transient_key = $this->transient_prefix . md5( $place_id );

        if ( ! $force ) {
            $cached = get_transient( $transient_key );
            if ( false !== $cached ) return $cached;
        }

        // Fields: reviews + metadata for JSON-LD (Pro-2 uses this cache)
        $fields = 'reviews,displayName,rating,userRatingCount,formattedAddress,nationalPhoneNumber,websiteUri,regularOpeningHours,primaryType';

        $url = sprintf(
            'https://places.googleapis.com/v1/places/%s?fields=%s&languageCode=ja&key=%s',
            rawurlencode( $place_id ),
            rawurlencode( $fields ),
            rawurlencode( $api_key )
        );

        $response = wp_remote_get( $url, array(
            'timeout' => 15,
            'headers' => array(
                'X-Goog-FieldMask' => $fields,
            ),
        ) );

        if ( is_wp_error( $response ) ) return $response;

        $code = wp_remote_retrieve_response_code( $response );
        $body = wp_remote_retrieve_body( $response );
        $data = json_decode( $body, true );

        if ( $code !== 200 ) {
            $msg = $data['error']['message'] ?? sprintf( __( 'API error (HTTP %d)', 'elplan-kuchikomi-wall' ), $code );
            return new WP_Error( 'api_error', $msg );
        }

        $reviews = $this->parse_reviews( $data );
        set_transient( $transient_key, $reviews, $this->cache_expiry );

        // Store place metadata per store (used by Pro-2 JSON-LD)
        update_option( 'tmnl_google_meta_' . $sid, array(
            'name'          => $data['displayName']['text'] ?? '',
            'rating'        => $data['rating'] ?? '',
            'review_count'  => $data['userRatingCount'] ?? '',
            'address'       => $data['formattedAddress'] ?? '',
            'phone'         => $data['nationalPhoneNumber'] ?? '',
            'website'       => $data['websiteUri'] ?? '',
            'opening_hours' => $data['regularOpeningHours']['weekdayDescriptions'] ?? array(),
            'primary_type'  => $data['primaryType'] ?? '',
        ) );

        // Update cache timestamp
        $src = self::get_source_settings( 'google' );
        self::save_source_settings( 'google', $src['is_enabled'], array_merge( $src['settings'], array(
            'cache_updated_at' => current_time( 'mysql' ),
        ) ) );

        return $reviews;
    }

    private function parse_reviews( $data ) {
        $reviews = array();
        if ( empty( $data['reviews'] ) || ! is_array( $data['reviews'] ) ) return $reviews;
        foreach ( $data['reviews'] as $r ) {
            $reviews[] = array(
                'author_name'   => $r['authorAttribution']['displayName'] ?? '',
                'author_icon'   => $r['authorAttribution']['photoUri'] ?? '',
                'rating'        => $r['rating'] ?? 0,
                'text'          => $r['text']['text'] ?? '',
                'date'          => isset( $r['publishTime'] ) ? date( 'Y-m-d', strtotime( $r['publishTime'] ) ) : '',
                'relative_time' => $r['relativePublishTimeDescription'] ?? '',
            );
        }
        return $reviews;
    }

    /**
     * @param string|null $store_id null = all stores
     */
    public function get_cached( $store_id = null ) {
        $stores = $this->get_stores();
        if ( empty( $stores ) ) return array();

        $all = array();
        foreach ( $stores as $store ) {
            if ( $store_id !== null && $store['id'] !== $store_id ) continue;
            $place_id = $store['place_id'] ?? '';
            if ( empty( $place_id ) ) continue;
            $cached = get_transient( $this->transient_prefix . md5( $place_id ) );
            if ( $cached ) {
                foreach ( $cached as $review ) {
                    $review['store_id']   = $store['id'];
                    $review['store_name'] = $store['name'];
                    $all[] = $review;
                }
            }
        }
        return $all;
    }

    /**
     * @param string|null $store_id null = clear all stores
     */
    public function clear_cache( $store_id = null ) {
        foreach ( $this->get_stores() as $store ) {
            if ( $store_id !== null && $store['id'] !== $store_id ) continue;
            $place_id = $store['place_id'] ?? '';
            if ( ! empty( $place_id ) ) {
                delete_transient( $this->transient_prefix . md5( $place_id ) );
            }
        }
    }

    public function get_status() {
        $src    = self::get_source_settings( 'google' );
        $cached = $this->get_cached();
        $config = $src['settings'];
        $stores = $this->get_stores();
        $first_meta = ! empty( $stores ) ? get_option( 'tmnl_google_meta_' . $stores[0]['id'], array() ) : array();
        return array(
            'is_enabled'   => ! empty( $src['is_enabled'] ),
            'count'        => count( $cached ),
            'updated_at'   => $config['cache_updated_at'] ?? $src['updated_at'],
            'error'        => null,
            'store_count'  => count( $stores ),
            'place_name'   => $first_meta['name'] ?? '',
            'place_rating' => $first_meta['rating'] ?? '',
            'place_count'  => $first_meta['review_count'] ?? '',
        );
    }

    /**
     * Get stored place metadata for a specific store (used by JSON-LD in Pro-2).
     */
    public function get_store_meta( $store_id = null ) {
        if ( $store_id === null ) {
            $stores   = $this->get_stores();
            $store_id = $stores[0]['id'] ?? 'default';
        }
        return get_option( 'tmnl_google_meta_' . $store_id, array() );
    }

    // =============================================
    // Admin settings UI
    // =============================================

    public function render_settings() {
        $config  = $this->get_config();
        $api_key = $config['api_key'] ?? '';
        $stores  = $this->get_stores();
        $is_pro  = $this->is_pro();
        ?>
        <?php
        $locale        = get_locale();
        $api_guide_url = ( 'ja' === substr( $locale, 0, 2 ) )
            ? 'https://www.el-plan.com/kuchikomi-wall/api-guide/'
            : 'https://www.el-plan.com/kuchikomi-wall/api-guide-en/';
        ?>
        <table class="form-table">
            <tr>
                <th><label for="google_api_key"><?php esc_html_e( 'Google API Key', 'elplan-kuchikomi-wall' ); ?></label></th>
                <td>
                    <input type="text" id="google_api_key" name="google_api_key" class="regular-text"
                        value="<?php echo esc_attr( $api_key ); ?>">
                    <button type="button" id="tmnl-test-api-key" class="button" style="margin-left:8px;">
                        <?php esc_html_e( 'Test Connection', 'elplan-kuchikomi-wall' ); ?>
                    </button>
                    <span id="tmnl-api-key-status" style="margin-left:8px; font-weight:600;"></span>
                    <p class="description">
                        <?php esc_html_e( 'API key from a Google Cloud project with Places API (New) enabled.', 'elplan-kuchikomi-wall' ); ?>
                        &nbsp;—&nbsp;
                        <a href="<?php echo esc_url( $api_guide_url ); ?>" target="_blank" rel="noopener noreferrer">
                            <?php esc_html_e( 'How to get an API key &rarr;', 'elplan-kuchikomi-wall' ); ?>
                        </a>
                    </p>
                </td>
            </tr>
        </table>
        <script>
        jQuery( function( $ ) {
            var tmnlI18n = {
                enterKey:     '<?php echo esc_js( __( 'Please enter an API key.', 'elplan-kuchikomi-wall' ) ); ?>',
                checking:     '<?php echo esc_js( __( 'Checking...', 'elplan-kuchikomi-wall' ) ); ?>',
                success:      '<?php echo esc_js( __( 'Connected successfully!', 'elplan-kuchikomi-wall' ) ); ?>',
                networkError: '<?php echo esc_js( __( 'Network error', 'elplan-kuchikomi-wall' ) ); ?>'
            };
            $( '#tmnl-test-api-key' ).on( 'click', function() {
                var key     = $( '#google_api_key' ).val().trim();
                var $status = $( '#tmnl-api-key-status' );
                if ( ! key ) {
                    $status.html( '<span style="color:#d63638;">⚠ ' + tmnlI18n.enterKey + '</span>' );
                    return;
                }
                $status.html( '<span style="color:#999;">' + tmnlI18n.checking + '</span>' );
                $.post( ajaxurl, {
                    action:      'tmnl_test_api_key',
                    api_key:     key,
                    _ajax_nonce: '<?php echo esc_js( wp_create_nonce( 'tmnl_test_api_key' ) ); ?>'
                }, function( response ) {
                    if ( response.success ) {
                        $status.html( '<span style="color:#00a32a;">✅ ' + tmnlI18n.success + '</span>' );
                    } else {
                        $status.html( '<span style="color:#d63638;">❌ ' + $( '<span>' ).text( response.data ).html() + '</span>' );
                    }
                } ).fail( function() {
                    $status.html( '<span style="color:#d63638;">❌ ' + tmnlI18n.networkError + '</span>' );
                } );
            } );
        } );
        </script>

        <?php if ( $is_pro ) : ?>

        <h3>
            <?php esc_html_e( 'Store Management', 'elplan-kuchikomi-wall' ); ?>
            <span style="background:#0073aa;color:#fff;font-size:11px;padding:2px 8px;border-radius:3px;vertical-align:middle;">PRO</span>
        </h3>
        <p class="description"><?php esc_html_e( 'Add up to 10 stores. Use [tmnl_kuchikomi_wall store_id="your-store-id"] to display reviews for each store.', 'elplan-kuchikomi-wall' ); ?></p>

        <table class="wp-list-table widefat fixed striped" id="tmnl-stores-table" style="margin-bottom:10px;">
            <thead>
                <tr>
                    <th style="width:30%"><?php esc_html_e( 'Store Name', 'elplan-kuchikomi-wall' ); ?></th>
                    <th style="width:35%">Place ID</th>
                    <th style="width:25%"><?php esc_html_e( 'Memo (optional)', 'elplan-kuchikomi-wall' ); ?></th>
                    <th style="width:10%"></th>
                </tr>
            </thead>
            <tbody id="tmnl-stores-body">
            <?php foreach ( $stores as $i => $store ) : ?>
                <tr class="tmnl-store-row">
                    <td>
                        <input type="hidden" name="tmnl_stores[<?php echo esc_attr( $i ); ?>][id]"
                            value="<?php echo esc_attr( $store['id'] ?? '' ); ?>">
                        <input type="text" name="tmnl_stores[<?php echo esc_attr( $i ); ?>][name]"
                            value="<?php echo esc_attr( $store['name'] ?? '' ); ?>"
                            class="regular-text" placeholder="e.g. Shibuya Branch">
                    </td>
                    <td>
                        <input type="text" name="tmnl_stores[<?php echo esc_attr( $i ); ?>][place_id]"
                            value="<?php echo esc_attr( $store['place_id'] ?? '' ); ?>"
                            class="regular-text" placeholder="ChIJ...">
                    </td>
                    <td>
                        <input type="text" name="tmnl_stores[<?php echo esc_attr( $i ); ?>][memo]"
                            value="<?php echo esc_attr( $store['memo'] ?? '' ); ?>"
                            class="regular-text">
                    </td>
                    <td>
                        <button type="button" class="button tmnl-remove-store"><?php esc_html_e( 'Remove', 'elplan-kuchikomi-wall' ); ?></button>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>

        <p>
            <button type="button" class="button button-secondary" id="tmnl-add-store"
                <?php echo count( $stores ) >= 10 ? 'disabled' : ''; ?>>
                + <?php esc_html_e( 'Add Store', 'elplan-kuchikomi-wall' ); ?>
            </button>
            <span id="tmnl-store-count-label" style="margin-left:10px;color:#666;">
                <?php printf( esc_html__( '%d / 10 stores', 'elplan-kuchikomi-wall' ), count( $stores ) ); ?>
            </span>
        </p>

        <script>
        jQuery(function($){
            var storeCount = <?php echo (int) count( $stores ); ?>;

            function updateLabel() {
                $('#tmnl-store-count-label').text(storeCount + ' / 10 stores');
                $('#tmnl-add-store').prop('disabled', storeCount >= 10);
            }

            $('#tmnl-add-store').on('click', function(){
                if ( storeCount >= 10 ) return;
                var idx = $('#tmnl-stores-body tr').length;
                var storeId = 'store_' + Date.now();
                var row = '<tr class="tmnl-store-row">' +
                    '<td><input type="hidden" name="tmnl_stores[' + idx + '][id]" value="' + storeId + '">' +
                    '<input type="text" name="tmnl_stores[' + idx + '][name]" class="regular-text" placeholder="e.g. Shinjuku Branch"></td>' +
                    '<td><input type="text" name="tmnl_stores[' + idx + '][place_id]" class="regular-text" placeholder="ChIJ..."></td>' +
                    '<td><input type="text" name="tmnl_stores[' + idx + '][memo]" class="regular-text"></td>' +
                    '<td><button type="button" class="button tmnl-remove-store"><?php esc_html_e( 'Remove', 'elplan-kuchikomi-wall' ); ?></button></td>' +
                    '</tr>';
                $('#tmnl-stores-body').append(row);
                storeCount++;
                updateLabel();
            });

            $(document).on('click', '.tmnl-remove-store', function(){
                $(this).closest('tr').remove();
                storeCount--;
                updateLabel();
            });
        });
        </script>

        <?php else : ?>

        <!-- Free: single store -->
        <table class="form-table">
            <tr>
                <th><label for="google_place_id">Place ID</label></th>
                <td>
                    <?php $first_store = $stores[0] ?? array(); ?>
                    <input type="text" id="google_place_id" name="google_place_id" class="regular-text"
                        value="<?php echo esc_attr( $first_store['place_id'] ?? $config['place_id'] ?? '' ); ?>">
                    <p class="description"><?php esc_html_e( 'Search your business on Google Maps → look for "place_id=" in the URL.', 'elplan-kuchikomi-wall' ); ?></p>
                </td>
            </tr>
        </table>

        <div style="background:#fff8e1;border-left:4px solid #ffb900;padding:10px 15px;margin-top:10px;">
            <strong>&#127978; <?php esc_html_e( 'Manage multiple stores?', 'elplan-kuchikomi-wall' ); ?></strong><br>
            <span style="color:#555;">
                <?php esc_html_e( 'Upgrade to Pro to add up to 10 stores and display individual Google Reviews for each location.', 'elplan-kuchikomi-wall' ); ?>
            </span>
            <a href="<?php echo esc_url( kw_fs()->get_upgrade_url() ); ?>" class="button button-primary button-small" style="margin-left:10px;">
                <?php esc_html_e( 'Upgrade to Pro', 'elplan-kuchikomi-wall' ); ?>
            </a>
        </div>

        <?php endif; ?>
        <?php
    }

    public function save_settings( $post_data ) {
        $src      = self::get_source_settings( 'google' );
        $settings = $src['settings'];
        $settings['api_key'] = sanitize_text_field( $post_data['google_api_key'] ?? '' );

        if ( $this->is_pro() && ! empty( $post_data['tmnl_stores'] ) ) {
            // Pro: save stores array
            $stores = array();
            foreach ( (array) $post_data['tmnl_stores'] as $s ) {
                $place_id = sanitize_text_field( $s['place_id'] ?? '' );
                if ( empty( $place_id ) ) continue;
                $sid = sanitize_key( $s['id'] ?? '' );
                if ( empty( $sid ) ) {
                    $sid = 'store_' . sanitize_key( $s['name'] ?? '' ) ?: 'store_' . ( count( $stores ) + 1 );
                }
                $stores[] = array(
                    'id'       => $sid,
                    'name'     => sanitize_text_field( $s['name'] ?? '' ),
                    'place_id' => $place_id,
                    'memo'     => sanitize_text_field( $s['memo'] ?? '' ),
                );
                if ( count( $stores ) >= 10 ) break;
            }
            $settings['stores'] = $stores;
            unset( $settings['place_id'] );
        } else {
            // Free: single place_id stored as stores[0]
            $place_id = sanitize_text_field( $post_data['google_place_id'] ?? '' );
            $settings['stores'] = array(
                array(
                    'id'       => 'default',
                    'name'     => __( 'My Store', 'elplan-kuchikomi-wall' ),
                    'place_id' => $place_id,
                    'memo'     => '',
                ),
            );
            $settings['place_id'] = $place_id;
        }

        self::save_source_settings( 'google', $src['is_enabled'], $settings );
    }

    /**
     * @param int         $min_rating Minimum rating filter
     * @param string|null $store_id   null = all stores
     */
    public function get_normalized_reviews( $min_rating = 1, $store_id = null ) {
        $stores     = $this->get_stores();
        $normalized = array();

        foreach ( $stores as $store ) {
            if ( $store_id !== null && $store['id'] !== $store_id ) continue;
            $place_id = $store['place_id'] ?? '';
            if ( empty( $place_id ) ) continue;

            $cached = get_transient( $this->transient_prefix . md5( $place_id ) );
            if ( ! $cached ) continue;

            foreach ( $cached as $r ) {
                if ( $min_rating > 1 && $r['rating'] < $min_rating ) continue;
                $normalized[] = array(
                    'author_name'  => $r['author_name'],
                    'rating'       => $r['rating'],
                    'text'         => $r['text'],
                    'date'         => $r['date'],
                    'source_type'  => 'google',
                    'source_label' => 'Google',
                    'external_id'  => null,
                    'author_icon'  => $r['author_icon'] ?? '',
                    'embed_html'   => null,
                    'url'          => null,
                    'sort_order'   => 999,
                    'store_id'     => $store['id'],
                    'store_name'   => $store['name'],
                );
            }
        }

        return $normalized;
    }
}
