-- ============================================================================
-- Migration: Add controller_id columns for multi-controller support
-- Run this once against the existing HC900 database.
-- ============================================================================

BEGIN;

-- 1. realtime_table: add controller_id + UNIQUE(controller_id, tagname)
ALTER TABLE realtime_table
  ADD COLUMN IF NOT EXISTS controller_id TEXT NOT NULL DEFAULT 'HC1';

-- Drop any existing unique constraint on tagname alone (idempotent wrapper)
DO $$
BEGIN
  IF EXISTS (
    SELECT 1 FROM pg_indexes
    WHERE tablename = 'realtime_table'
      AND indexname = 'idx_realtime_table_tagname_unique'
  ) THEN
    DROP INDEX IF EXISTS idx_realtime_table_tagname_unique;
  END IF;
  IF EXISTS (
    SELECT 1 FROM pg_constraint c
    JOIN pg_class t ON t.oid = c.conrelid
    WHERE t.relname = 'realtime_table' AND c.contype = 'u'
  ) THEN
    -- There's a unique constraint; we can't easily drop it by name unless we know it.
    -- Use a safe approach: drop any unique constraint on tagname
  END IF;
END $$;

-- Add the new composite UNIQUE (required for ON CONFLICT (controller_id, tagname) DO UPDATE)
-- Skip if already exists
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_indexes
    WHERE tablename = 'realtime_table'
      AND indexname = 'idx_realtime_table_ctrl_tag_unique'
  ) THEN
    CREATE UNIQUE INDEX idx_realtime_table_ctrl_tag_unique
      ON realtime_table(controller_id, tagname);
  END IF;
END $$;

-- 2. history_table: add controller_id with default 'HC1'
ALTER TABLE history_table
  ADD COLUMN IF NOT EXISTS controller_id TEXT NOT NULL DEFAULT 'HC1';

-- 3. event_history_table: add controller_id
ALTER TABLE event_history_table
  ADD COLUMN IF NOT EXISTS controller_id TEXT NOT NULL DEFAULT 'HC1';

-- 4. tag_metadata: add controller_id
ALTER TABLE tag_metadata
  ADD COLUMN IF NOT EXISTS controller_id TEXT NOT NULL DEFAULT 'HC1';

-- 5. hc900_map_master: add controller_id
ALTER TABLE hc900_map_master
  ADD COLUMN IF NOT EXISTS controller_id TEXT NOT NULL DEFAULT 'HC1';

-- 6. v_tag_summary: recreate with controller_id
DROP VIEW IF EXISTS v_tag_summary CASCADE;
CREATE VIEW v_tag_summary AS
SELECT
  rt_base.base_tag,
  pv_rt.livevalue AS pv,
  sp_rt.livevalue AS sp,
  op_rt.livevalue AS op,
  instate0_rt.livevalue AS instate0,
  instate1_rt.livevalue AS instate1,
  instate2_rt.livevalue AS instate2,
  desc_md.value AS description,
  area_md.value AS area,
  sub_area_md.value AS sub_area,
  rt_base.controller_id
FROM (SELECT DISTINCT split_part(tagname, '.', 1) AS base_tag, controller_id FROM realtime_table) rt_base
LEFT JOIN realtime_table pv_rt ON pv_rt.tagname = rt_base.base_tag || '.pv' AND pv_rt.controller_id = rt_base.controller_id
LEFT JOIN realtime_table sp_rt ON sp_rt.tagname = rt_base.base_tag || '.sp' AND sp_rt.controller_id = rt_base.controller_id
LEFT JOIN realtime_table op_rt ON op_rt.tagname = rt_base.base_tag || '.op' AND op_rt.controller_id = rt_base.controller_id
LEFT JOIN realtime_table instate0_rt ON instate0_rt.tagname = rt_base.base_tag || '.instate0' AND instate0_rt.controller_id = rt_base.controller_id
LEFT JOIN realtime_table instate1_rt ON instate1_rt.tagname = rt_base.base_tag || '.instate1' AND instate1_rt.controller_id = rt_base.controller_id
LEFT JOIN realtime_table instate2_rt ON instate2_rt.tagname = rt_base.base_tag || '.instate2' AND instate2_rt.controller_id = rt_base.controller_id
LEFT JOIN tag_metadata desc_md ON desc_md.base_tag = rt_base.base_tag AND desc_md.attribute = 'desc'
LEFT JOIN tag_metadata area_md ON area_md.base_tag = rt_base.base_tag AND area_md.attribute = 'area'
LEFT JOIN tag_metadata sub_area_md ON sub_area_md.base_tag = rt_base.base_tag AND sub_area_md.attribute = 'sub_area';

-- 7. v_plant_running_state: recreate (depends on v_tag_summary)
DROP VIEW IF EXISTS v_plant_running_state;
CREATE VIEW v_plant_running_state AS
WITH pump_state AS (
    SELECT
        trim(split_part(area, '|', 2)) AS area_code,
        area AS area_raw,
        base_tag,
        pv,
        controller_id
    FROM v_tag_summary
    WHERE area IS NOT NULL
      AND (base_tag LIKE 'p-%' OR base_tag LIKE 'vp-%')
      AND pv ~ '\|\s*(L-RUN|R-RUN|L-STOP|R-STOP|L-TRIP|R-TRIP)\s*\|'
)
SELECT
    area_code,
    MAX(area_raw)                                              AS area_raw,
    COUNT(*)                                                   AS total_pumps,
    COUNT(*) FILTER (WHERE pv ~ '\|\s*[LR]-RUN\s*\|')          AS running_pumps,
    COUNT(*) FILTER (WHERE pv ~ '\|\s*[LR]-TRIP\s*\|')         AS tripped_pumps,
    COUNT(*) FILTER (WHERE pv ~ '\|\s*(L-STOP|R-STOP)\s*\|')   AS stopped_pumps,
    CASE
        WHEN COUNT(*) FILTER (WHERE pv ~ '\|\s*[LR]-RUN\s*\|') > 0 THEN 'RUNNING'
        WHEN COUNT(*) FILTER (WHERE pv ~ '\|\s*[LR]-TRIP\s*\|') > 0 THEN 'TRIPPED'
        ELSE 'STOPPED'
    END                                                        AS status,
    array_agg(base_tag) FILTER (WHERE pv ~ '\|\s*[LR]-RUN\s*\|') AS running_pump_tags
FROM pump_state
WHERE area_code IS NOT NULL AND area_code <> ''
GROUP BY area_code
ORDER BY area_code;

COMMIT;
