-- +goose Up
-- Apply legacy user staging data into new auth/contact schema.
-- Expected flow before this migration:
-- 1) Run previous migration that creates `user_old_import` and role map.
-- 2) Import old dump rows into `user_old_import`.
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
-- then upserts into `users`, `user_roles`, and role-specific profile tables.

START TRANSACTION;

-- 1) Reuse existing users by normalized email when possible.
INSERT INTO user_old_id_map (old_id, new_id)
SELECT
  s.id AS old_id,
  u.id AS new_id
FROM user_old_import s
JOIN users u
  ON LOWER(TRIM(u.email)) = LOWER(TRIM(s.email))
LEFT JOIN user_old_id_map m ON m.old_id = s.id
WHERE m.old_id IS NULL
  AND s.email IS NOT NULL
  AND TRIM(s.email) <> '';

-- 2) Generate IDs for remaining legacy users.
INSERT INTO user_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 user_old_import s
LEFT JOIN user_old_id_map m ON m.old_id = s.id
WHERE m.old_id IS NULL;

-- 3) Upsert core users.
INSERT INTO users (
  id,
  role_id,
  email,
  username,
  first_name,
  last_name,
  mobile_phone,
  timezone,
  is_active,
  password_hash,
  salt_value,
  email_verified_at,
  created_at,
  updated_at
)
SELECT
  m.new_id AS id,
  r.id AS role_id,
  CONCAT(
    COALESCE(
      NULLIF(LOWER(TRIM(SUBSTRING_INDEX(NULLIF(s.email, ''), '@', 1))), ''),
      CONCAT('legacy-user-', s.id)
    ),
    '+u', s.id,
    '@mybit-innovation'
  ) AS email,
  NULLIF(LEFT(TRIM(COALESCE(s.username, '')), 100), '') AS username,
  LEFT(SUBSTRING_INDEX(TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))), ' ', 1), 100) AS first_name,
  LEFT(
    COALESCE(
      NULLIF(
        TRIM(
          SUBSTRING(
            TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))),
            LENGTH(SUBSTRING_INDEX(TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))), ' ', 1)) + 1
          )
        ),
        ''
      ),
      '-'
    ),
    100
  ) AS last_name,
  LEFT(TRIM(COALESCE(s.mobile, s.phone, '')), 32) AS mobile_phone,
  'UTC' AS timezone,
  CASE WHEN COALESCE(s.visible, 1) = 1 THEN 1 ELSE 0 END AS is_active,
  NULL AS password_hash,
  NULL AS salt_value,
  NULL AS email_verified_at,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
LEFT JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
JOIN roles r ON r.code = COALESCE(lrm.role_code, 'staff')
ON DUPLICATE KEY UPDATE
  role_id = VALUES(role_id),
  username = VALUES(username),
  first_name = VALUES(first_name),
  last_name = VALUES(last_name),
  mobile_phone = VALUES(mobile_phone),
  timezone = VALUES(timezone),
  is_active = VALUES(is_active),
  password_hash = NULL,
  salt_value = NULL,
  email_verified_at = NULL,
  updated_at = UTC_TIMESTAMP();

-- 4) Ensure user_roles relation exists for mapped role.
INSERT INTO user_roles (
  id,
  user_id,
  role_id,
  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,
  m.new_id AS user_id,
  r.id AS role_id,
  UTC_TIMESTAMP() AS created_at,
  UTC_TIMESTAMP() AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
LEFT JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
JOIN roles r ON r.code = COALESCE(lrm.role_code, 'staff')
ON DUPLICATE KEY UPDATE
  updated_at = UTC_TIMESTAMP();

-- 5) Pilot profiles.
INSERT INTO pilot_profiles (
  user_id,
  pilot_category,
  short_name,
  license_no,
  technician_license_no,
  is_chief_pilot,
  total_flight_minutes,
  responsible_pilot_minutes,
  second_pilot_minutes,
  double_command_minutes,
  flight_instructor_minutes,
  night_flight_minutes,
  ifr_flight_minutes,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  COALESCE(NULLIF(lrm.pilot_category, ''), 'regular') AS pilot_category,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  LEFT(TRIM(COALESCE(s.license, '')), 120) AS license_no,
  LEFT(TRIM(COALESCE(s.techLicense, '')), 120) AS technician_license_no,
  COALESCE(lrm.is_chief_pilot, 0) AS is_chief_pilot,
  CASE WHEN TRIM(COALESCE(s.airport_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.airport_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.airport_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS total_flight_minutes,
  CASE WHEN TRIM(COALESCE(s.responsible_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.responsible_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.responsible_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS responsible_pilot_minutes,
  CASE WHEN TRIM(COALESCE(s.second_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.second_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.second_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS second_pilot_minutes,
  CASE WHEN TRIM(COALESCE(s.double_tax_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.double_tax_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.double_tax_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS double_command_minutes,
  CASE WHEN TRIM(COALESCE(s.flight_instructor_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.flight_instructor_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.flight_instructor_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS flight_instructor_minutes,
  CASE WHEN TRIM(COALESCE(s.night_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.night_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.night_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS night_flight_minutes,
  CASE WHEN TRIM(COALESCE(s.fir_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
    THEN CAST(SUBSTRING_INDEX(TRIM(s.fir_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.fir_pilot), ':', -1) AS UNSIGNED)
    ELSE 0 END AS ifr_flight_minutes,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'pilot'
ON DUPLICATE KEY UPDATE
  pilot_category = VALUES(pilot_category),
  short_name = VALUES(short_name),
  license_no = VALUES(license_no),
  technician_license_no = VALUES(technician_license_no),
  is_chief_pilot = VALUES(is_chief_pilot),
  total_flight_minutes = VALUES(total_flight_minutes),
  responsible_pilot_minutes = VALUES(responsible_pilot_minutes),
  second_pilot_minutes = VALUES(second_pilot_minutes),
  double_command_minutes = VALUES(double_command_minutes),
  flight_instructor_minutes = VALUES(flight_instructor_minutes),
  night_flight_minutes = VALUES(night_flight_minutes),
  ifr_flight_minutes = VALUES(ifr_flight_minutes),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

-- 6) Doctor profiles.
INSERT INTO doctor_profiles (
  user_id,
  short_name,
  medical_license_no,
  is_chief_physician,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  LEFT(TRIM(COALESCE(s.license, '')), 120) AS medical_license_no,
  COALESCE(lrm.is_chief_physician, 0) AS is_chief_physician,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'doctor'
ON DUPLICATE KEY UPDATE
  short_name = VALUES(short_name),
  medical_license_no = VALUES(medical_license_no),
  is_chief_physician = VALUES(is_chief_physician),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

-- 7) Air rescuer profiles.
INSERT INTO air_rescuer_profiles (
  user_id,
  short_name,
  is_chief_physician_in_charge,
  responsible_flight_rescuer,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  COALESCE(lrm.is_chief_physician_in_charge, 0) AS is_chief_physician_in_charge,
  0 AS responsible_flight_rescuer,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'air_rescuer'
ON DUPLICATE KEY UPDATE
  short_name = VALUES(short_name),
  is_chief_physician_in_charge = VALUES(is_chief_physician_in_charge),
  responsible_flight_rescuer = VALUES(responsible_flight_rescuer),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

-- 8) Technician profiles.
INSERT INTO technician_profiles (
  user_id,
  short_name,
  license_no,
  is_chief_technician,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  LEFT(TRIM(COALESCE(s.license, '')), 120) AS license_no,
  COALESCE(lrm.is_chief_technician, 0) AS is_chief_technician,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'technician'
ON DUPLICATE KEY UPDATE
  short_name = VALUES(short_name),
  license_no = VALUES(license_no),
  is_chief_technician = VALUES(is_chief_technician),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

-- 9) Flight assistant profiles.
INSERT INTO flight_assistant_profiles (
  user_id,
  short_name,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'flight_assistant'
ON DUPLICATE KEY UPDATE
  short_name = VALUES(short_name),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

-- 10) Staff profiles.
INSERT INTO staff_profiles (
  user_id,
  short_name,
  role_label,
  location,
  postcode,
  street_line,
  photo_file_id,
  created_at,
  updated_at
)
SELECT
  m.new_id AS user_id,
  LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
  LEFT(TRIM(COALESCE(lrm.staff_role_label, 'staff')), 120) AS role_label,
  LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
  LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
  LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
  LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
  COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
  COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
FROM user_old_import s
JOIN user_old_id_map m ON m.old_id = s.id
JOIN users u ON u.id = m.new_id
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
WHERE lrm.role_code = 'staff'
ON DUPLICATE KEY UPDATE
  short_name = VALUES(short_name),
  role_label = VALUES(role_label),
  location = VALUES(location),
  postcode = VALUES(postcode),
  street_line = VALUES(street_line),
  photo_file_id = VALUES(photo_file_id),
  updated_at = UTC_TIMESTAMP();

COMMIT;

-- +goose Down
-- Data migration is intentionally non-reversible.
-- Keep imported data and ID mapping as audit trail.
SELECT 1;
