-- +goose Up
-- Apply legacy base staging data into new bases schema.

START TRANSACTION;

-- 1) Reuse existing base rows by normalized (base, abbreviation) when possible.
INSERT INTO base_old_id_map (old_id, new_id)
SELECT
  s.id AS old_id,
  b.id AS new_id
FROM bases_old_import s
JOIN bases b
  ON LOWER(TRIM(b.base)) = LOWER(TRIM(s.name))
 AND LOWER(TRIM(COALESCE(b.base_abbreviation, ''))) = LOWER(TRIM(COALESCE(s.code, '')))
LEFT JOIN base_old_id_map m ON m.old_id = s.id
WHERE m.old_id IS NULL;

-- 2) Generate IDs for remaining legacy bases.
INSERT INTO base_old_id_map (old_id, new_id)
SELECT
  s.id AS old_id,
  UNHEX(REPLACE(
    LOWER(CONCAT(
      LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
      '-',
      LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
      '-',
      '7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
      '-',
      LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
      '-',
      LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
    )),
    '-', ''
  )) AS new_id
FROM bases_old_import s
LEFT JOIN base_old_id_map m ON m.old_id = s.id
WHERE m.old_id IS NULL;

-- 3) Upsert base rows.
INSERT INTO bases (
  id,
  base,
  base_category_id,
  base_abbreviation,
  address,
  landline_number,
  mobile_number,
  email,
  sortkey,
  sms_alert,
  checklist,
  dry,
  control_center,
  dul,
  is_active,
  created_at,
  updated_at
)
SELECT
  m.new_id AS id,
  LEFT(TRIM(COALESCE(s.name, '')), 150) AS base,
  bc.id AS base_category_id,
  LEFT(TRIM(COALESCE(s.code, '')), 64) AS base_abbreviation,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS address,
  LEFT(TRIM(COALESCE(s.phone, '')), 64) AS landline_number,
  LEFT(TRIM(COALESCE(s.mobile, '')), 64) AS mobile_number,
  LEFT(TRIM(COALESCE(s.email, '')), 191) AS email,
  COALESCE(s.position, 0) AS sortkey,
  CASE WHEN COALESCE(s.sms_alert, 0) <> 0 THEN 1 ELSE 0 END AS sms_alert,
  CASE WHEN COALESCE(s.check_list, 0) <> 0 THEN 1 ELSE 0 END AS checklist,
  CASE WHEN COALESCE(s.dry, 0) <> 0 THEN 1 ELSE 0 END AS dry,
  CASE WHEN COALESCE(s.control_center, 0) <> 0 THEN 1 ELSE 0 END AS control_center,
  CASE WHEN COALESCE(s.service_transfer_list, 0) <> 0 THEN 1 ELSE 0 END AS dul,
  CASE WHEN COALESCE(s.visible, 0) <> 0 THEN 1 ELSE 0 END AS is_active,
  UTC_TIMESTAMP() AS created_at,
  UTC_TIMESTAMP() AS updated_at
FROM bases_old_import s
JOIN base_old_id_map m ON m.old_id = s.id
LEFT JOIN base_categories bc
  ON bc.`key` = CASE WHEN LOWER(TRIM(COALESCE(s.type, ''))) = 'hems' THEN 'hems' ELSE 'regular' END
ON DUPLICATE KEY UPDATE
  base = VALUES(base),
  base_category_id = VALUES(base_category_id),
  base_abbreviation = VALUES(base_abbreviation),
  address = VALUES(address),
  landline_number = VALUES(landline_number),
  mobile_number = VALUES(mobile_number),
  email = VALUES(email),
  sortkey = VALUES(sortkey),
  sms_alert = VALUES(sms_alert),
  checklist = VALUES(checklist),
  dry = VALUES(dry),
  control_center = VALUES(control_center),
  dul = VALUES(dul),
  is_active = VALUES(is_active),
  updated_at = UTC_TIMESTAMP();

-- 4) Build extracted legacy base-contact links from serialized fields.
DROP TEMPORARY TABLE IF EXISTS tmp_base_contact_extract;
CREATE TEMPORARY TABLE tmp_base_contact_extract (
  old_base_id int(11) NOT NULL,
  role_code varchar(64) NOT NULL,
  legacy_user_id int(11) NOT NULL,
  PRIMARY KEY (old_base_id, role_code, legacy_user_id)
) ENGINE=MEMORY;

INSERT IGNORE INTO tmp_base_contact_extract (old_base_id, role_code, legacy_user_id)
WITH RECURSIVE seq AS (
  SELECT 1 AS n
  UNION ALL
  SELECT n + 1 FROM seq WHERE n < 128
),
src AS (
  SELECT
    b.id AS old_base_id,
    'responsible_flight_rescuer' AS role_code,
    COALESCE(b.rescue_emails, '') AS serialized
  FROM bases_old_import b
  UNION ALL
  SELECT
    b.id AS old_base_id,
    'chief_physician_in_charge' AS role_code,
    COALESCE(b.doctor_emails, '') AS serialized
  FROM bases_old_import b
)
SELECT
  src.old_base_id,
  src.role_code,
  CAST(
    SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        REGEXP_SUBSTR(src.serialized, 's:[0-9]+:"[0-9]+"', 1, seq.n),
        '"',
        2
      ),
      '"',
      -1
    ) AS UNSIGNED
  ) AS legacy_user_id
FROM src
JOIN seq
  ON REGEXP_SUBSTR(src.serialized, 's:[0-9]+:"[0-9]+"', 1, seq.n) IS NOT NULL;

-- 5) Replace base_contact_roles for imported bases (targeted role codes only).
DELETE bcr
FROM base_contact_roles bcr
JOIN base_old_id_map bm ON bm.new_id = bcr.base_id
WHERE bcr.role_code IN ('responsible_flight_rescuer', 'chief_physician_in_charge');

-- 6) Insert deduplicated base_contact_roles by mapping legacy user IDs to new user IDs.
INSERT INTO base_contact_roles (
  id,
  base_id,
  contact_id,
  role_code,
  created_at,
  updated_at
)
SELECT
  UNHEX(REPLACE(
    LOWER(CONCAT(
      LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
      '-',
      LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
      '-',
      '7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
      '-',
      LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
      '-',
      LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
    )),
    '-', ''
  )) AS id,
  bm.new_id AS base_id,
  um.new_id AS contact_id,
  e.role_code AS role_code,
  UTC_TIMESTAMP() AS created_at,
  UTC_TIMESTAMP() AS updated_at
FROM (
  SELECT DISTINCT old_base_id, role_code, legacy_user_id
  FROM tmp_base_contact_extract
) e
JOIN base_old_id_map bm ON bm.old_id = e.old_base_id
JOIN user_old_id_map um ON um.old_id = e.legacy_user_id
;

DROP TEMPORARY TABLE IF EXISTS tmp_base_contact_extract;

COMMIT;

-- +goose Down
-- no-op rollback
