<?php
require_once __DIR__ . '/common.php';

header('Content-Type: application/json');
$dbconn = getDBConnection();

// Default endpoint: Get current point outages
if (empty(array_diff_key($_GET, array('service' => '')))) {
    try {
        $query = "
            SELECT json_build_object(
                'type', 'FeatureCollection',
                'features', COALESCE(json_agg(
                    json_build_object(
                        'type', 'Feature',
                        'geometry', ST_AsGeoJSON(geom)::json,
                        'properties', json_build_object(
                            'time', start_time,
                            'county', county,
                            'state', state,
                            'outage', outagen,
                            'lastchange', last_change,
                            'cause', COALESCE(cause, ''),
                            'area_geometry', ST_AsGeoJSON(COALESCE(realareageom, geom))::json
                        )
                    )
                    ORDER BY start_time ASC
                ), '[]'::json)
            ) as geojson
            FROM newpower
            WHERE cwa = $1 AND active = true AND geom IS NOT NULL
        ";

        $result = pg_query_params($dbconn, $query, array('RLX'));
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $resultArray = pg_fetch_assoc($result);

        if ($resultArray && $resultArray['geojson']) {
            echo $resultArray['geojson'];
        } else {
            echo json_encode(['type' => 'FeatureCollection', 'features' => []]);
        }

        pg_free_result($result);
    } catch (Exception $e) {
        http_response_code(500);
        echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
    }
}

// Get states boundaries
if (isset($_GET['states'])) {
    try {
        $query = "
            SELECT jsonb_build_object(
                'type', 'FeatureCollection',
                'features', jsonb_agg(features.feature)
            )
            FROM (
                SELECT jsonb_build_object(
                    'type', 'Feature',
                    'geometry', ST_AsGeoJSON(ST_Transform(geom, 4326))::jsonb,
                    'properties', to_jsonb(properties) - 'geom'
                ) AS feature
                FROM (
                    SELECT *
                    FROM states
                    WHERE state IN ('WV', 'VA', 'KY', 'MD', 'PA', 'OH')
                ) AS properties
            ) AS features
        ";

        $result = pg_query($dbconn, $query);
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $resultArray = pg_fetch_all($result);

        // Set proper JSON header and handle output
        header('Content-Type: application/json');
        if ($resultArray && isset($resultArray[0]['jsonb_build_object'])) {
            echo $resultArray[0]['jsonb_build_object'];
        } else {
            echo json_encode(['type' => 'FeatureCollection', 'features' => []]);
        }

        pg_free_result($result);
    } catch (Exception $e) {
        header('Content-Type: application/json');
        http_response_code(500);
        echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
        exit;
    }
}

// Get current county outages
if (isset($_GET['county'])) {
    try {
        $query = "
            WITH latest_fetch AS (
                SELECT MAX(fetch_time) as max_fetch_time FROM newcountyoutages
            )
            SELECT
                n.county,
                n.state,
                SUM(n.outages) as outage,
                MAX(n.fetch_time) as time,
                SUM(n.served) as served,
                CASE
                    WHEN SUM(n.served) > 0 THEN ROUND(CAST((SUM(n.outages)::FLOAT / SUM(n.served)) * 100 AS NUMERIC), 2)
                    ELSE 0
                END as perout
            FROM newcountyoutages n, latest_fetch
            WHERE n.fetch_time = latest_fetch.max_fetch_time
                AND n.cwa = $1
            GROUP BY n.county, n.state
        ";

        $result = pg_query_params($dbconn, $query, ['RLX']);
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $results = pg_fetch_all($result) ?: [];
        header('Content-Type: application/json');
        echo json_encode($results);

        pg_free_result($result);
    } catch (Exception $e) {
        header('Content-Type: application/json');
        http_response_code(500);
        echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
    }
}

// Max county outages for a time range
if (isset($_GET['max'])) {
    if (isset($_GET['start']) && isset($_GET['end'])) {
        try {
            $starttime = getParam('start');
            $endtime = getParam('end');

            $query = "
                SELECT DISTINCT ON (county, state)
                    max(outage) as max_outage,
                    county,
                    state
                FROM (
                    SELECT DISTINCT ON (county, state, fetch_time)
                        county,
                        state,
                        SUM(outages) as outage,
                        fetch_time as time,
                        SUM(served) as served
                    FROM newcountyoutages
                    WHERE fetch_time > $2
                        AND fetch_time < $3
                        AND cwa = $1
                    GROUP BY county, state, fetch_time
                ) as subquery
                GROUP BY county, state
            ";

            $result = pg_query_params(
                $dbconn,
                $query,
                ['RLX', $starttime, $endtime]
            );

            if ($result === false) {
                throw new Exception('Query failed: ' . pg_last_error());
            }

            $results = [];
            while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
                $results[] = $line;
            }

            header('Content-Type: application/json');
            echo json_encode($results);

            pg_free_result($result);
        } catch (Exception $e) {
            header('Content-Type: application/json');
            http_response_code(500);
            echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
            exit;
        }
    } else {
        header('Content-Type: application/json');
        http_response_code(400);
        echo json_encode(['error' => 'Both start and end parameters are required']);
    }
}

// Archive county outages for a time range
if (isset($_GET['countyarchive'])) {
    if (isset($_GET['start']) && isset($_GET['end'])) {
        try {
            $starttime = getParam('start');
            $endtime = getParam('end');

            $query = "
                SELECT DISTINCT ON (county, state, fetch_time)
                    county,
                    state,
                    SUM(outages) as outage,
                    fetch_time as time,
                    SUM(served) as served
                FROM newcountyoutages
                WHERE fetch_time > $9
                    AND fetch_time < $10
                    AND (cwa = $1 OR cwa = $2 OR cwa = $3 OR cwa = $4 OR cwa = $5 OR cwa = $6 OR cwa = $7 OR cwa = $8)
                GROUP BY county, state, fetch_time
            ";

            $result = pg_query_params($dbconn, $query, ['RLX','JKL','ILN','PBZ','MRX','LWX','RNK','CTP',$starttime,$endtime]);
            if ($result === false) {
                throw new Exception('Query failed: ' . pg_last_error());
            }

            $results = [];
            while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
                $results[] = $line;
            }

            header('Content-Type: application/json');
            echo json_encode($results);

            pg_free_result($result);
        } catch (Exception $e) {
            header('Content-Type: application/json');
            http_response_code(500);
            echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
            if (isset($result)) {
                pg_free_result($result);
            }
            exit;
        }
    } else {
        header('Content-Type: application/json');
        http_response_code(400);
        echo json_encode(['error' => 'Both start and end parameters are required']);
    }
}

// Archive point data for a time range
if (isset($_GET['archivepoint'])) {
    try {
        if (!isset($_GET['start']) || !isset($_GET['end'])) {
            throw new Exception('Both start and end parameters are required');
        }

        $starttime = getParam('start');
        $endtime = getParam('end');

        $query = "
            SELECT json_build_object(
                'type', 'FeatureCollection',
                'features', json_agg(
                    json_build_object(
                        'type', 'Feature',
                        'geometry', ST_AsGeoJSON(geom)::json,
                        'properties', json_build_object(
                            'time', start_time,
                            'county', county,
                            'state', state,
                            'outage', outagen,
                            'lastchange', last_change,
                            'cause', cause
                        )
                    )
                    ORDER BY start_time ASC
                )
            )
            FROM newpower
            WHERE cwa = $1
                AND start_time > $2
                AND last_change < $3
                AND geom IS NOT NULL
        ";

        $result = pg_query_params($dbconn, $query, ['RLX', $starttime, $endtime]);
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $resultArray = pg_fetch_all($result);

        header('Content-Type: application/json');
        if ($resultArray && isset($resultArray[0]['json_build_object'])) {
            echo $resultArray[0]['json_build_object'];
        } else {
            echo json_encode(['type' => 'FeatureCollection', 'features' => []]);
        }

        pg_free_result($result);
    } catch (Exception $e) {
        header('Content-Type: application/json');
        $statusCode = strpos($e->getMessage(), 'required') !== false ? 400 : 500;
        http_response_code($statusCode);
        echo json_encode(['error' => $e->getMessage()]);
        if (isset($result)) {
            pg_free_result($result);
        }
        exit;
    }
}

// Current severe weather warnings
if (@$_GET['svr'] == 'current') {
    try {
        $result = pg_query($dbconn,
        "SELECT json_build_object('type', 'FeatureCollection','features', json_agg(json_build_object('type','Feature', 'geometry',  ST_AsGeoJSON(nwspoly)::json,'properties',json_build_object('issue',issue,'end',endtime,'vtec',vtec,'type',warntype)))) FROM svr where issue < now() and endtime > now()") or die('Query failed: ' . pg_last_error());
        $resultArray = pg_fetch_all($result);

        header('Content-Type: application/json');
        if ($resultArray && isset($resultArray[0]['json_build_object'])) {
            echo $resultArray[0]['json_build_object'];
        } else {
            echo json_encode(['type' => 'FeatureCollection', 'features' => []]);
        }

        pg_free_result($result);
    } catch (Exception $e) {
        header('Content-Type: application/json');
        http_response_code(500);
        echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]);
    }
}

// Archive severe weather warnings
if (isset($_GET['svr']) && $_GET['svr'] === 'archive') {
    try {
        $result = null;

        if (isset($_GET['start']) && isset($_GET['end'])) {
            $starttime = getParam('start');
            $endtime = getParam('end');

            $query = "
                SELECT json_build_object(
                    'type', 'FeatureCollection',
                    'features', json_agg(
                        json_build_object(
                            'type', 'Feature',
                            'geometry', ST_AsGeoJSON(nwspoly)::json,
                            'properties', json_build_object(
                                'issue', issue,
                                'end', endtime,
                                'vtec', vtec,
                                'type', warntype
                            )
                        )
                    )
                )
            FROM svr
            WHERE issue > $1
                AND endtime < $2
            ";

            $result = pg_query_params($dbconn, $query, [$starttime, $endtime]);
        } elseif (!isset($_GET['start']) && !isset($_GET['end'])) {
            $query = "
                SELECT json_build_object(
                    'type', 'FeatureCollection',
                    'features', json_agg(
                        json_build_object(
                            'type', 'Feature',
                            'geometry', ST_AsGeoJSON(nwspoly)::json,
                            'properties', json_build_object(
                                'issue', issue,
                                'end', endtime,
                                'vtec', vtec,
                                'type', warntype
                            )
                        )
                    )
                )
            FROM svr
            WHERE issue < NOW() - INTERVAL '24 hours'
                AND endtime > NOW() - INTERVAL '24 hours'
            ";

            $result = pg_query($dbconn, $query);
        } else {
            throw new Exception('Both start and end parameters are required together');
        }

        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $resultArray = pg_fetch_all($result);

        header('Content-Type: application/json');
        if ($resultArray && isset($resultArray[0]['json_build_object'])) {
            echo $resultArray[0]['json_build_object'];
        } else {
            echo json_encode(['type' => 'FeatureCollection', 'features' => []]);
        }

        pg_free_result($result);
    } catch (Exception $e) {
        if (isset($result)) {
            pg_free_result($result);
        }
        header('Content-Type: application/json');
        $statusCode = strpos($e->getMessage(), 'required') !== false ? 400 : 500;
        http_response_code($statusCode);
        echo json_encode(['error' => $e->getMessage()]);
        exit;
    }
}

// Severe weather warning polygons
if (isset($_GET['svrpolys'])) {
    try {
        $query = "
            SELECT
                vtec,
                outagesvalid,
                polygonpop,
                outagesbuffer,
                lsrids
            FROM svr
            WHERE EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - endtime)) / 60 / 60 / 24 < 60
        ";

        $result = pg_query($dbconn, $query);
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $results = [];
        while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
            $results[] = $line;
        }

        header('Content-Type: application/json');
        echo json_encode($results);

        pg_free_result($result);
    } catch (Exception $e) {
        if (isset($result)) {
            pg_free_result($result);
        }
        header('Content-Type: application/json');
        http_response_code(500);
        echo json_encode(['error' => $e->getMessage()]);
        exit;
    }
}

// Power outage details by IDs
if (isset($_GET['powerids'])) {
    try {
        $powerids = $_GET['powerids'];

        // Validate input exists and isn't empty
        if (empty($powerids)) {
            throw new Exception('No power IDs provided');
        }

        // Convert comma-separated string to array and sanitize
        $poweridArray = explode(',', $powerids);
        $sanitizedIds = array_filter(array_map('intval', $poweridArray));

        if (empty($sanitizedIds)) {
            throw new Exception('Invalid power ID format');
        }

        // Prepare placeholders for the query
        $placeholders = implode(',', array_map(function($i) { return '$' . $i; }, range(1, count($sanitizedIds))));

        $query = "
            SELECT
                lat,
                lon,
                last_change,
                start_time,
                peakoutage,
                cause,
                lsrtime,
                lsrref,
                (lsrtime AT TIME ZONE 'America/New_York')::timestamp as lsrlocal
            FROM newpower
            WHERE id IN ($placeholders)
        ";

        $result = pg_query_params($dbconn, $query, $sanitizedIds);
        if ($result === false) {
            throw new Exception('Query failed: ' . pg_last_error());
        }

        $results = pg_fetch_all($result) ?: [];

        header('Content-Type: application/json');
        echo json_encode($results);

        pg_free_result($result);
    } catch (Exception $e) {
        if (isset($result)) {
            pg_free_result($result);
        }
        header('Content-Type: application/json');
        $statusCode = strpos($e->getMessage(), 'Invalid') !== false ? 400 : 500;
        http_response_code($statusCode);
        echo json_encode(['error' => $e->getMessage()]);
        exit;
    }
}

pg_close($dbconn);
?>