# test_students_list_yaml.rb
require 'minitest/autorun'
require 'yaml'
require 'date'
require_relative '../students_list_yaml'
require_relative '../student'
require_relative '../student_short'

class TestStudentsListYAML < Minitest::Test
  TEMP_FILE = 'temp_students.yaml'

  def setup
    # Удаляем временный файл перед каждым тестом, если он существует
    File.delete(TEMP_FILE) if File.exist?(TEMP_FILE)
    @students_list = Students_list_YAML.new(TEMP_FILE)
    
    # Создаём несколько объектов Student для тестирования
    @student1 = Student.new(
      id: "1",
      git: "https://github.com/test1",
      surname: "Иванов",
      name: "Иван",
      patronymic: "Иванович",
      birth_date: Date.new(2000, 1, 1),
      phone: "+123456789",
      telegram: "@test1",
      email: "test1@example.com"
    )
    @student2 = Student.new(
      id: "2",
      git: "https://github.com/test2",
      surname: "Петров",
      name: "Пётр",
      patronymic: "Петрович",
      birth_date: Date.new(1999, 2, 2),
      phone: "+987654321",
      telegram: "@test2",
      email: "test2@example.com"
    )
    @student3 = Student.new(
      id: "3",
      git: "https://github.com/test3",
      surname: "Сидоров",
      name: "Сидор",
      patronymic: "Сидорович",
      birth_date: Date.new(1998, 3, 3),
      phone: "+192837465",
      telegram: "@test3",
      email: "test3@example.com"
    )
    
    # Добавляем студентов в список (при добавлении формируется новый ID)
    @students_list.add_student(@student1)
    @students_list.add_student(@student2)
    @students_list.add_student(@student3)
  end

  def teardown
    # Удаляем временный файл после выполнения тестов
    File.delete(TEMP_FILE) if File.exist?(TEMP_FILE)
  end

  def test_save_and_load_from_file
    # Сохраняем список в YAML-файл
    @students_list.save_to_file

    # Создаём новый объект, который загрузит данные из файла
    new_list = Students_list_YAML.new(TEMP_FILE)
    new_list.load_from_file

    # Проверяем, что количество студентов совпадает
    assert_equal @students_list.get_student_short_count, new_list.get_student_short_count

    # Проверяем, что фамилии и инициалы студентов совпадают
    original_names = @students_list.students.map(&:surname_initials).sort
    loaded_names   = new_list.students.map(&:surname_initials).sort
    assert_equal original_names, loaded_names
  end

  def test_get_student_by_id
    # Поиск студента по ID "1"
    student = @students_list.get_student_by_id("1")
    refute_nil student
    assert_equal "Иванов И.И.", student.surname_initials
  end

  def test_get_k_n_student_short_list
    # Получаем первую "страницу" из 2-х студентов
    data_list = @students_list.get_k_n_student_short_list(2, 1)
    # Ожидаем, что DataList содержит 2 записи
    assert_equal 2, data_list.get_data.rows_count

    # Проверяем, что столбец с Фамилией и инициалами содержит корректное значение
    first_row = data_list.get_data.item(0, 1)
    refute_nil first_row
    assert_match(/[А-ЯЁ][а-яё]+ [А-Я]\./, first_row)
  end

  def test_sort_students!
    # Перемешиваем порядок студентов и выполняем сортировку
    @students_list.students.shuffle!
    @students_list.sort_students!
    sorted_names = @students_list.students.map(&:surname_initials)
    # Проверяем, что список отсортирован лексикографически
    assert_equal sorted_names.sort, sorted_names
  end

  def test_add_student
    new_student = Student.new(
      id: "0", # ID будет перезаписан
      git: "https://github.com/test4",
      surname: "Алексеев",
      name: "Алексей",
      patronymic: "Алексеевич",
      birth_date: Date.new(2001, 4, 4),
      phone: "+111222333",
      telegram: "@test4",
      email: "test4@example.com"
    )
    added_student = @students_list.add_student(new_student)
    # Новый ID должен быть равен (максимальный существующий id + 1)
    expected_id = (@students_list.students.map { |s| s.id.to_i }.max).to_s
    assert_equal expected_id, added_student.id
    assert_equal 4, @students_list.get_student_short_count
  end

  def test_update_student_by_id
    updated_student = Student.new(
      id: "0", # ID будет перезаписан
      git: "https://github.com/updated",
      surname: "Обновлённый",
      name: "Студент",
      patronymic: "Тестович",
      birth_date: Date.new(2002, 5, 5),
      phone: "+444555666",
      telegram: "@updated",
      email: "updated@example.com"
    )
    # Обновляем студента с ID "2"
    result = @students_list.update_student_by_id("2", updated_student)
    assert result

    student = @students_list.get_student_by_id("2")
    refute_nil student
    assert_equal "Обновлённый С.Т.", student.surname_initials
    assert_equal "https://github.com/updated", student.git
  end

  def test_delete_student_by_id
    # Удаляем студента с ID "1"
    result = @students_list.delete_student_by_id("1")
    assert result

    # Проверяем, что студент с ID "1" отсутствует
    student = @students_list.get_student_by_id("1")
    assert_nil student

    # Количество студентов должно уменьшиться
    assert_equal 2, @students_list.get_student_short_count
  end

  def test_get_student_short_count
    assert_equal 3, @students_list.get_student_short_count
  end
end