-- ========================================
-- 실제 테이블 데이터로 CAST 호환성 테스트
-- ========================================

-- 1. 최근 5분 데이터 샘플 확인 (100개)
SELECT
    '=== SAMPLE 5MIN DATA ===' as section,
    sig_src_cd,
    target_id,
    time_bucket,
    public.ST_NPoints(track_geom) as points,
    public.ST_IsValid(track_geom) as is_valid
FROM signal.t_vessel_tracks_5min
WHERE track_geom IS NOT NULL
    AND public.ST_NPoints(track_geom) > 0
ORDER BY time_bucket DESC
LIMIT 100;

-- 2. 테스트할 선박 선정 (최근 1시간 내 5분 데이터가 있는 선박)
WITH recent_vessels AS (
    SELECT
        sig_src_cd,
        target_id,
        DATE_TRUNC('hour', time_bucket) as hour_bucket,
        COUNT(*) as record_count,
        MIN(time_bucket) as min_time,
        MAX(time_bucket) as max_time
    FROM signal.t_vessel_tracks_5min
    WHERE time_bucket >= CURRENT_TIMESTAMP - INTERVAL '24 hours'
        AND track_geom IS NOT NULL
        AND public.ST_NPoints(track_geom) > 0
    GROUP BY sig_src_cd, target_id, DATE_TRUNC('hour', time_bucket)
    HAVING COUNT(*) >= 2
    ORDER BY hour_bucket DESC
    LIMIT 10
)
SELECT
    '=== TEST CANDIDATE VESSELS ===' as section,
    sig_src_cd,
    target_id,
    hour_bucket,
    record_count,
    min_time,
    max_time
FROM recent_vessels;

-- 3. 특정 선박의 5분 데이터 상세 확인
-- 아래 값들을 위 결과에서 선택해서 수정하세요
-- 예시: sig_src_cd = '000019', target_id = '111440547', hour_bucket = '2025-01-07 10:00:00'
\set test_sig_src_cd '000019'
\set test_target_id '111440547'
\set test_hour_start '''2025-01-07 10:00:00'''
\set test_hour_end '''2025-01-07 11:00:00'''

SELECT
    '=== 5MIN DATA FOR TEST VESSEL ===' as section,
    sig_src_cd,
    target_id,
    time_bucket,
    public.ST_NPoints(track_geom) as points,
    public.ST_IsValid(track_geom) as is_valid,
    public.ST_GeometryType(track_geom) as geom_type,
    public.ST_AsText(track_geom) as wkt,
    substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)') as regex_v1,
    COALESCE(
        substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)'),
        substring(public.ST_AsText(track_geom) from '\\((.+)\\)')
    ) as regex_v2
FROM signal.t_vessel_tracks_5min
WHERE sig_src_cd = :'test_sig_src_cd'
    AND target_id = :'test_target_id'
    AND time_bucket >= CAST(:test_hour_start AS timestamp)
    AND time_bucket < CAST(:test_hour_end AS timestamp)
    AND track_geom IS NOT NULL
    AND public.ST_NPoints(track_geom) > 0
ORDER BY time_bucket;

-- 4. string_agg 결과 확인
SELECT
    '=== STRING_AGG TEST ===' as section,
    sig_src_cd,
    target_id,
    string_agg(
        COALESCE(
            substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)'),
            substring(public.ST_AsText(track_geom) from '\\((.+)\\)')
        ),
        ','
        ORDER BY time_bucket
    ) FILTER (WHERE track_geom IS NOT NULL) as all_coords,
    COUNT(*) as track_count
FROM signal.t_vessel_tracks_5min
WHERE sig_src_cd = :'test_sig_src_cd'
    AND target_id = :'test_target_id'
    AND time_bucket >= CAST(:test_hour_start AS timestamp)
    AND time_bucket < CAST(:test_hour_end AS timestamp)
    AND track_geom IS NOT NULL
    AND public.ST_NPoints(track_geom) > 0
GROUP BY sig_src_cd, target_id;

-- 5. 병합된 WKT로 geometry 생성 테스트
WITH ordered_tracks AS (
    SELECT *
    FROM signal.t_vessel_tracks_5min
    WHERE sig_src_cd = :'test_sig_src_cd'
        AND target_id = :'test_target_id'
        AND time_bucket >= CAST(:test_hour_start AS timestamp)
        AND time_bucket < CAST(:test_hour_end AS timestamp)
        AND track_geom IS NOT NULL
        AND public.ST_NPoints(track_geom) > 0
    ORDER BY time_bucket
),
merged_coords AS (
    SELECT
        sig_src_cd,
        target_id,
        string_agg(
            COALESCE(
                substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)'),
                substring(public.ST_AsText(track_geom) from '\\((.+)\\)')
            ),
            ','
            ORDER BY time_bucket
        ) FILTER (WHERE track_geom IS NOT NULL) as all_coords
    FROM ordered_tracks
    GROUP BY sig_src_cd, target_id
)
SELECT
    '=== WKT GENERATION TEST ===' as section,
    sig_src_cd,
    target_id,
    'LINESTRING M(' || all_coords || ')' as full_wkt,
    LENGTH(all_coords) as coords_length,
    public.ST_GeomFromText('LINESTRING M(' || all_coords || ')', 4326) as test_geom,
    public.ST_NPoints(public.ST_GeomFromText('LINESTRING M(' || all_coords || ')', 4326)) as merged_points,
    public.ST_IsValid(public.ST_GeomFromText('LINESTRING M(' || all_coords || ')', 4326)) as is_valid
FROM merged_coords;

-- 6. 전체 시간별 집계 쿼리 실행 (SELECT만, INSERT 안함)
WITH ordered_tracks AS (
    SELECT *
    FROM signal.t_vessel_tracks_5min
    WHERE sig_src_cd = :'test_sig_src_cd'
        AND target_id = :'test_target_id'
        AND time_bucket >= CAST(:test_hour_start AS timestamp)
        AND time_bucket < CAST(:test_hour_end AS timestamp)
        AND track_geom IS NOT NULL
        AND public.ST_NPoints(track_geom) > 0
    ORDER BY time_bucket
),
merged_coords AS (
    SELECT
        sig_src_cd,
        target_id,
        string_agg(
            COALESCE(
                substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)'),
                substring(public.ST_AsText(track_geom) from '\\((.+)\\)')
            ),
            ','
            ORDER BY time_bucket
        ) FILTER (WHERE track_geom IS NOT NULL) as all_coords
    FROM ordered_tracks
    GROUP BY sig_src_cd, target_id
),
merged_tracks AS (
    SELECT
        mc.sig_src_cd,
        mc.target_id,
        CAST(:test_hour_start AS timestamp) as time_bucket,
        public.ST_GeomFromText('LINESTRING M(' || mc.all_coords || ')', 4326) as merged_geom,
        (SELECT MAX(max_speed) FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id) as max_speed,
        (SELECT SUM(point_count) FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id) as total_points,
        (SELECT MIN(time_bucket) FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id) as start_time,
        (SELECT MAX(time_bucket) FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id) as end_time,
        (SELECT start_position FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id ORDER BY time_bucket LIMIT 1) as start_pos,
        (SELECT end_position FROM ordered_tracks WHERE sig_src_cd = mc.sig_src_cd AND target_id = mc.target_id ORDER BY time_bucket DESC LIMIT 1) as end_pos
    FROM merged_coords mc
),
calculated_tracks AS (
    SELECT
        *,
        public.ST_Length(merged_geom::geography) / 1852.0 as total_distance,
        CASE
            WHEN public.ST_NPoints(merged_geom) > 0 THEN
                public.ST_M(public.ST_PointN(merged_geom, public.ST_NPoints(merged_geom))) -
                public.ST_M(public.ST_PointN(merged_geom, 1))
            ELSE
                EXTRACT(EPOCH FROM
                    CAST(end_pos->>'time' AS timestamp) - CAST(start_pos->>'time' AS timestamp)
                )
        END as time_diff_seconds
    FROM merged_tracks
)
SELECT
    '=== FULL HOURLY AGGREGATION TEST ===' as section,
    sig_src_cd,
    target_id,
    time_bucket,
    public.ST_NPoints(merged_geom) as merged_points,
    public.ST_IsValid(merged_geom) as is_valid,
    total_distance,
    CASE
        WHEN time_diff_seconds > 0 THEN
            CAST(LEAST((total_distance / (time_diff_seconds / 3600.0)), 9999.99) AS numeric(6,2))
        ELSE 0
    END as avg_speed,
    max_speed,
    total_points,
    start_time,
    end_time,
    start_pos,
    end_pos,
    public.ST_AsText(merged_geom) as geom_text,
    time_diff_seconds
FROM calculated_tracks;

-- 7. M값 시간 순서 검증
WITH ordered_tracks AS (
    SELECT *
    FROM signal.t_vessel_tracks_5min
    WHERE sig_src_cd = :'test_sig_src_cd'
        AND target_id = :'test_target_id'
        AND time_bucket >= CAST(:test_hour_start AS timestamp)
        AND time_bucket < CAST(:test_hour_end AS timestamp)
        AND track_geom IS NOT NULL
        AND public.ST_NPoints(track_geom) > 0
    ORDER BY time_bucket
),
merged_coords AS (
    SELECT
        sig_src_cd,
        target_id,
        string_agg(
            COALESCE(
                substring(public.ST_AsText(track_geom) from 'LINESTRING\\s*M\\s*\\((.+)\\)'),
                substring(public.ST_AsText(track_geom) from '\\((.+)\\)')
            ),
            ','
            ORDER BY time_bucket
        ) FILTER (WHERE track_geom IS NOT NULL) as all_coords
    FROM ordered_tracks
    GROUP BY sig_src_cd, target_id
),
merged_tracks AS (
    SELECT
        mc.sig_src_cd,
        mc.target_id,
        public.ST_GeomFromText('LINESTRING M(' || mc.all_coords || ')', 4326) as merged_geom
    FROM merged_coords mc
)
SELECT
    '=== TIME ORDERING CHECK ===' as section,
    sig_src_cd,
    target_id,
    public.ST_M(public.ST_PointN(merged_geom, 1)) as first_m_value,
    to_timestamp(public.ST_M(public.ST_PointN(merged_geom, 1))) as first_time,
    public.ST_M(public.ST_PointN(merged_geom, public.ST_NPoints(merged_geom))) as last_m_value,
    to_timestamp(public.ST_M(public.ST_PointN(merged_geom, public.ST_NPoints(merged_geom)))) as last_time,
    CASE
        WHEN public.ST_M(public.ST_PointN(merged_geom, public.ST_NPoints(merged_geom))) >=
             public.ST_M(public.ST_PointN(merged_geom, 1))
        THEN 'PASS'
        ELSE 'FAIL'
    END as time_order_check
FROM merged_tracks;

-- ========================================
-- 사용 방법:
-- 1. 먼저 쿼리 2번 실행해서 테스트할 선박 선택
-- 2. \set 변수 값 수정 (라인 48-51)
-- 3. 전체 스크립트 실행
-- 4. 각 섹션별 결과 확인
-- ========================================
