create table if not exists eventhub.nation (
    numeric_code integer primary key,
    alpha_code text,
    name text not null,
    default_language_code text,
    is_known boolean not null default true,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now()
);

create unique index if not exists ux_eventhub_nation_alpha_code
    on eventhub.nation(alpha_code)
    where alpha_code is not null;

insert into eventhub.nation(numeric_code, alpha_code, name, default_language_code, is_known)
values
    (0, '0', 'Unknown 0', null, true),
    (1, 'A', 'Austria', 'de-AT', true),
    (2, 'AL', 'Albania', 'sq-AL', true),
    (3, 'AND', 'Andorra', 'ca', true),
    (4, 'ARM', 'Armenia', 'hy-AM', true),
    (5, 'AZ', 'Azerbaijan', 'az', true),
    (6, 'B', 'Belgium', null, true),
    (7, 'BG', 'Bulgaria', 'bg-BG', true),
    (8, 'BIH', 'Bosnia Herzegovina', null, true),
    (9, 'BY', 'Belarus', 'be-BY', true),
    (10, 'CH', 'Switzerland', 'de-CH', true),
    (11, 'CY', 'Cyprus', null, true),
    (12, 'CZ', 'Czech Republic', 'cs-CZ', true),
    (13, 'D', 'Germany', 'de-DE', true),
    (14, 'DK', 'Denmark', 'da-DK', true),
    (15, 'E', 'Spain', 'es-ES', true),
    (16, 'EST', 'Estonia', 'et-EE', true),
    (17, 'F', 'France', 'fr-FR', true),
    (18, 'FIN', 'Finland', 'fi-FI', true),
    (19, 'FL', 'Liechtenstein', 'de-LI', true),
    (20, 'FR', 'Faroe Islands', 'fo-FO', true),
    (21, 'UK', 'United Kingdom', 'en-GB', true),
    (22, 'GE', 'Georgia', 'ka-GE', true),
    (23, 'GR', 'Greece', 'el-GR', true),
    (24, 'H', 'Hungary', 'hu-HU', true),
    (25, 'HR', 'Croatia', 'hr-HR', true),
    (26, 'I', 'Italy', 'it-IT', true),
    (27, 'IRL', 'Ireland', 'en-IE', true),
    (28, 'IS', 'Iceland', 'is-IS', true),
    (29, 'KZ', 'Kazakhstan', 'kk-KZ', true),
    (30, 'L', 'Luxembourg', 'de-LU', true),
    (31, 'LT', 'Lithuania', 'lt-LT', true),
    (32, 'LV', 'Latvia', 'lv-LV', true),
    (33, 'M', 'Malta', null, true),
    (34, 'MC', 'Monaco', 'fr-MC', true),
    (35, 'MD', 'Moldova', 'ro', true),
    (36, 'MK', 'North Macedonia', 'mk-MK', true),
    (37, 'N', 'Norway', 'no', true),
    (38, 'NL', 'Netherlands', 'nl-NL', true),
    (39, 'P', 'Portugal', 'pt-PT', true),
    (40, 'PL', 'Poland', 'pl-PL', true),
    (41, 'RO', 'Romania', 'ro-RO', true),
    (42, 'RSM', 'San Marino', 'it-IT', true),
    (43, 'RUS', 'Russia', 'ru-RU', true),
    (44, 'S', 'Sweden', 'sv-SE', true),
    (45, 'SK', 'Slovakia', 'sk-SK', true),
    (46, 'SLO', 'Slovenia', 'sl-SI', true),
    (47, 'TM', 'Turkmenistan', null, true),
    (48, 'TR', 'Turkey', 'tr-TR', true),
    (49, 'UA', 'Ukraine', 'uk-UA', true),
    (50, 'V', 'Vatican City', 'it-IT', true),
    (51, 'YU', 'Yugoslavia', null, true),
    (52, 'MNE', 'Montenegro', null, true),
    (53, 'SRB', 'Serbia', null, true),
    (54, 'UZ', 'Uzbekistan', null, true),
    (55, 'TJ', 'Tajikistan', null, true),
    (253, 'EC', 'European Community', null, true),
    (254, 'EUR', 'Rest of Europe', null, true),
    (255, 'WLD', 'Rest of the world', null, true)
on conflict (numeric_code) do update set
    alpha_code = excluded.alpha_code,
    name = excluded.name,
    default_language_code = excluded.default_language_code,
    is_known = excluded.is_known,
    updated_at = now();

alter table eventhub.driver_card
    add column if not exists nation_numeric_code integer references eventhub.nation(numeric_code);

alter table eventhub.vehicle_registration
    add column if not exists nation_numeric_code integer references eventhub.nation(numeric_code);

create index if not exists idx_driver_card_numeric_key
    on eventhub.driver_card(nation_numeric_code, card_number)
    where nation_numeric_code is not null;

create index if not exists idx_vehicle_registration_numeric_key
    on eventhub.vehicle_registration(nation_numeric_code, registration_number)
    where nation_numeric_code is not null;

update eventhub.driver_card card
set nation_numeric_code = nation_ref.numeric_code
from eventhub.nation nation_ref
where card.nation_numeric_code is null
  and upper(card.nation) = upper(nation_ref.alpha_code);

update eventhub.driver_card card
set nation_numeric_code = cast(card.nation as integer)
where card.nation_numeric_code is null
  and trim(card.nation) ~ '^[0-9]+$';

update eventhub.driver_card card
set nation_numeric_code = cast(substring(card.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') as integer)
where card.nation_numeric_code is null
  and substring(card.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') is not null;

update eventhub.driver_card card
set nation = coalesce(nation_ref.alpha_code, 'Unknown ' || card.nation_numeric_code::text)
from eventhub.nation nation_ref
where card.nation_numeric_code is not null
  and nation_ref.numeric_code = card.nation_numeric_code
  and (
      trim(card.nation) ~ '^[0-9]+$'
      or substring(card.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') is not null
  );

update eventhub.vehicle_registration registration
set nation_numeric_code = nation_ref.numeric_code
from eventhub.nation nation_ref
where registration.nation_numeric_code is null
  and upper(registration.nation) = upper(nation_ref.alpha_code);

update eventhub.vehicle_registration registration
set nation_numeric_code = cast(registration.nation as integer)
where registration.nation_numeric_code is null
  and trim(registration.nation) ~ '^[0-9]+$';

update eventhub.vehicle_registration registration
set nation_numeric_code = cast(substring(registration.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') as integer)
where registration.nation_numeric_code is null
  and substring(registration.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') is not null;

update eventhub.vehicle_registration registration
set nation = coalesce(nation_ref.alpha_code, 'Unknown ' || registration.nation_numeric_code::text)
from eventhub.nation nation_ref
where registration.nation_numeric_code is not null
  and nation_ref.numeric_code = registration.nation_numeric_code
  and (
      trim(registration.nation) ~ '^[0-9]+$'
      or substring(registration.nation from '^[Uu]nknown[[:space:]]+([0-9]+)$') is not null
  );
