<?php
/**
 * GeolocationDataTable — standalone class file.
 *
 * @package UltraguardPro\modules\firewall\db
 */

namespace UltraguardPro\modules\firewall\db;

use UltraguardPro\db\BaseTable;
use UltraguardPro\core\DatabaseCrud;

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

// ─────────────────────────────────────────────────────────────────────────────
class GeolocationDataTable extends BaseTable {

    protected $table_name  = 'ultraguard_geolocation_data';
    protected $cache_group = 'ultraguard_geolocation_data';

    public function get_defaults(): array {
        return [
            'id'           => 0,
            'ip_address'   => '',
            'country_code' => null,
            'country_name' => null,
            'region'       => null,
            'city'         => null,
            'isp'          => null,
            'is_proxy'     => 0,
            'is_tor'       => 0,
            'threat_score' => 0,
            'cached_at'    => '',
        ];
    }

    protected function validate_data( $data ) {
        if ( empty( $data['ip_address'] ) ) { return false; }
        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'is_proxy', 'is_tor' => (int) (bool) $v,
                'threat_score'       => max( 0, min( 100, absint( $v ) ) ),
                default              => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    public function get_for_ip( string $ip ): ?array {
        $record = $this->get_by_field( 'ip_address', $ip );
        if ( ! $record || empty( $record['ip_address'] ) ) { return null; }
        // Invalidate stale cache (older than 7 days)
        if ( ! empty( $record['cached_at'] ) && strtotime( $record['cached_at'] ) < strtotime( '-7 days' ) ) {
            $this->delete( (int) $record['id'] );
            return null;
        }
        return $record;
    }

    public function upsert( string $ip, array $geo_data ): int|false {
        $existing = $this->get_by_field( 'ip_address', $ip );
        if ( $existing && ! empty( $existing['id'] ) ) {
            $this->update( (int) $existing['id'], array_merge( $geo_data, [ 'cached_at' => current_time( 'mysql', true ) ] ) );
            return (int) $existing['id'];
        }
        return $this->insert( array_merge( [ 'ip_address' => $ip ], $geo_data ) );
    }

    protected function get_searchable_fields(): array {
        return [ 'ip_address', 'country_code', 'country_name', 'isp' ];
    }
}

// ─────────────────────────────────────────────────────────────────────────────
