-- Генерация целочисленного значения в диапазоне
CREATE OR REPLACE FUNCTION random_int (min_val int, max_val int)
    RETURNS int
    AS $$
BEGIN
    RETURN min_val + trunc(random() * (max_val - min_val + 1))::int;
END;
$$
LANGUAGE plpgsql
VOLATILE;

-- Генерация даты рождения в диапазоне
CREATE OR REPLACE FUNCTION random_date ()
    RETURNS date
    AS $$
DECLARE
    from_date date := '1950-01-01';
    to_date date := '2010-12-31';
BEGIN
    RETURN from_date + random_int (0, to_date - from_date);
END;
$$
LANGUAGE plpgsql
VOLATILE;

-- Генерация адреса проживания
CREATE OR REPLACE FUNCTION random_address (street text)
    RETURNS text
    AS $$
BEGIN
    RETURN street || ', дом ' || random_int (1, 40) || ', квартира ' || random_int (40, 120);
END;
$$
LANGUAGE plpgsql
VOLATILE;

-- --- Подготовленные общие данные ---
CREATE TEMP TABLE streets (
    street text
);

\copy streets FROM 'csv/streets.csv' (FORMAT csv);
-- --- Подготовленные данные для генерации мужских записей ---
CREATE TEMP TABLE male_last_names (
    last_name text
);

\copy male_last_names FROM 'csv/male_last_names.csv' (FORMAT csv);
CREATE TEMP TABLE male_first_names (
    first_name text
);

\copy male_first_names FROM 'csv/male_first_names.csv' (FORMAT csv);
CREATE TEMP TABLE male_middle_names (
    middle_name text
);

\copy male_middle_names FROM 'csv/male_middle_names.csv' (FORMAT csv);
-- Подготовленные данные для генерации женских записей
CREATE TEMP TABLE female_last_names (
    last_name text
);

\copy female_last_names FROM 'csv/female_last_names.csv' (FORMAT csv);
CREATE TEMP TABLE female_first_names (
    first_name text
);

\copy female_first_names FROM 'csv/female_first_names.csv' (FORMAT csv);
CREATE TEMP TABLE female_middle_names (
    middle_name text
);

\copy female_middle_names FROM 'csv/female_middle_names.csv' (FORMAT csv);
-- Генерация --
-- Удаление старых данных
TRUNCATE TABLE persons RESTART IDENTITY CASCADE;

-- Генерация записей
INSERT INTO persons (last_name, first_name, middle_name, birth_date, gender, address)
SELECT
    last_name,
    first_name,
    middle_name,
    random_date (),
    gender_enum,
    random_address (street)
FROM (
    -- Мужские записи
    SELECT
        ml.last_name,
        mf.first_name,
        mm.middle_name,
        'male'::gender_enum,
        s.street
    FROM
        male_last_names ml
    CROSS JOIN male_first_names mf
    CROSS JOIN male_middle_names mm
    CROSS JOIN streets s
UNION ALL
-- Женские записи
SELECT
    fl.last_name,
    ff.first_name,
    fm.middle_name,
    'female'::gender_enum,
    s.street
FROM
    female_last_names fl
    CROSS JOIN female_first_names ff
    CROSS JOIN female_middle_names fm
    CROSS JOIN streets s) all_people
ORDER BY
    random();

DROP TABLE IF EXISTS streets;

DROP TABLE IF EXISTS male_last_names;

DROP TABLE IF EXISTS male_first_names;

DROP TABLE IF EXISTS male_middle_names;

DROP TABLE IF EXISTS female_last_names;

DROP TABLE IF EXISTS female_first_names;

DROP TABLE IF EXISTS female_middle_names;

DROP FUNCTION IF EXISTS random_date ();

DROP FUNCTION IF EXISTS random_address (TEXT);

