-- migrate:up
--
-- One-shot plate consolidation:
--   1. extract plate from each device's device_name (post " - ", strip _cam)
--   2. for each plate appearing on >1 device (tracker+camera pair), pick the
--      lowest existing vehicle_id as canonical
--   3. remap state.position_history, state.live_positions, domain.devices
--      to the canonical vehicle_id
--   4. delete orphaned vehicle rows
--   5. update canonical vehicles' plate to the extracted plate
--
-- After this runs, domain.vehicles holds one row per physical plate. The
-- PRD F1.6 dedup rule in serve.fn_live_view picks tracker-first when both
-- a tracker and camera report for the same vehicle.
--
-- Idempotent: re-running the migration only updates plates that have moved on.

DO $migration$
BEGIN
    CREATE TEMP TABLE _plate_map ON COMMIT DROP AS
    SELECT
        d.imei,
        d.vehicle_id AS current_vehicle_id,
        regexp_replace(
            (regexp_match(lp.device_name, '^.* - (.+)$'))[1],
            '_(cam|CAM)$', ''
        ) AS new_plate
    FROM domain.devices d
    JOIN state.live_positions lp ON lp.imei = d.imei
    WHERE lp.device_name LIKE '% - %';

    DELETE FROM _plate_map
    WHERE new_plate IS NULL
       OR new_plate = ''
       OR new_plate !~ '[A-Z]'
       OR new_plate !~ '[0-9]';

    CREATE TEMP TABLE _canonical ON COMMIT DROP AS
    SELECT new_plate, min(current_vehicle_id) AS canonical_vehicle_id
    FROM _plate_map
    GROUP BY new_plate;

    -- Drop UNIQUE so the multi-row plate assignment doesn't transiently violate
    ALTER TABLE domain.vehicles DROP CONSTRAINT IF EXISTS vehicles_plate_key;

    UPDATE state.position_history ph
    SET vehicle_id = c.canonical_vehicle_id
    FROM _plate_map pm
    JOIN _canonical c ON c.new_plate = pm.new_plate
    WHERE ph.imei = pm.imei
      AND ph.vehicle_id != c.canonical_vehicle_id;

    UPDATE state.live_positions lp
    SET vehicle_id = c.canonical_vehicle_id
    FROM _plate_map pm
    JOIN _canonical c ON c.new_plate = pm.new_plate
    WHERE lp.imei = pm.imei
      AND lp.vehicle_id != c.canonical_vehicle_id;

    UPDATE domain.devices d
    SET vehicle_id = c.canonical_vehicle_id
    FROM _plate_map pm
    JOIN _canonical c ON c.new_plate = pm.new_plate
    WHERE d.imei = pm.imei
      AND d.vehicle_id != c.canonical_vehicle_id;

    DELETE FROM domain.vehicles v
    WHERE NOT EXISTS (SELECT 1 FROM domain.devices d WHERE d.vehicle_id = v.vehicle_id)
      AND NOT EXISTS (SELECT 1 FROM state.live_positions lp WHERE lp.vehicle_id = v.vehicle_id)
      AND NOT EXISTS (SELECT 1 FROM state.position_history ph WHERE ph.vehicle_id = v.vehicle_id);

    UPDATE domain.vehicles v
    SET plate = c.new_plate, updated_at = now()
    FROM _canonical c
    WHERE v.vehicle_id = c.canonical_vehicle_id;

    ALTER TABLE domain.vehicles ADD CONSTRAINT vehicles_plate_key UNIQUE (plate);
END
$migration$;

-- migrate:down
-- No-op: plate consolidation is a one-way operation.
