-- Merge plants + warehouses into locations (type: plant | warehouse)

BEGIN;

CREATE TABLE IF NOT EXISTS locations (
  id          BIGSERIAL PRIMARY KEY,
  type        VARCHAR(20)  NOT NULL CHECK (type IN ('plant', 'warehouse')),
  code        VARCHAR(30)  NOT NULL,
  name        VARCHAR(150) NOT NULL,
  parent_id   BIGINT       REFERENCES locations(id),
  gstin       VARCHAR(15),
  address     TEXT,
  city        VARCHAR(100),
  state       VARCHAR(100),
  pincode     VARCHAR(10),
  phone       VARCHAR(15),
  location    VARCHAR(200),
  is_active   BOOLEAN      NOT NULL DEFAULT true,
  created_by  BIGINT,
  updated_by  BIGINT,
  created_at  TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  updated_at  TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
  deleted_at  TIMESTAMPTZ
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_locations_code_active
  ON locations (code)
  WHERE deleted_at IS NULL;

CREATE INDEX IF NOT EXISTS idx_locations_type ON locations (type);
CREATE INDEX IF NOT EXISTS idx_locations_parent_id ON locations (parent_id);

-- Migrate plants (preserve ids) when legacy table exists
DO $$
BEGIN
  IF EXISTS (
    SELECT 1 FROM information_schema.tables
    WHERE table_schema = 'public' AND table_name = 'plants'
  ) THEN
    INSERT INTO locations (
      id, type, code, name, gstin, address, city, state, pincode, phone,
      is_active, created_by, updated_by, created_at, updated_at, deleted_at
    )
    OVERRIDING SYSTEM VALUE
    SELECT
      id, 'plant', code, name, gstin, address, city, state, pincode, phone,
      is_active, created_by, updated_by, created_at, updated_at, deleted_at
    FROM plants
    ON CONFLICT (id) DO NOTHING;
  END IF;
END $$;

-- Migrate warehouses (preserve ids; plant_id -> parent_id)
DO $$
BEGIN
  IF EXISTS (
    SELECT 1 FROM information_schema.tables
    WHERE table_schema = 'public' AND table_name = 'warehouses'
  ) THEN
    INSERT INTO locations (
      id, type, code, name, parent_id, location,
      is_active, created_by, updated_by, created_at, updated_at, deleted_at
    )
    OVERRIDING SYSTEM VALUE
    SELECT
      id, 'warehouse', code, name, plant_id, location,
      is_active, created_by, updated_by, created_at, updated_at, deleted_at
    FROM warehouses
    ON CONFLICT (id) DO NOTHING;
  END IF;
END $$;

SELECT setval(
  pg_get_serial_sequence('locations', 'id'),
  GREATEST(COALESCE((SELECT MAX(id) FROM locations), 1), 1)
);

-- Drop FKs referencing plants / warehouses
DO $$
DECLARE r RECORD;
BEGIN
  IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'plants') THEN
    FOR r IN
      SELECT c.conname, c.conrelid::regclass AS tbl
      FROM pg_constraint c
      WHERE c.contype = 'f' AND c.confrelid = 'public.plants'::regclass
    LOOP
      EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname);
    END LOOP;
  END IF;

  IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'warehouses') THEN
    FOR r IN
      SELECT c.conname, c.conrelid::regclass AS tbl
      FROM pg_constraint c
      WHERE c.contype = 'f' AND c.confrelid = 'public.warehouses'::regclass
    LOOP
      EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %I', r.tbl, r.conname);
    END LOOP;
  END IF;
END $$;

-- Point existing FK columns to locations (idempotent)
DO $$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'users_plant_id_fkey') THEN
    ALTER TABLE users ADD CONSTRAINT users_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'assets_plant_id_fkey') THEN
    ALTER TABLE assets ADD CONSTRAINT assets_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'assets_warehouse_id_fkey') THEN
    ALTER TABLE assets ADD CONSTRAINT assets_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'purchase_orders_plant_id_fkey') THEN
    ALTER TABLE purchase_orders ADD CONSTRAINT purchase_orders_plant_id_fkey FOREIGN KEY (plant_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'purchase_orders_warehouse_id_fkey') THEN
    ALTER TABLE purchase_orders ADD CONSTRAINT purchase_orders_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'grn_warehouse_id_fkey') THEN
    ALTER TABLE grn ADD CONSTRAINT grn_warehouse_id_fkey FOREIGN KEY (warehouse_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_from_plant_id_fkey') THEN
    ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_from_plant_id_fkey FOREIGN KEY (from_plant_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_to_plant_id_fkey') THEN
    ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_to_plant_id_fkey FOREIGN KEY (to_plant_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_from_warehouse_id_fkey') THEN
    ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_from_warehouse_id_fkey FOREIGN KEY (from_warehouse_id) REFERENCES locations(id);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'asset_transfers_to_warehouse_id_fkey') THEN
    ALTER TABLE asset_transfers ADD CONSTRAINT asset_transfers_to_warehouse_id_fkey FOREIGN KEY (to_warehouse_id) REFERENCES locations(id);
  END IF;
END $$;

-- Drop views that depend on plants/warehouses, then drop legacy tables
DROP VIEW IF EXISTS v_purchase_orders CASCADE;
DROP VIEW IF EXISTS v_grn CASCADE;
DROP VIEW IF EXISTS v_assets CASCADE;
DROP VIEW IF EXISTS v_asset_expiry_alerts CASCADE;
DROP VIEW IF EXISTS v_asset_next_service CASCADE;

DROP TABLE IF EXISTS warehouses;
DROP TABLE IF EXISTS plants;

COMMIT;
