"""
    pip install faker
"""

import csv
import os
import random
import time
from faker import Faker

OUTPUT_DIR = "csv_output"

COUNTS = {
    "User":                   10_000_000,
    "Message":                10_000_000,
    "Notification":           10_000_000,
    "Mentorship":              1_000_000,
    "CommentOpinion":          1_000_000,
    "Chat":                    1_000_000,
    "University":                     10,
    "Faculty":                        60,
    "Permission":                     20,
    "Role":                           10,
    "UserAttribute":                  15,
    "MentorshipAttribute":            10,
    "Interest":                      100,
    "Subject":                       500,
    "StudyProgram":                  200,
    "MentorshipType":                 10,
    "User_Role":                 200_000,
    "Role_Permission":            50_000,
    "User_Subject":              500_000,
    "User_Interest":             500_000,
    "Subject_StudyProgram":       50_000,
    "TopicSuggestion":         2_000_000,
    "UserAttributeValue":        500_000,
    "Task":                    2_000_000,
    "MentorshipAttributeValue":  500_000,
    "Notification_Type":         500_000,
}

BATCH = 10_000

MK_MALE_NAMES = [
    "Александар", "Борис", "Васил", "Горан", "Дарко", "Ѓорѓи", "Емил",
    "Жарко", "Зоран", "Иван", "Јован", "Коста", "Лазар", "Марко", "Никола",
    "Огнен", "Петар", "Роберт", "Сашо", "Тони", "Филип", "Христо", "Методи",
    "Бошко", "Димитар", "Ѓоко", "Ненад", "Стефан", "Тодор", "Виктор",
    "Ацо", "Благоја", "Влатко", "Далибор", "Елвис", "Зафир", "Илија",
    "Јоце", "Кире", "Љупчо", "Митко", "Наум", "Оливер", "Предраг",
    "Радован", "Симон", "Трајко", "Урош", "Фросина", "Цветан", "Чедомир",
]

MK_FEMALE_NAMES = [
    "Александра", "Билјана", "Валентина", "Гордана", "Данела", "Ѓурѓица",
    "Елена", "Жаклина", "Зорица", "Ивана", "Јасмина", "Катерина", "Лидија",
    "Марија", "Наташа", "Оливера", "Петра", "Розита", "Сузана", "Тања",
    "Фламурта", "Христина", "Цвета", "Шекерие", "Ана", "Бојана",
    "Весна", "Дивна", "Емилија", "Зана", "Ирена", "Јованка", "Калина",
    "Лилјана", "Маја", "Нада", "Олга", "Пауна", "Радица", "Сања",
    "Теодора", "Ула", "Фатима", "Цеца", "Ангела", "Бисера", "Верица",
    "Даница", "Евица", "Загорка",
]

MK_MALE_SURNAMES = [
    "Петровски", "Јовановски", "Илиевски", "Димовски", "Стојановски",
    "Николовски", "Георгиевски", "Марковски", "Ангеловски", "Василевски",
    "Ристовски", "Христовски", "Тодоровски", "Поповски", "Коцевски",
    "Мицевски", "Трајковски", "Атанасовски", "Блажевски", "Велјановски",
    "Гелевски", "Дамјановски", "Ефтимовски", "Зафировски", "Иванов",
    "Јаковлевски", "Крстевски", "Лазаревски", "Манчевски", "Наумовски",
    "Огњановски", "Панчевски", "Радевски", "Симоновски", "Тасевски",
    "Урдаревски", "Филиповски", "Цветановски", "Шаќири", "Апостолски",
    "Бојаџиевски", "Велиновски", "Гулевски", "Дончевски", "Ѓоргиевски",
    "Жежовски", "Зивковски", "Икономовски", "Јанчевски", "Китановски",
]

MK_FEMALE_SURNAMES = [
    "Петровска", "Јовановска", "Илиевска", "Димовска", "Стојановска",
    "Николовска", "Георгиевска", "Марковска", "Ангеловска", "Василевска",
    "Ристовска", "Христовска", "Тодоровска", "Поповска", "Коцевска",
    "Мицевска", "Трајковска", "Атанасовска", "Блажевска", "Велјановска",
    "Гелевска", "Дамјановска", "Ефтимовска", "Зафировска", "Иванова",
    "Јаковлевска", "Крстевска", "Лазаревска", "Манчевска", "Наумовска",
    "Огњановска", "Панчевска", "Радевска", "Симоновска", "Тасевска",
    "Урдаревска", "Филиповска", "Цветановска", "Шаќири", "Апостолска",
    "Бојаџиевска", "Велиновска", "Гулевска", "Дончевска", "Ѓоргиевска",
    "Жежовска", "Зивковска", "Икономовска", "Јанчевска", "Китановска",
]

MK_UNIVERSITIES = [
    ("Универзитет Св. Кирил и Методиј", "Скопје", "02 3293 293", "проф. д-р Никола Јанкуловски"),
    ("Универзитет Св. Климент Охридски", "Битола", "047 223 788", "проф. д-р Сашо Коруноски"),
    ("Универзитет на Југоисточна Европа", "Тетово", "044 356 000", "проф. д-р Буњамин Јашари"),
    ("Државен Универзитет во Тетово", "Тетово", "044 334 222", "проф. д-р Вјоса Садику"),
    ("Универзитет Гоце Делчев", "Штип", "032 550 000", "проф. д-р Блажо Боев"),
    ("Европски Универзитет", "Скопје", "02 3075 570", "проф. д-р Наталија Долтчинска"),
    ("Меѓународен Балкански Универзитет", "Скопје", "02 3224 455", "проф. д-р Ериван Хасани"),
    ("Универзитет на Информатичките Науки и Технологии", "Охрид", "046 270 170", "проф. д-р Горан Јаќимовски"),
    ("МИТ Универзитет", "Скопје", "02 2408 920", "проф. д-р Петар Намичев"),
    ("Американски Универзитет на Европа", "Скопје", "02 2463 156", "проф. д-р Роберт Никодиновски"),
]

MK_FACULTIES = [
    # УКИМ — Скопје
    ("Факултет за информатички науки и компјутерско инженерство", "бул. Партизански одреди б.б., Скопје", "02 3099 066", "проф. д-р Сашо Гелев"),
    ("Природно-математички факултет", "бул. Гази Баба б.б., Скопје", "02 3249 900", "проф. д-р Зоран Десподов"),
    ("Електротехнички факултет", "бул. Гурчинов 18, Скопје", "02 3099 198", "проф. д-р Методија Атанасовски"),
    ("Машински факултет", "бул. Партизански одреди б.б., Скопје", "02 3099 260", "проф. д-р Атанасе Кочов"),
    ("Економски факултет", "бул. Крсте Мисирков б.б., Скопје", "02 3286 800", "проф. д-р Горан Петревски"),
    ("Правен факултет Јустинијан Први", "бул. Гоце Делчев б.б., Скопје", "02 3226 626", "проф. д-р Тодор Кошевалиски"),
    ("Медицински факултет", "бул. Мајка Тереза 17, Скопје", "02 3125 044", "проф. д-р Никола Камчев"),
    ("Филолошки факултет Блаже Конески", "бул. Гоце Делчев б.б., Скопје", "02 3227 701", "проф. д-р Елена Јованова-Грујовска"),
    ("Филозофски факултет", "бул. Крсте Мисирков 2, Скопје", "02 3116 520", "проф. д-р Барбара Саракинска"),
    ("Архитектонски факултет", "бул. Партизански одреди б.б., Скопје", "02 3099 270", "проф. д-р Мимоза Добрикова"),
    ("Градежен факултет", "бул. Партизански одреди б.б., Скопје", "02 3099 200", "проф. д-р Зоран Рецески"),
    ("Фармацевтски факултет", "Мајка Тереза 47, Скопје", "02 3126 032", "проф. д-р Марија Главаш Додов"),
    # УКЛО — Битола
    ("Технички факултет", "ул. Иво Лола Рибар б.б., Битола", "047 207 700", "проф. д-р Мишо Докузовски"),
    ("Економски факултет Прилеп", "ул. Горце Петров б.б., Прилеп", "048 426 655", "проф. д-р Трајко Мицески"),
    ("Факултет за туризам и угостителство", "ул. Маршал Тито б.б., Охрид", "046 262 147", "проф. д-р Лидија Симпсон"),
    ("Биотехнички факултет", "ул. Борки б.б., Битола", "047 203 600", "проф. д-р Душан Спасов"),
    ("Факултет за безбедност", "ул. Маршал Тито б.б., Битола", "047 237 011", "проф. д-р Никола Дујовски"),
    # УГД — Штип
    ("Факултет за информатика", "бул. Гоце Делчев б.б., Штип", "032 550 005", "проф. д-р Зоран Здравев"),
    ("Земјоделски факултет", "бул. Гоце Делчев б.б., Штип", "032 550 013", "проф. д-р Љупчо Михајловски"),
    ("Правен факултет", "бул. Гоце Делчев б.б., Штип", "032 550 018", "проф. д-р Јован Андоновски"),
    # ДУТ — Тетово
    ("Факултет за математички и природни науки", "ул. Илинден б.б., Тетово", "044 334 222", "проф. д-р Шефкет Арслани"),
    ("Факултет за економски науки", "ул. Илинден б.б., Тетово", "044 334 233", "проф. д-р Арбен Ислами"),
    # УЈИE — Тетово
    ("Факултет за современи науки и технологии", "ул. Илинден б.б., Тетово", "044 356 020", "проф. д-р Бесарт Рамадани"),
    ("Бизнис и економија", "ул. Илинден б.б., Тетово", "044 356 030", "проф. д-р Фатмир Азири"),
]

MK_STUDY_PROGRAMS = [
    "Компјутерски науки", "Информатика", "Компјутерско инженерство",
    "Електротехника и автоматика", "Телекомуникации",
    "Математика", "Физика", "Хемија", "Биологија",
    "Економија", "Финансии и сметководство", "Менаџмент", "Маркетинг",
    "Право", "Криминалистика", "Безбедност",
    "Медицина", "Стоматологија", "Фармација",
    "Градежништво", "Архитектура", "Машинство",
    "Туризам", "Угостителство",
    "Македонски јазик", "Англиски јазик", "Германски јазик", "Француски јазик",
    "Психологија", "Педагогија", "Социологија", "Философија",
    "Земјоделство", "Хортикултура",
    "Применета математика", "Статистика", "Актуарство",
    "Кибербезбедност", "Вештачка интелигенција", "Анализа на податоци",
]

MK_SUBJECTS = [
    "Математика 1", "Математика 2", "Математика 3",
    "Дискретна математика", "Линеарна алгебра", "Нумерички методи",
    "Веројатност и статистика", "Логика",
    "Вовед во програмирање", "Програмирање во Јава", "Програмирање во Пајтон",
    "Објектно-ориентирано програмирање", "Функционално програмирање",
    "Алгоритми и структури на податоци", "Напредни алгоритми",
    "Бази на податоци", "Напредни бази на податоци", "NoSQL бази",
    "Оперативни системи", "Компјутерски мрежи", "Дистрибуирани системи",
    "Компајлери", "Теорија на пресметување",
    "Вештачка интелигенција", "Машинско учење", "Длабоко учење",
    "Обработка на природен јазик", "Компјутерска визија",
    "Веб програмирање", "Мобилни апликации", "Развој на игри",
    "Кибербезбедност", "Криптографија", "Форензика",
    "Софтверско инженерство", "Тестирање на софтвер", "Agile методологии",
    "Анализа на податоци", "Визуелизација на податоци", "Big Data",
    "Облак пресметување", "IoT системи", "Вградени системи",
    "Електроника", "Дигитална електроника", "Електрични кола",
    "Телекомуникации", "Безжични мрежи", "Оптички влакна",
    "Микроконтролери", "Роботика", "Автоматско управување",
    "Економија", "Микроекономија", "Макроекономија",
    "Сметководство", "Финансиски менаџмент", "Банкарство",
    "Маркетинг", "Стратегиски менаџмент", "Бизнис планирање",
    "Право", "Граѓанско право", "Трговско право",
    "Медицина", "Анатомија", "Физиологија", "Патологија",
    "Фармакологија", "Биохемија", "Микробиологија",
    "Психологија", "Педагогија", "Социологија",
    "Математичка анализа", "Диференцијални равенки",
    "Физика 1", "Физика 2", "Термодинамика",
    "Хемија", "Органска хемија", "Аналитичка хемија",
    "Градежна механика", "Архитектонско проектирање",
    "Машинство", "Термотехника", "Хидраулика",
    "Туризам", "Туристичка географија", "Хотелски менаџмент",
    "Македонски јазик", "Англиски јазик", "Германски јазик",
    "Француски јазик", "Руски јазик", "Шпански јазик",
    "Историја на Македонија", "Политикологија",
]

MK_INTERESTS = [
    "Вештачка интелигенција", "Машинско учење", "Длабоко учење",
    "Веб развој", "Мобилен развој", "Игри", "Кибербезбедност",
    "Бази на податоци", "Big Data", "Облак пресметување",
    "IoT", "Роботика", "Блокчеин", "Криптографија",
    "Отворен код", "DevOps", "Microservices", "API dizajn",
    "Математика", "Статистика", "Теорија на графови",
    "Физика", "Хемија", "Биологија", "Медицина",
    "Право", "Економија", "Финансии", "Претприемаштво",
    "Маркетинг", "Продажба", "Брендирање",
    "Музика", "Сликарство", "Фотографија", "Видео",
    "Спорт", "Планинарење", "Патување", "Готвење",
    "Книги", "Филм", "Театар", "Танц",
    "Волонтирање", "Еколошки прашања", "Одржлив развој",
    "Јазици", "Превод", "Лингвистика",
    "Психологија", "Педагогија", "Социологија", "Философија",
    "Архитектура", "Урбанизам", "Дизајн", "UX/UI",
    "Историја", "Политика", "Меѓународни односи",
    "Биотехнологија", "Фармација", "Нанотехнологија",
    "Астрономија", "Метеорологија", "Геологија",
    "Земјоделство", "Хортикултура", "Ветерина",
    "Туризам", "Угостителство", "Авантура",
    "Фитнес", "Јога", "Медитација",
    "Шах", "Стратешки игри", "Е-спорт",
    "Хакатони", "Натпревари", "Олимпијади",
    "Научни истражувања", "Академско пишување", "Публикации",
    "Предавање", "Менторирање", "Студентски организации",
    "Стартапи", "Иновации", "Трансфер на технологии",
    "Дата новинарство", "Фект-чекинг", "Социјални медиуми",
    "Аниме", "Стрипови", "Научна фантастика",
    "Моделирање", "3D принтање", "Дронови",
    "Сигурност на мрежи", "Пенетрациско тестирање", "CTF натпревари",
    "Квантно пресметување", "Биоинформатика", "Геоинформатика",
    "Правна регулатива на AI", "Дигитална трансформација",
    "Финансиска технологија", "Криптовалути", "NFT",
    "Образование", "Е-учење", "Едукативен софтвер",
]

MK_MENTORSHIP_TYPES = [
    "Дипломска работа", "Магистерска теза", "Докторска дисертација",
    "Практична настава", "Истражувачки проект", "Научна статија",
    "Компаниска пракса", "Индустриски проект", "Семинарска работа",
    "Студентски проект",
]

MK_USER_ATTRIBUTES = [
    "Биографија", "Индекс", "Семестар", "Циклус", "Наслов",
    "Линкедин профил", "GitHub профил", "Личен веб сајт",
    "Дата на вработување", "Кабинет", "Работно искуство",
    "Јазици кои ги зборува", "Сертификати", "Публикации",
    "Истражувачки области",
]

MK_MENTORSHIP_ATTRIBUTES = [
    "Цел на менторство", "Очекуван резултат", "Седмичен ангажман",
    "Место на средби", "Главен предмет", "Дополнителни барања",
    "Буџет", "Компанија партнер", "Оценка на завршување",
    "Забелешки",
]

MK_PERMISSIONS = [
    "view_profile", "edit_profile", "delete_profile",
    "create_mentorship", "edit_mentorship", "delete_mentorship",
    "view_mentorship", "approve_request", "reject_request",
    "send_message", "delete_message", "view_comments",
    "post_comment", "delete_comment", "manage_users",
    "manage_roles", "manage_system", "view_reports",
    "export_data", "admin_panel",
]

MK_ROLES = [
    "Администратор", "Студент", "Ментор", "Модератор", "Гостин",
    "Супер Администратор", "Поддршка", "Прегледувач", "Уредник", "Менаџер",
]

MK_TOPIC_KEYWORDS = [
    "Анализа на", "Дизајн на", "Развој на", "Имплементација на",
    "Оптимизација на", "Компарација на", "Евалуација на", "Истражување на",
]

MK_TOPIC_SUBJECTS = [
    "систем за препораки", "алгоритам за машинско учење",
    "веб апликација", "мобилна апликација", "база на податоци",
    "мрежна безбедност", "блокчеин систем", "IoT платформа",
    "систем за автентикација", "алатка за визуелизација",
    "пребарувач", "chatbot", "систем за мониторирање",
    "платформа за е-учење", "апликација за здравство",
    "систем за управување со документи", "API gateway",
    "микросервисна архитектура", "систем за верификација",
    "платформа за менторство",
]

MK_CHAT_TOPICS = [
    "Консултација за дипломска", "Прашање за проект", "Договор за средба",
    "Повратна информација", "Следен чекор", "Техничко прашање",
    "Преглед на код", "Коментар за теза", "Пракса",
    "Истражување", "Подготовка за одбрана", "Корекции",
]

MK_CITIES = [
    "Скопје", "Битола", "Куманово", "Прилеп", "Тетово",
    "Велес", "Штип", "Охрид", "Гостивар", "Струmica",
    "Кичево", "Кавадарци", "Гевгелија", "Дебар", "Ресен",
]

# ──────────────────────────────────────────────
#  HELPERS
# ──────────────────────────────────────────────
fake = Faker()

def log(msg):
    print(f"[{time.strftime('%H:%M:%S')}] {msg}")

def dt():
    return fake.date_time_between('-2y', 'now').strftime('%Y-%m-%d %H:%M:%S')

def dt_past():
    return fake.date_time_between('-60y', '-5y').strftime('%Y-%m-%d %H:%M:%S')

def dt_future():
    return fake.date_time_between('now', '+2y').strftime('%Y-%m-%d %H:%M:%S')

def mk_name():
    if random.random() < 0.5:
        return random.choice(MK_MALE_NAMES), random.choice(MK_MALE_SURNAMES)
    else:
        return random.choice(MK_FEMALE_NAMES), random.choice(MK_FEMALE_SURNAMES)

def mk_username(name, surname, uid):
    n = name.lower().replace('ѓ','gj').replace('ќ','kj').replace('ж','zh')\
        .replace('ш','sh').replace('ч','ch').replace('џ','dz')\
        .replace('ц','c').replace('љ','lj').replace('њ','nj')\
        .replace('а','a').replace('б','b').replace('в','v')\
        .replace('г','g').replace('д','d').replace('е','e')\
        .replace('з','z').replace('и','i').replace('ј','j')\
        .replace('к','k').replace('л','l').replace('м','m')\
        .replace('н','n').replace('о','o').replace('п','p')\
        .replace('р','r').replace('с','s').replace('т','t')\
        .replace('у','u').replace('ф','f').replace('х','h')\
        .replace('ѕ','dz')
    s = surname.lower().replace('ѓ','gj').replace('ќ','kj').replace('ж','zh')\
        .replace('ш','sh').replace('ч','ch').replace('џ','dz')\
        .replace('ц','c').replace('љ','lj').replace('њ','nj')\
        .replace('а','a').replace('б','b').replace('в','v')\
        .replace('г','g').replace('д','d').replace('е','e')\
        .replace('з','z').replace('и','i').replace('ј','j')\
        .replace('к','k').replace('л','l').replace('м','m')\
        .replace('н','n').replace('о','o').replace('п','p')\
        .replace('р','r').replace('с','s').replace('т','t')\
        .replace('у','u').replace('ф','f').replace('х','h')\
        .replace('ѕ','dz')
    return f"{n}.{s}.{uid}"[:50]

def mk_email(username):
    domains = ["ukim.edu.mk", "uklo.edu.mk", "ugd.edu.mk", "unite.edu.mk",
               "seeu.edu.mk", "gmail.com", "yahoo.com", "outlook.com",
               "finki.ukim.mk", "tmf.ukim.mk"]
    return f"{username}@{random.choice(domains)}"

def mk_topic():
    kw = random.choice(MK_TOPIC_KEYWORDS)
    subj = random.choice(MK_TOPIC_SUBJECTS)
    return f"{kw} {subj}"

def mk_biography(role):
    if role == "mentor":
        titles = ["Редовен професор", "Вонреден професор", "Доцент", "Асистент", "Виш асистент"]
        t = random.choice(titles)
        areas = random.sample(MK_INTERESTS[:30], 2)
        return f"{t} на {random.choice(MK_FACULTIES)[0][:40]}. Истражувачки интереси: {areas[0]}, {areas[1]}."
    else:
        yr = random.randint(1, 4)
        prog = random.choice(MK_STUDY_PROGRAMS)
        return f"Студент на {yr} год. — {prog}. Заинтересиран за {random.choice(MK_INTERESTS[:40])}."

id_max = {}

def rand_id(table):
    return random.randint(1, id_max[table])

def write_table(filename, columns, row_gen, total):
    path = os.path.join(OUTPUT_DIR, filename)
    with open(path, 'w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(columns)
        done = 0
        while done < total:
            chunk = min(BATCH, total - done)
            writer.writerows(row_gen(done + 1, done + chunk))
            done += chunk
            print(f"  {done:,} / {total:,}", end='\r')
    print()
    table = filename.replace('.csv', '')
    id_max[table] = total
    log(f"  Saved → {path}")

# ──────────────────────────────────────────────
#  ROW GENERATORS
# ──────────────────────────────────────────────

def rows_university(id_start, id_end):
    rows = []
    pool = MK_UNIVERSITIES * ((id_end - id_start + 2) // len(MK_UNIVERSITIES) + 1)
    for i in range(id_start, id_end + 1):
        u = pool[i - 1]
        name, city, phone, rector = u
        addr = f"бул. {random.choice(['Гоце Делчев', 'Партизански одреди', 'Кирил и Методиј'])} б.б., {city}"
        rows.append((i, name, f"Државен универзитет во {city}.", dt_past(), addr, phone, rector))
    return rows

def rows_faculty(id_start, id_end):
    rows = []
    pool = MK_FACULTIES * ((id_end - id_start + 2) // len(MK_FACULTIES) + 1)
    for i in range(id_start, id_end + 1):
        f = pool[i - 1]
        fname, addr, phone, dean = f
        univ_id = random.randint(1, id_max['University'])
        rows.append((i, fname, f"Акредитиран факултет.", dt_past(), addr, phone, dean, univ_id))
    return rows

def rows_permission(id_start, id_end):
    pool = MK_PERMISSIONS
    return [(i, pool[(i - 1) % len(pool)]) for i in range(id_start, id_end + 1)]

def rows_role(id_start, id_end):
    return [(i, MK_ROLES[(i - 1) % len(MK_ROLES)]) for i in range(id_start, id_end + 1)]

def rows_user_attribute(id_start, id_end):
    pool = MK_USER_ATTRIBUTES
    return [(i, pool[(i - 1) % len(pool)]) for i in range(id_start, id_end + 1)]

def rows_mentorship_attribute(id_start, id_end):
    pool = MK_MENTORSHIP_ATTRIBUTES
    return [(i, pool[(i - 1) % len(pool)]) for i in range(id_start, id_end + 1)]

def rows_interest(id_start, id_end):
    pool = MK_INTERESTS * ((id_end - id_start + 2) // len(MK_INTERESTS) + 1)
    return [
        (i, pool[i - 1], f"Интерес поврзан со областа на {pool[i-1].lower()}.")
        for i in range(id_start, id_end + 1)
    ]

def rows_subject(id_start, id_end):
    pool = MK_SUBJECTS * ((id_end - id_start + 2) // len(MK_SUBJECTS) + 1)
    return [
        (i, pool[i - 1], f"Предмет кој ги опфаќа основите на {pool[i-1].lower()}.")
        for i in range(id_start, id_end + 1)
    ]

def rows_study_program(id_start, id_end):
    pool = MK_STUDY_PROGRAMS * ((id_end - id_start + 2) // len(MK_STUDY_PROGRAMS) + 1)
    return [
        (i, pool[i - 1], f"Студиска програма за {pool[i-1].lower()}.", rand_id('Faculty'))
        for i in range(id_start, id_end + 1)
    ]

def rows_mentorship_type(id_start, id_end):
    pool = MK_MENTORSHIP_TYPES
    return [
        (i, pool[(i - 1) % len(pool)], rand_id('MentorshipAttribute'))
        for i in range(id_start, id_end + 1)
    ]

def rows_user(id_start, id_end):
    rows = []
    for i in range(id_start, id_end + 1):
        name, surname = mk_name()
        uname = mk_username(name, surname, i)
        email = mk_email(uname)
        is_mentor = (i % 5 == 0)  # ~20% mentori
        bio = mk_biography("mentor" if is_mentor else "student")
        rows.append((
            i, uname, fake.sha256(), email,
            name, surname, bio,
            rand_id('Faculty')
        ))
    return rows

def rows_user_role(id_start, id_end):
    return [
        (i, rand_id('User'), rand_id('Role'))
        for i in range(id_start, id_end + 1)
    ]

def rows_role_permission(id_start, id_end):
    return [
        (i, rand_id('Role'), rand_id('Permission'))
        for i in range(id_start, id_end + 1)
    ]

def rows_user_subject(id_start, id_end):
    return [
        (i, rand_id('Subject'), rand_id('User'), random.randint(1, 8))
        for i in range(id_start, id_end + 1)
    ]

def rows_user_interest(id_start, id_end):
    return [
        (i, rand_id('User'), rand_id('Interest'))
        for i in range(id_start, id_end + 1)
    ]

def rows_subject_study_program(id_start, id_end):
    return [
        (i, rand_id('Subject'), rand_id('StudyProgram'))
        for i in range(id_start, id_end + 1)
    ]

def rows_topic_suggestion(id_start, id_end):
    return [
        (i, mk_topic(),
         f"Предлог тема за истражување и анализа во областа на {random.choice(MK_INTERESTS[:40]).lower()}.",
         dt(), random.choice([True, False]),
         rand_id('User'), rand_id('User'), rand_id('Subject'))
        for i in range(id_start, id_end + 1)
    ]

def rows_user_attribute_value(id_start, id_end):
    sample_values = [
        "2024/0001", "2023/0145", "2022/0312", "3", "4", "2", "1",
        "прв циклус", "втор циклус", "трет циклус",
        "linkedin.com/in/petar.petrovski", "github.com/petar",
        "Скопје", "Битола", "Охрид", "Тетово", "Штип",
    ]
    return [
        (i, random.choice(sample_values), rand_id('User'), rand_id('UserAttribute'))
        for i in range(id_start, id_end + 1)
    ]

def rows_mentorship(id_start, id_end):
    return [
        (i, rand_id('User'), rand_id('User'),
         rand_id('TopicSuggestion'), rand_id('MentorshipType'))
        for i in range(id_start, id_end + 1)
    ]

def rows_mentorship_attribute_value(id_start, id_end):
    sample_values = [
        "Секоја недела", "Двапати месечно", "По потреба",
        "Онлајн", "Во кабинет", "Хибридно",
        "3 месеци", "6 месеци", "1 година",
        "ФИНКИ", "Машински факултет", "Економски факултет",
    ]
    return [
        (i, random.choice(sample_values),
         rand_id('Mentorship'), rand_id('MentorshipAttribute'))
        for i in range(id_start, id_end + 1)
    ]

def rows_task(id_start, id_end):
    task_descriptions = [
        "Напиши прв нацрт на вовед", "Имплементирај го модулот за автентикација",
        "Подготви литературен преглед", "Постави база на податоци",
        "Напиши единечни тестови", "Изработи UML дијаграми",
        "Подготви презентација", "Направи истражување на корисници",
        "Пополни поглавје 2", "Испрати нацрт за преглед",
        "Поправи коментари од ментор", "Финализирај методологија",
        "Собери податоци за истражување", "Анализирај резултати",
        "Подготви заклучок",
    ]
    return [
        (i, dt_future(), dt(), random.randint(0, 3),
         random.choice(task_descriptions), rand_id('Mentorship'))
        for i in range(id_start, id_end + 1)
    ]

def rows_chat(id_start, id_end):
    return [
        (i, random.choice(MK_CHAT_TOPICS),
         f"Разговор за {random.choice(MK_MENTORSHIP_TYPES).lower()}",
         random.randint(0, 2), dt(),
         rand_id('User'), rand_id('User'))
        for i in range(id_start, id_end + 1)
    ]

def rows_message(id_start, id_end):
    messages_mk = [
        "Здраво, можеме ли да закажеме средба оваа недела?",
        "Ги прегледав вашите коментари и направив корекции.",
        "Имам прашање во врска со методологијата.",
        "Ве молам погледнете го последниот нацрт.",
        "Кога сте слободни за консултација?",
        "Ги завршив задачите за оваа недела.",
        "Можете ли да ми препорачате литература?",
        "Имам проблем со имплементацијата.",
        "Благодарам за вашите совети!",
        "Дали е добро вака или треба промени?",
        "Подготвен сум за следната фаза.",
        "Може ли да разговараме за оценувањето?",
        "Пратив го финалниот документ на мејл.",
        "Треба ли да додадам уште примери?",
        "Работам на поглавје 3, наскоро ќе пратам.",
    ]
    return [
        (i, random.choice(messages_mk), random.choice([True, False]),
         dt(), rand_id('Chat'), rand_id('User'))
        for i in range(id_start, id_end + 1)
    ]

def rows_comment_opinion(id_start, id_end):
    comments_mk = [
        "Одличен ментор, многу стручен и достапен.",
        "Многу помагаше во текот на целиот процес.",
        "Даваше јасни насоки и корисни совети.",
        "Понекогаш тешко достапен, но кога се сретневме беше корисно.",
        "Препорачувам го на сите студенти.",
        "Прекрасно менторство, научив многу.",
        "Беше флексибилен и разбирлив.",
        "Даваше конструктивна критика.",
        "Многу знае за областа, инспиративен.",
        "Добар ментор, само понекогаш доцни со повратна информација.",
    ]
    return [
        (i, random.choice(comments_mk), random.randint(1, 5),
         dt(), random.randint(0, 2),
         rand_id('User'), rand_id('User'))
        for i in range(id_start, id_end + 1)
    ]

def rows_notification(id_start, id_end):
    notifications_mk = [
        "Имате ново барање за контакт.",
        "Менторот го прифати вашето барање.",
        "Имате нова порака.",
        "Добивте нов коментар.",
        "Вашата задача е оценета.",
        "Новата тема е достапна.",
        "Терминот е потврден.",
        "Потсетување за претстојниот рок.",
        "Вашето мислење е прифатено.",
        "Системска нотификација.",
    ]
    return [
        (i, random.choice(notifications_mk), dt(),
         random.choice([True, False]),
         rand_id('User'),
         rand_id('CommentOpinion'),
         rand_id('Message'))
        for i in range(id_start, id_end + 1)
    ]

def rows_notification_type(id_start, id_end):
    types = ["информација", "предупредување", "тревога", "порака", "систем"]
    return [
        (i, random.choice(types), rand_id('Notification'))
        for i in range(id_start, id_end + 1)
    ]

# ──────────────────────────────────────────────
#  TABLE MANIFEST
# ──────────────────────────────────────────────
TABLES = [
    ("University.csv",            ["ID","Name","Description","DateFounded","Address","Contact","Rector"],                          rows_university),
    ("Faculty.csv",               ["ID","Name","Description","DateFounded","Address","Contact","Dean","UniversityID"],              rows_faculty),
    ("Permission.csv",            ["ID","PermissionName"],                                                                          rows_permission),
    ("Role.csv",                  ["ID","RoleName"],                                                                                rows_role),
    ("UserAttribute.csv",         ["ID","Name"],                                                                                    rows_user_attribute),
    ("MentorshipAttribute.csv",   ["ID","Name"],                                                                                    rows_mentorship_attribute),
    ("Interest.csv",              ["ID","Name","Description"],                                                                      rows_interest),
    ("Subject.csv",               ["ID","Name","Description"],                                                                      rows_subject),
    ("StudyProgram.csv",          ["ID","Name","Description","FacultyID"],                                                          rows_study_program),
    ("MentorshipType.csv",        ["ID","Type","MentorshipAttributeID"],                                                            rows_mentorship_type),
    ("User.csv",                  ["ID","Username","Password","Email","Name","Surname","Biography","FacultyID"],                    rows_user),
    ("User_Role.csv",             ["ID","UserID","RoleID"],                                                                         rows_user_role),
    ("Role_Permission.csv",       ["ID","RoleID","PermissionID"],                                                                   rows_role_permission),
    ("User_Subject.csv",          ["ID","SubjectID","UserID","Semester"],                                                           rows_user_subject),
    ("User_Interest.csv",         ["ID","UserID","InterestID"],                                                                     rows_user_interest),
    ("Subject_StudyProgram.csv",  ["ID","SubjectID","StudyProgramID"],                                                              rows_subject_study_program),
    ("TopicSuggestion.csv",       ["ID","Name","Description","Date","isAvailable","StudentID","MentorID","SubjectID"],              rows_topic_suggestion),
    ("UserAttributeValue.csv",    ["ID","Value","UserID","UserAttributeID"],                                                        rows_user_attribute_value),
    ("Mentorship.csv",            ["ID","StudentID","MentorID","TopicSuggestionID","MentorshipTypeID"],                             rows_mentorship),
    ("MentorshipAttributeValue.csv", ["ID","Value","MentorshipID","MentorshipAttributeID"],                                        rows_mentorship_attribute_value),
    ("Task.csv",                  ["ID","EndDate","StartDate","Status","Description","MentorshipID"],                               rows_task),
    ("Chat.csv",                  ["ID","Title","Topic","Status","Date","StudentID","MentorID"],                                    rows_chat),
    ("Message.csv",               ["ID","Content","isRead","Timestamp","ChatID","UserID"],                                          rows_message),
    ("CommentOpinion.csv",        ["ID","Comment","MentorRating","Timestamp","Status","StudentID","MentorID"],                      rows_comment_opinion),
    ("Notification.csv",          ["ID","Content","Timestamp","isRead","UserToNotifyID","CommentOpinionID","MessageID"],            rows_notification),
    ("Notification_Type.csv",     ["ID","Type","NotificationID"],                                                                   rows_notification_type),
]

# ──────────────────────────────────────────────
#  MAIN
# ──────────────────────────────────────────────
def main():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    log(f"Запишување CSV во: {os.path.abspath(OUTPUT_DIR)}/")
    log("Ова ќе потрае малку за поголемите табели — земи кафе.\n")

    for filename, columns, gen_fn in TABLES:
        table = filename.replace('.csv', '')
        n = COUNTS[table]
        log(f"Генерирање {n:,} редови → {filename}")
        write_table(filename, columns, gen_fn, n)

    log("\nГотово!")
    log("Увоз: COPY \"TableName\" FROM '/full/path/csv_output/TableName.csv' CSV HEADER;")

if __name__ == "__main__":
    t0 = time.time()
    main()
    log(f"Вкупно време: {(time.time() - t0) / 60:.1f} мин")
