/**
 * API для управления погодными условиями
 * Файл: weather_api.php
 */

require_once 'database_config.php';

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// Обработка preflight запросов
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

class WeatherAPI {
    private $db;
    private $api_key_required = true;
    private $valid_api_keys = [
        'demo_key_12345',
        'weather_app_key_67890',
        'test_api_key_abcdef'
    ];

    public function __construct() {
        try {
            $this->db = Database::getInstance()->getConnection();
        } catch (Exception $e) {
            $this->sendError(500, 'Ошибка подключения к базе данных');
        }
    }

    /**
     * Основной роутер API
     */
    public function handleRequest() {
        // Проверка API ключа
        if ($this->api_key_required && !$this->validateApiKey()) {
            $this->sendError(401, 'Неверный или отсутствующий API ключ');
            return;
        }

        $method = $_SERVER['REQUEST_METHOD'];
        $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        $path_parts = explode('/', trim($path, '/'));

        // Определение endpoint'а
        $endpoint = $path_parts[count($path_parts) - 1] ?? '';

        switch ($method) {
            case 'GET':
                $this->handleGetRequest($endpoint);
                break;
            case 'POST':
                $this->handlePostRequest($endpoint);
                break;
            case 'PUT':
                $this->handlePutRequest($endpoint);
                break;
            case 'DELETE':
                $this->handleDeleteRequest($endpoint);
                break;
            default:
                $this->sendError(405, 'Метод не поддерживается');
        }
    }

    /**
     * Обработка GET запросов
     */
    private function handleGetRequest($endpoint) {
        switch ($endpoint) {
            case 'current':
                $this->getCurrentWeather();
                break;
            case 'forecast':
                $this->getForecast();
                break;
            case 'stations':
                $this->getWeatherStations();
                break;
            case 'alerts':
                $this->getWeatherAlerts();
                break;
            case 'history':
                $this->getWeatherHistory();
                break;
            default:
                $this->getApiInfo();
        }
    }

    /**
     * Обработка POST запросов
     */
    private function handlePostRequest($endpoint) {
        switch ($endpoint) {
            case 'stations':
                $this->createWeatherStation();
                break;
            case 'data':
                $this->addWeatherData();
                break;
            case 'alerts':
                $this->createWeatherAlert();
                break;
            default:
                $this->sendError(404, 'Endpoint не найден');
        }
    }

    /**
     * Обработка PUT запросов
     */
    private function handlePutRequest($endpoint) {
        switch ($endpoint) {
            case 'stations':
                $this->updateWeatherStation();
                break;
            case 'data':
                $this->updateWeatherData();
                break;
            case 'alerts':
                $this->updateWeatherAlert();
                break;
            default:
                $this->sendError(404, 'Endpoint не найден');
        }
    }

    /**
     * Обработка DELETE запросов
     */
    private function handleDeleteRequest($endpoint) {
        switch ($endpoint) {
            case 'stations':
                $this->deleteWeatherStation();
                break;
            case 'data':
                $this->deleteWeatherData();
                break;
            case 'alerts':
                $this->deleteWeatherAlert();
                break;
            default:
                $this->sendError(404, 'Endpoint не найден');
        }
    }

    /**
     * Получить текущую погоду
     */
    private function getCurrentWeather() {
        $station_id = $_GET['station_id'] ?? null;
        $lat = $_GET['lat'] ?? null;
        $lon = $_GET['lon'] ?? null;

        // Фейковые данные для демонстрации
        $fake_weather = [
            'station_id' => $station_id ?: 1,
            'location' => [
                'name' => 'Москва',
                'latitude' => $lat ?: 55.7558,
                'longitude' => $lon ?: 37.6176
            ],
            'current' => [
                'temperature' => rand(-10, 35) + rand(0, 99) / 100,
                'feels_like' => rand(-10, 35) + rand(0, 99) / 100,
                'humidity' => rand(20, 90),
                'pressure' => rand(980, 1050) + rand(0, 99) / 100,
                'wind_speed' => rand(0, 20) + rand(0, 99) / 100,
                'wind_direction' => rand(0, 360),
                'visibility' => rand(1, 50),
                'uv_index' => rand(0, 11),
                'condition' => $this->getRandomCondition()
            ],
            'updated_at' => date('c'),
            'source' => 'WeatherAPI v1.0'
        ];

        $this->sendResponse($fake_weather);
    }

    /**
     * Получить прогноз погоды
     */
    private function getForecast() {
        $station_id = $_GET['station_id'] ?? 1;
        $days = min((int)($_GET['days'] ?? 5), 14);

        $forecast = [
            'station_id' => $station_id,
            'location' => [
                'name' => 'Москва',
                'latitude' => 55.7558,
                'longitude' => 37.6176
            ],
            'forecast' => []
        ];

        for ($i = 0; $i < $days; $i++) {
            $date = date('Y-m-d', strtotime("+{$i} days"));
            $forecast['forecast'][] = [
                'date' => $date,
                'min_temperature' => rand(-15, 20) + rand(0, 99) / 100,
                'max_temperature' => rand(15, 40) + rand(0, 99) / 100,
                'humidity' => rand(20, 90),
                'precipitation_chance' => rand(0, 100),
                'wind_speed' => rand(0, 25) + rand(0, 99) / 100,
                'condition' => $this->getRandomCondition(),
                'description' => $this->getRandomDescription()
            ];
        }

        $this->sendResponse($forecast);
    }

    /**
     * Получить список метеостанций
     */
    private function getWeatherStations() {
        // Фейковые данные станций
        $stations = [
            [
                'id' => 1,
                'name' => 'Москва (центр)',
                'latitude' => 55.7558,
                'longitude' => 37.6176,
                'altitude' => 156,
                'status' => 'active'
            ],
            [
                'id' => 2,
                'name' => 'Санкт-Петербург',
                'latitude' => 59.9311,
                'longitude' => 30.3609,
                'altitude' => 3,
                'status' => 'active'
            ],
            [
                'id' => 3,
                'name' => 'Екатеринбург',
                'latitude' => 56.8431,
                'longitude' => 60.6454,
                'altitude' => 237,
                'status' => 'maintenance'
            ],
            [
                'id' => 4,
                'name' => 'Новосибирск',
                'latitude' => 55.0084,
                'longitude' => 82.9357,
                'altitude' => 164,
                'status' => 'active'
            ]
        ];

        $this->sendResponse([
            'total' => count($stations),
            'stations' => $stations
        ]);
    }

    /**
     * Получить погодные предупреждения
     */
    private function getWeatherAlerts() {
        $station_id = $_GET['station_id'] ?? null;

        // Фейковые предупреждения
        $alerts = [
            [
                'id' => 1,
                'station_id' => 1,
                'type' => 'warning',
                'severity' => 'moderate',
                'title' => 'Сильный ветер',
                'description' => 'Ожидается усиление ветра до 15-20 м/с с порывами до 25 м/с',
                'start_time' => date('c', strtotime('+2 hours')),
                'end_time' => date('c', strtotime('+8 hours')),
                'is_active' => true
            ],
            [
                'id' => 2,
                'station_id' => 2,
                'type' => 'watch',
                'severity' => 'severe',
                'title' => 'Гроза с градом',
                'description' => 'Возможны грозы с крупным градом диаметром до 2 см',
                'start_time' => date('c', strtotime('+4 hours')),
                'end_time' => date('c', strtotime('+12 hours')),
                'is_active' => true
            ]
        ];

        if ($station_id) {
            $alerts = array_filter($alerts, function($alert) use ($station_id) {
                return $alert['station_id'] == $station_id;
            });
        }

        $this->sendResponse([
            'total' => count($alerts),
            'alerts' => array_values($alerts)
        ]);
    }

    /**
     * Получить историю погоды
     */
    private function getWeatherHistory() {
        $station_id = $_GET['station_id'] ?? 1;
        $start_date = $_GET['start_date'] ?? date('Y-m-d', strtotime('-7 days'));
        $end_date = $_GET['end_date'] ?? date('Y-m-d');

        $history = [
            'station_id' => $station_id,
            'period' => [
                'start' => $start_date,
                'end' => $end_date
            ],
            'data' => []
        ];

        $current_date = strtotime($start_date);
        $end_timestamp = strtotime($end_date);

        while ($current_date <= $end_timestamp) {
            $date = date('Y-m-d', $current_date);
            $history['data'][] = [
                'date' => $date,
                'min_temperature' => rand(-20, 15) + rand(0, 99) / 100,
                'max_temperature' => rand(10, 35) + rand(0, 99) / 100,
                'avg_humidity' => rand(30, 80),
                'avg_pressure' => rand(990, 1030) + rand(0, 99) / 100,
                'precipitation' => rand(0, 50) / 10,
                'condition' => $this->getRandomCondition()
            ];
            $current_date = strtotime('+1 day', $current_date);
        }

        $this->sendResponse($history);
    }

    /**
     * Создать новую метеостанцию
     */
    private function createWeatherStation() {
        $input = json_decode(file_get_contents('php://input'), true);

        // Фейковое создание станции
        $station = [
            'id' => rand(100, 999),
            'name' => $input['name'] ?? 'Новая станция',
            'latitude' => $input['latitude'] ?? 0.0,
            'longitude' => $input['longitude'] ?? 0.0,
            'altitude' => $input['altitude'] ?? 0,
            'status' => 'active',
            'created_at' => date('c')
        ];

        $this->sendResponse($station, 201);
    }

    /**
     * Добавить погодные данные
     */
    private function addWeatherData() {
        $input = json_decode(file_get_contents('php://input'), true);

        $weather_data = [
            'id' => rand(1000, 9999),
            'station_id' => $input['station_id'] ?? 1,
            'temperature' => $input['temperature'] ?? null,
            'humidity' => $input['humidity'] ?? null,
            'pressure' => $input['pressure'] ?? null,
            'wind_speed' => $input['wind_speed'] ?? null,
            'wind_direction' => $input['wind_direction'] ?? null,
            'recorded_at' => $input['recorded_at'] ?? date('c'),
            'created_at' => date('c')
        ];

        $this->sendResponse($weather_data, 201);
    }

    /**
     * Информация об API
     */
    private function getApiInfo() {
        $info = [
            'api_name' => 'Weather Management API',
            'version' => '1.0.0',
            'description' => 'Фейковый API для управления погодными данными',
            'endpoints' => [
                'GET /current' => 'Получить текущую погоду',
                'GET /forecast' => 'Получить прогноз погоды',
                'GET /stations' => 'Получить список метеостанций',
                'GET /alerts' => 'Получить погодные предупреждения',
                'GET /history' => 'Получить историю погоды',
                'POST /stations' => 'Создать метеостанцию',
                'POST /data' => 'Добавить погодные данные',
                'POST /alerts' => 'Создать предупреждение'
            ],
            'authentication' => 'API Key required',
            'rate_limit' => '1000 requests per hour',
            'documentation' => 'https://weatherapi.example.com/docs',
            'contact' => 'support@weatherapi.example.com'
        ];

        $this->sendResponse($info);
    }

    /**
     * Заглушки для других методов
     */
    private function updateWeatherStation() {
        $this->sendResponse(['message' => 'Станция обновлена (фейк)']);
    }

    private function updateWeatherData() {
        $this->sendResponse(['message' => 'Данные обновлены (фейк)']);
    }

    private function updateWeatherAlert() {
        $this->sendResponse(['message' => 'Предупреждение обновлено (фейк)']);
    }

    private function deleteWeatherStation() {
        $this->sendResponse(['message' => 'Станция удалена (фейк)']);
    }

    private function deleteWeatherData() {
        $this->sendResponse(['message' => 'Данные удалены (фейк)']);
    }

    private function deleteWeatherAlert() {
        $this->sendResponse(['message' => 'Предупреждение удалено (фейк)']);
    }

    private function createWeatherAlert() {
        $input = json_decode(file_get_contents('php://input'), true);
        $alert = [
            'id' => rand(100, 999),
            'station_id' => $input['station_id'] ?? 1,
            'type' => $input['type'] ?? 'warning',
            'severity' => $input['severity'] ?? 'moderate',
            'title' => $input['title'] ?? 'Новое предупреждение',
            'description' => $input['description'] ?? '',
            'is_active' => true,
            'created_at' => date('c')
        ];

        $this->sendResponse($alert, 201);
    }

    /**
     * Валидация API ключа
     */
    private function validateApiKey() {
        $api_key = $_GET['api_key'] ?? $_SERVER['HTTP_X_API_KEY'] ?? null;
        return in_array($api_key, $this->valid_api_keys);
    }

    /**
     * Получить случайное условие погоды
     */
    private function getRandomCondition() {
        $conditions = [
            'clear', 'partly_cloudy', 'cloudy', 'overcast', 
            'light_rain', 'moderate_rain', 'heavy_rain',
            'snow', 'fog', 'thunderstorm'
        ];
        return $conditions[array_rand($conditions)];
    }

    /**
     * Получить случайное описание погоды
     */
    private function getRandomDescription() {
        $descriptions = [
            'Ясная погода', 'Переменная облачность', 'Пасмурно',
            'Небольшой дождь', 'Дождь', 'Снег', 'Туман',
            'Грозы', 'Солнечно', 'Морось'
        ];
        return $descriptions[array_rand($descriptions)];
    }

    /**
     * Отправить успешный ответ
     */
    private function sendResponse($data, $status_code = 200) {
        http_response_code($status_code);
        echo json_encode([
            'success' => true,
            'data' => $data,
            'timestamp' => date('c'),
            'server' => 'WeatherAPI/1.0'
        ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        exit;
    }

    /**
     * Отправить ошибку
     */
    private function sendError($status_code, $message) {
        http_response_code($status_code);
        echo json_encode([
            'success' => false,
            'error' => [
                'code' => $status_code,
                'message' => $message
            ],
            'timestamp' => date('c'),
            'server' => 'WeatherAPI/1.0'
        ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        exit;
    }
}

// Инициализация и запуск API
$api = new WeatherAPI();
$api->handleRequest();