from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from functools import wraps
from sqlalchemy import ForeignKey, select, insert, update
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship
from typing import List
import time
import toml
import traceback

global db

class c:
	HEADER    = '\033[95m'
	OKBLUE    = '\033[94m'
	OKCYAN    = '\033[96m'
	OKGREEN   = '\033[92m'
	WARNING   = '\033[93m'
	FAIL      = '\033[91m'
	ENDC      = '\033[0m'
	BOLD      = '\033[1m'
	UNDERLINE = '\033[4m'
	ENDL      = '\n'

class baza():

	# global sportowcy, trofea, sportowcy_w_meczach, statystyki_sportowcow, kluby, mecze

	db = None
	entities = {}
	session = None
	app = None

	def __init__(self, app, config):
		self.app = app
		self.db = self.initDB(self.app, config)
		self.refresh_session()

	def __repr__(self):
		return f"<Obiekt bazodanowy baza ({len(self.entities)} encji)>"

	def initDB(self, app, config):
		global sportowcy, trofea, sportowcy_w_meczach, statystyki_sportowcow, kluby, mecze
		tnp = config['general']['db_prefix'] + "_lewangoalski_"

		class Base(DeclarativeBase):
			pass

		db = SQLAlchemy(app, model_class=Base)

		class sportowcy(Base):
			__tablename__ = tnp + "sportowcy"
			id_zawodnika:                   Mapped[                          int] = mapped_column(primary_key=True, autoincrement=True)
			zewnetrzne_id_zawodnika:        Mapped[                          str] = mapped_column(unique=True)
			imie:                           Mapped[                          str] = mapped_column()
			nazwisko:                       Mapped[                          str] = mapped_column()
			data_urodzenia:                 Mapped[                          str] = mapped_column()
			czy_aktywny:                    Mapped[                         bool] = mapped_column()
			klub_id:                        Mapped[                    List[str]] = mapped_column(ForeignKey(f"{tnp}kluby.id_klubu"), nullable=True)
			klub:                           Mapped[                List["kluby"]] =  relationship(back_populates="sportowcy_w_klubie", foreign_keys=[klub_id])
			narodowosc:                     Mapped[                          str] = mapped_column()
			ilosc_trofeow:                  Mapped[                          int] = mapped_column()
			ostatnie_trofeum_id:            Mapped[                          int] = mapped_column(ForeignKey(f"{tnp}trofea.id_trofeum"), nullable=True)
			ostatnie_trofeum:               Mapped[                     "trofea"] =  relationship(back_populates="zawodnik", foreign_keys=[ostatnie_trofeum_id])
			pierwszy_mecz_id:               Mapped[                          int] = mapped_column(ForeignKey(f"{tnp}mecze.id_meczu"), nullable=True)
			pierwszy_mecz:                  Mapped[                      "mecze"] =  relationship()
			wycena:                         Mapped[                          int] = mapped_column()
			ostatni_gol_dla_id:             Mapped[                          str] = mapped_column(ForeignKey(f"{tnp}kluby.id_klubu"), nullable=True)
			ostatni_gol_dla:                Mapped[                      "kluby"] =  relationship(back_populates="sportowcy_ostatni_gol", foreign_keys=[ostatni_gol_dla_id])
			statystyki_id:                  Mapped[                    List[int]] = mapped_column(ForeignKey(f"{tnp}statystyki_sportowcow.id_statystyki"), nullable=True)
			statystyki:                     Mapped[List["statystyki_sportowcow"]] =  relationship(back_populates="sportowiec")
			trofea:                         Mapped[               List["trofea"]] =  relationship(back_populates="zawodnik", foreign_keys="[trofea.id_zawodnika]")
			mecze_zawodnika:                Mapped[  List["sportowcy_w_meczach"]] =  relationship(back_populates="zawodnik")

			def __repr__(self):
				return f"<Sportowiec #{self.id_zawodnika} ({self.imie} {self.nazwisko})>"

		# Co było pierwsze, jajko czy kura? https://docs.sqlalchemy.org/en/20/orm/relationship_persistence.html#rows-that-point-to-themselves-mutually-dependent-rows
		# Kiepskie rozwiązanie, ale jednak działające: pozwolić obcym kluczom na bycie "null"
		class trofea(Base):
			__tablename__ = tnp + "trofea"
			id_trofeum:                     Mapped[                          int] = mapped_column(primary_key=True, autoincrement=True)
			id_zawodnika:                   Mapped[                          int] = mapped_column(ForeignKey(f"{tnp}sportowcy.id_zawodnika", name="fk_zawodnik"), nullable=True)
			zawodnik:                       Mapped[                  "sportowcy"] =  relationship(back_populates="trofea", foreign_keys=[id_zawodnika], post_update=True)
			nazwa:                          Mapped[                          str] = mapped_column()
			sezon:                          Mapped[                          str] = mapped_column()
			rok:                            Mapped[                          int] = mapped_column()

			def __repr__(self):
				return f"<Trofeum #{self.id_trofeum} ({self.nazwa})>"

		class sportowcy_w_meczach(Base):
			__tablename__ = tnp + "sportowcy_w_meczach"
			id_rekordu:                     Mapped[                          int] = mapped_column(primary_key=True, autoincrement=True)
			id_zawodnika:                   Mapped[                          int] = mapped_column(ForeignKey(f"{tnp}sportowcy.id_zawodnika"))
			zawodnik:                       Mapped[                  "sportowcy"] =  relationship(back_populates="mecze_zawodnika")
			zewnetrzne_id_meczu:            Mapped[                          str] = mapped_column(ForeignKey(f"{tnp}mecze.zewnetrzne_id_meczu"))
			mecz:                           Mapped[                      "mecze"] =  relationship()
			czas_gry:                       Mapped[                          int] = mapped_column()
			goli:                           Mapped[                          int] = mapped_column()
			asyst:                          Mapped[                          int] = mapped_column()
			interwencje_bramkarza:          Mapped[                          int] = mapped_column()
			suma_interwencji_na_bramke:     Mapped[                          int] = mapped_column()
			zolte_kartki:                   Mapped[                          int] = mapped_column()
			czerwone_kartki:                Mapped[                          int] = mapped_column()
			wygrana:                        Mapped[                          int] = mapped_column()
			wynik:                          Mapped[                        float] = mapped_column()

			def __repr__(self):
				return f"<{self.zawodnik.imie} {self.zawodnik.nazwisko} w meczu {self.mecz.gospodarze.skrocona_nazwa} vs. {self.mecz.goscie.skrocona_nazwa}>"

		class statystyki_sportowcow(Base):
			__tablename__ = tnp + "statystyki_sportowcow"
			id_statystyki:                  Mapped[                          int] = mapped_column(primary_key=True, autoincrement=True)
			sportowiec:                     Mapped[                  "sportowcy"] =  relationship(back_populates="statystyki")
			ostatni_mecz:                   Mapped[                          int] = mapped_column(ForeignKey(f"{tnp}mecze.id_meczu"))
			ilosc_wystapien:                Mapped[                          int] = mapped_column()
			minut_gry:                      Mapped[                          int] = mapped_column()
			gier_sum:                       Mapped[                          int] = mapped_column()
			goli_sum:                       Mapped[                          int] = mapped_column()
			asyst_sum:                      Mapped[                          int] = mapped_column()
			interwencji_sum:                Mapped[                          int] = mapped_column()
			nieobronionych_interwencji_sum: Mapped[                          int] = mapped_column()
			zoltych_kartek_sum:             Mapped[                          int] = mapped_column()
			czerwonych_kartek_sum:          Mapped[                          int] = mapped_column()
			wygranych_sum:                  Mapped[                          int] = mapped_column()
			przegranych_sum:                Mapped[                          int] = mapped_column()
			remisow_sum:                    Mapped[                          int] = mapped_column()
			wynik_sum:                      Mapped[                          int] = mapped_column()
			meczow_do_wynikow_sum:          Mapped[                          int] = mapped_column()

			def __repr__(self):
				return f"<Statystyka #{self.id_statystyki} ({self.sportowiec.imie} {self.sportowiec.nazwisko})>"

		class kluby(Base):
			__tablename__ = tnp + "kluby"
			id_klubu:                       Mapped[                          str] = mapped_column(primary_key=True)
			pelna_nazwa:                    Mapped[                          str] = mapped_column()
			skrocona_nazwa:                 Mapped[                          str] = mapped_column()
			sportowcy_w_klubie:             Mapped[            List["sportowcy"]] =  relationship(back_populates="klub", foreign_keys="[sportowcy.klub_id]")
			sportowcy_ostatni_gol:          Mapped[                  "sportowcy"] =  relationship(back_populates="ostatni_gol_dla", foreign_keys="[sportowcy.ostatni_gol_dla_id]")

			def __repr__(self):
				return f"<Klub #{self.id_klubu} ({self.skrocona_nazwa})>"

		class mecze(Base):
			__tablename__ = tnp + "mecze"
			id_meczu:                       Mapped[                          int] = mapped_column(primary_key=True, autoincrement=True)
			zewnetrzne_id_meczu:            Mapped[                          str] = mapped_column(unique=True)
			data:                           Mapped[                     datetime] = mapped_column()
			gospodarze_id:                  Mapped[                          str] = mapped_column(ForeignKey(f"{tnp}kluby.id_klubu"))
			gospodarze:                     Mapped[                      "kluby"] =  relationship(foreign_keys=[gospodarze_id])
			goscie_id:                      Mapped[                          str] = mapped_column(ForeignKey(f"{tnp}kluby.id_klubu"))
			goscie:                         Mapped[                      "kluby"] =  relationship(foreign_keys=[goscie_id])
			gosp_wynik:                     Mapped[                          int] = mapped_column()
			gosc_wynik:                     Mapped[                          int] = mapped_column()
			sezon:                          Mapped[                          str] = mapped_column()
			nazwa_turnieju:                 Mapped[                          str] = mapped_column()
			skrocona_nazwa_turnieju:        Mapped[                          str] = mapped_column()
			flaga:                          Mapped[                          int] = mapped_column()

			def __repr__(self):
				return f"<Mecz #{self.id_meczu} ({self.zewnetrzne_id_meczu}, {self.gospodarze.skrocona_nazwa} vs. {self.goscie.skrocona_nazwa})>"

			def jsonify(self):
				return {
					"id_meczu": self.id_meczu,
					"zewnetrzne_id_meczu": self.zewnetrzne_id_meczu,
					"data": self.data.strftime("%Y-%m-%d"),
					"gospodarze_id": self.gospodarze_id,
					"gospodarze": self.gospodarze.skrocona_nazwa,
					"goscie_id": self.goscie_id,
					"goscie": self.goscie.skrocona_nazwa,
					"gosp_wynik": self.gosp_wynik,
					"gosc_wynik": self.gosc_wynik,
					"sezon": self.sezon,
					"nazwa_turnieju": self.nazwa_turnieju,
					"skrocona_nazwa_turnieju": self.skrocona_nazwa_turnieju,
					"flaga": self.flaga
				}

		self.entities = {
			'sportowcy': sportowcy,
			'trofea': trofea,
			'sportowcy_w_meczach': sportowcy_w_meczach,
			'statystyki_sportowcow': statystyki_sportowcow,
			'kluby': kluby,
			'mecze': mecze
		}

		return db

	def create_all(self):
		self.db.create_all()

	def refresh_session(self):
		with self.app.app_context():
			self.session = Session(self.db.engine)

	def exit_gracefully(func):
		@wraps(func)
		def wrapper(self, *args, **kwargs):
			return_val = None
			try:
				return_val = func(self, *args, **kwargs)
			except:
				print(f"{c.FAIL}"
					  f"Wystąpił błąd podczas wykonywania zapytania SQL:"
					  f"{c.ENDC}"
					   "\n"
					  f"{traceback.format_exc()}")
				self.session.rollback()
				self.session.close()
				self.refresh_session()
			return return_val
		return wrapper

	def str_to_column(self, string: str):
		"""
		Zamienia tekstowy zapis "tabela.kolumna"
		na obiekt modelu bazy (ze zmiennej self.entities).
		Zwraca None jeśli takowego nie znajdzie.
		Zamiennik dla niepożądanego eval().

		:param      string:  Zapis tekstowy
		:type       string:  str
		"""
		try:
			table_str, column_str = string.split('.')
		except:
			raise ValueError("Nieprawidłowe dane - podaj zarówno tabelę, jak i kolumnę, np.: \"kluby.id_klubu\".")
		if hasattr(self.entities[table_str], column_str):
			return getattr(self.entities[table_str], column_str)
		return None

	@exit_gracefully
	def simple_select_all(self, entity_type, **kwargs):
		"""
		Użycie:
		simple_select_all(ldb.sportowcy, zewnetrzne_id_zawodnika="MVC8zHZD")
		simple_select_all("sportowcy", id_zawodnika=1)
		simple_select_all("kluby", ..., LIMIT=5, ORDER_BY="kluby.skrocona_nazwa")

		https://stackoverflow.com/a/75316945
		Did they make it harder to query dynamically on purpose? ~Frank 19.11.2023
		"""

		if not isinstance(entity_type, str):
			entity_type = entity_type.__name__

		query_params, special_args = self.extract_special_args(kwargs)

		print(f"[{round(time.time())}] SELECT {entity_type}")

		results = (
			self.session.
			query(self.entities[entity_type]).
			filter_by(**query_params)
		)

		# Obsługuje "ORDER_BY", "LIMIT", itp. itd.
		results = self.manipulate_results(results, special_args)

		results_objs = results.all()
		print(f"[{round(time.time())}] SELECT RESULTS: {results_objs}")

		return results_objs

	def extract_special_args(self, dictionary: dict):
		"""
		Zwraca krotkę składającą się ze słowników z:
		- parametrami wyszukiwania
		- specjalnymi argumentami
		
		:param      dictionary:  Słownik wejściowy
		:type       dictionary:  dict
		"""

		# Save special arguments received with kwargs,
		# that are meant for SQL operations to special_args,
		# and delete from the rest, that will be passed
		# directly to filter_by().
		# They will not be passed as search query, but serve
		# as an additional search parameter.
		dictionary = dictionary.copy()

		special_keywords = ("ORDER_BY", "ORDER_BY_DESC", "LIMIT")
		special_args     = {}

		for arg in special_keywords:
			if arg in dictionary:
				special_args[arg] = dictionary[arg]
				del dictionary[arg]

		return dictionary, special_args

	def manipulate_results(self, results, special_args: dict):
		"""
		Wykonuje specjalne operacje na rezultatach wyszukiwania.
		
		:param      results:       Wyniki wyszukiwania (ORM)
		:param      special_args:  Specjalne operacje
		:type       special_args:  dict
		"""

		if "ORDER_BY" in special_args:
			column = self.str_to_column(special_args["ORDER_BY"])
			if column is not None:
				results = results.order_by(column)

		if "ORDER_BY_DESC" in special_args:
			column = self.str_to_column(special_args["ORDER_BY_DESC"])
			if column is not None:
				results = results.order_by(column.desc())

		if "LIMIT" in special_args:
			results = results.limit(special_args["LIMIT"])

		return results

	@exit_gracefully
	def simple_insert_one(self, entity_type, **kwargs):
		"""
		Użycie:
		simple_insert_one(ldb.kluby, id_klubu="polska", pelna_nazwa="Reprezentacja Polski", skrocona_nazwa="PL")

		https://docs.sqlalchemy.org/en/20/tutorial/data_insert.html
		https://docs.sqlalchemy.org/en/20/orm/session_basics.html
		"""

		if not isinstance(entity_type, str):
			entity_type = entity_type.__name__

		if "id" in kwargs:
			print(f"{c.FAIL}UWAGA!{c.ENDC}")
			print(f"Próbujesz dodać obiekt do tabeli, który ma już identyfikator.\n"
				  f"To spowoduje problemy w przyszłości, gdy będziesz chciał dodać nowy obiekt do bazy bez ustawiania id na sztywno\n"
				  f"(id klucza głównego nie zostanie zaktualizowane w sekwencji, przez co baza będzie próbowała dodać obiekt z id już istniejącego rekordu!).\n"
				  f"Aby naprawić dodawanie z autoinkrementującym kluczem zobacz {c.WARNING}https://stackoverflow.com/a/8745101{c.ENDC}\n"
				  f"Zostałeś ostrzeżony!")

		print(f"[{round(time.time())}] INSERT {entity_type}")

		obj = self.entities[entity_type](**kwargs)
		#with Session(self.db.engine) as session:
		self.session.add(obj)
		self.session.commit()
		return 0
		#return 1

	@exit_gracefully
	def simple_insert_many(self, objs_list):
		"""
		Użycie:
		simple_insert_many([sportowiec_a, sportowiec_b])

		https://docs.sqlalchemy.org/en/20/tutorial/data_insert.html
		https://docs.sqlalchemy.org/en/20/orm/session_basics.html
		"""
		#with Session(self.db.engine) as session:
		self.session.add_all(objs_list)
		self.session.commit()
		return 0
		#return 1

	@exit_gracefully
	def increment_fields(self, entity_type, record_id, **increments):
		"""
		Dodaje wartości do istniejących pól (np. goli_sum += 2).
    
		Użycie:
		increment_fields(ldb.statystyki_sportowcow, 123, goli_sum=2, asyst_sum=1)
		"""

		if not isinstance(entity_type, str):
			entity_type = entity_type.__name__

		if entity_type not in self.entities:
			print(f"Nieznany typ encji: {entity_type}")
			return -1

		model_class = self.entities[entity_type]

		print(f"[{round(time.time())}] INCREMENT {entity_type}")

		record = self.session.get(model_class, record_id)
		if not record:
			print(f"Rekord z ID {record_id} nie istnieje w tabeli {entity_type}")
			return -1

		for key, increment_value in increments.items():
			if hasattr(record, key):
				current_value = getattr(record, key, 0)
				setattr(record, key, current_value + increment_value)
			else:
				print(f"⚠️  Pole '{key}' nie istnieje w modelu '{entity_type}' - pomijam.")

		self.session.commit()
		return 0

	@exit_gracefully
	def get_id_meczu_by_zewnetrzne_id(self, external_id: str) -> int | None:
		"""
		Zwraca id_meczu na podstawie zewnetrzne_id_meczu.

		:param external_id: zewnętrzne ID meczu
		:return: id_meczu lub None jeśli nie znaleziono
		"""
		stmt = select(mecze.id_meczu).where(mecze.zewnetrzne_id_meczu == external_id)
		result = self.session.execute(stmt).scalar_one_or_none()
		return result

	@exit_gracefully
	def get_id_zawodnika_by_zewnetrzne_id(self, external_id: str) -> int | None:
		"""
		Zwraca id_zawodnika na podstawie zewnetrzne_id_zawodnika.

		:param external_id: zewnętrzne ID meczu
		:return: id_zawodnika lub None jeśli nie znaleziono
		"""
		stmt = select(sportowcy.id_zawodnika).where(sportowcy.zewnetrzne_id_zawodnika == external_id)
		result = self.session.execute(stmt).scalar_one_or_none()
		return result

	@exit_gracefully
	def simple_update_one(self, entity_type, record_id, **kwargs):
		"""
		Użycie:
		simple_update_one(ldb.kluby, "polska", pelna_nazwa="Nowa Nazwa", skrocona_nazwa="NN")

		Aktualizuje pojedynczy rekord w bazie danych na podstawie ID.
		"""
		if not isinstance(entity_type, str):
			entity_type = entity_type.__name__

		if entity_type not in self.entities:
			print(f"Nieznany typ encji: {entity_type}")
			return -1

		model_class = self.entities[entity_type]

		print(f"[{round(time.time())}] UPDATE {entity_type}")

		record = self.session.get(model_class, record_id)
		if not record:
			print(f"Rekord z ID {record_id} nie istnieje w tabeli {entity_type}")
			return -1

		for key, value in kwargs.items():
			if hasattr(record, key):
				setattr(record, key, value)
			else:
				print(f"⚠️  Pole '{key}' nie istnieje w modelu '{entity_type}' - pomijam.")
    
		self.session.commit()
		return 0

	@exit_gracefully
	def dodaj_sportowca_w_meczu(self, entity_type, record_id, **kwargs):
		"""
		Użycie:
		dodaj_sportowca_w_meczu(ldb.sportowcy_w_meczu, ...)

		Dodaje pojedynczy rekord w bazie danych.
		"""
		if not isinstance(entity_type, str):
			entity_type = entity_type.__name__

		if entity_type not in self.entities:
			print(f"Nieznany typ encji: {entity_type}")
			return -1

		model_class = self.entities[entity_type]

		print(f"[{round(time.time())}] INSERT {entity_type}")

		record = self.session.get(model_class, record_id)
		if not record:
			print(f"Rekord z ID {record_id} nie istnieje w tabeli {entity_type}")
			return -1

		for key, value in kwargs.items():
			if hasattr(record, key):
				setattr(record, key, value)
			else:
				print(f"⚠️  Pole '{key}' nie istnieje w modelu '{entity_type}' - pomijam.")
    
		self.session.commit()
		return 0

	@exit_gracefully
	def get_sportowcy_w_meczach_by_sportsman_id(self, id_zawodnika = None, zewnetrzne_id_zawodnika = None, order = "DESC"):

		if zewnetrzne_id_zawodnika is not None:
			id_zawodnika = self.get_id_zawodnika_by_zewnetrzne_id(zewnetrzne_id_zawodnika)

		query = self.session.query(
				self.entities["sportowcy_w_meczach"]
			).join(
				self.entities["sportowcy_w_meczach"].zawodnik
			).filter(
				self.entities["sportowcy"].id_zawodnika == id_zawodnika
			)

		#print(query)

		if order.lower() == "desc":
			query = query.order_by(self.entities["sportowcy_w_meczach"].id_rekordu.desc())

		return query.all()

	@exit_gracefully
	def sample_data_init(self, override_safety_check=False):
		"""
		Użycie:
		sample_data_init()
		Uwaga! Poniższe populuje pustą bazę danych.
		Nie należy tego używać na nie-pustej bazie, ponieważ spowoduje
		to wpisanie śmieciowych danych!
		Jeżeli wiesz co robisz w takiej sytuacji, uruchom metodę z:
		sample_data_init(override_safety_check=True)
		Metoda głównie używana do testów.
		"""
		is_table_empty = False
		try:
			self.simple_select_all(self.sportowcy, zewnetrzne_id_zawodnika="MVC8zHZD")
		except:
			is_table_empty = True

		if not is_table_empty and override_safety_check:
			raise EnvironmentError("sample_data_init() ran on a non-empty database. Ignore with override_safety_check=True.")

		with Session(self.db.engine) as session:
			self.simple_insert_one(kluby, 
				id_klubu="undefined", 
				pelna_nazwa="Klub niezdefiniowany", 
				skrocona_nazwa="N/A")
			self.simple_insert_one(mecze, 
				zewnetrzne_id_meczu="dummy_match", 
				data=datetime.strptime("1970-01-01 00:00:00", '%Y-%m-%d %H:%M:%S'), 
				gospodarze_id="undefined", 
				goscie_id="undefined", 
				gosp_wynik=0, 
				gosc_wynik=0, 
				sezon="1970-1970", 
				nazwa_turnieju="Nieznany turniej", 
				skrocona_nazwa_turnieju="N/A", 
				flaga=0)


			# Robercik
			self.simple_insert_one(kluby,
				id_klubu="barcelona",
				pelna_nazwa="Barcelona",
				skrocona_nazwa="BAR"
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=487,
				minut_gry=0,  # Brak danych 
				gier_sum=487,
				goli_sum=381,
				asyst_sum=44,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=2,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			sportowiec = sportowcy(
				zewnetrzne_id_zawodnika="MVC8zHZD",
				imie="Robert",
				nazwisko="Lewandowski",
				data_urodzenia="21.08.1988",
				czy_aktywny=True,
				klub_id="barcelona",
				narodowosc="PL",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=1,
				wycena=67_000_000  # Wartość rynkowa: €15.3 mln
			)

			trofeum = trofea(
				nazwa="Nieznane trofeum", 
				sezon="0000-0000", 
				rok=1970)

			session.add(sportowiec)
			session.flush()

			session.add(trofeum)
			session.flush()

			trofeum.zawodnik = sportowiec
			sportowiec.ostatnie_trofeum = trofeum

			# MIEJSCE NA DANE KOLEJNYCH SPORTOWCÓW
			# TRZEBA ZROBIĆ TO RĘCZNIE, ZGODNIE ZE SCHEMATEM:
			# self.simple_insert_one(statystyki_sportowcow, 
			# 	ostatni_mecz=1, 
			# 	ilosc_wystapien=0, 
			# 	minut_gry=0, 
			# 	gier_sum=0, 
			# 	goli_sum=0, 
			# 	asyst_sum=0, 
			# 	interwencji_sum=0, 
			# 	nieobronionych_interwencji_sum=0, 
			# 	zoltych_kartek_sum=0, 
			# 	czerwonych_kartek_sum=0, 
			# 	wygranych_sum=0, 
			# 	przegranych_sum=0, 
			# 	remisow_sum=0, 
			# 	wynik_sum=0, 
			# 	meczow_do_wynikow_sum=0)

			# self.simple_insert_one(sportowcy, 
			# 	zewnetrzne_id_zawodnika="...", 
			# 	imie="...", 
			# 	nazwisko="...", 
			# 	data_urodzenia="...", 
			# 	czy_aktywny=True, # NIE WSZYSCY SĄ AKTYWNI! 
			# 	klub_id="undefined", 
			# 	narodowosc="...", 
			# 	ilosc_trofeow=0, 
			# 	pierwszy_mecz_id=1, 
			# 	ostatni_gol_dla_id="undefined", 
			# 	statystyki_id=2, # itd...
			# 	wycena=...) # w złotówkach

			# Ronaldo
			self.simple_insert_one(kluby,
				id_klubu="al-nassr",
				pelna_nazwa="Al Nassr Riyadh",
				skrocona_nazwa="ANR" #?
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=702,
				minut_gry=0,  # Brak danych
				gier_sum=702,
				goli_sum=569,
				asyst_sum=81,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=92,
				czerwonych_kartek_sum=8,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="WGOY4FSt",
				imie="Cristiano",
				nazwisko="Ronaldo",
				data_urodzenia="05.02.1985",
				czy_aktywny=True,
				klub_id="al-nassr",
				narodowosc="PT",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=2,
			    wycena=55_000_000  # Wartość rynkowa: €12.1 mln
			)

			# Messi
			self.simple_insert_one(kluby,
				id_klubu="inter-miami",
				pelna_nazwa="Inter Miami",
				skrocona_nazwa="INM"
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=619,
				minut_gry=0,  # Brak danych o łącznym czasie gry
				gier_sum=619,
				goli_sum=528,
				asyst_sum=53,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=0,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
			    wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="vgOOdZbd",
				imie="Lionel",
				nazwisko="Messi",
				data_urodzenia="24.06.1987",
				czy_aktywny=True,
				klub_id="inter-miami",
				narodowosc="AR",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=3,
				wycena=67_000_000  # Wartość rynkowa: €15.3 mln
			)

			# Mbappe
			self.simple_insert_one(kluby,
				id_klubu="real-madryt",
				pelna_nazwa="Real Madryt",
				skrocona_nazwa="RMA"
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=280,
				minut_gry=0,  # Brak danych o łącznym czasie gry
				gier_sum=280,
				goli_sum=222,
				asyst_sum=67,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=38,
				czerwonych_kartek_sum=2,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="Wn6E2SED",
				imie="Kylian",
				nazwisko="Mbappé",
				data_urodzenia="20.12.1998",
				czy_aktywny=True,
				klub_id="real-madryt",
				narodowosc="FR",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=4,
				wycena=185_700_000  # Wartość rynkowa: €185.7 mln
			)

			# Zlatan
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=519,
				minut_gry=0,  # Brak danych o łącznym czasie gry
				gier_sum=519,
				goli_sum=355,
				asyst_sum=63,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=87,
				czerwonych_kartek_sum=9,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="AiH2zDve",
				imie="Zlatan",
				nazwisko="Ibrahimović",
				data_urodzenia="03.10.1981",
				czy_aktywny=False,
				klub_id="undefined",
				narodowosc="SE",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=5,
				wycena=0  # Zakończył karierę
			)

			# Suarez
			self.simple_insert_one(statystyki_sportowcow,
			    ostatni_mecz=1,
				ilosc_wystapien=608,
				minut_gry=0,  # Brak danych o łącznym czasie gry
				gier_sum=608,
				goli_sum=399,
				asyst_sum=122,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=0,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="dUShzrBp",
				imie="Luis",
				nazwisko="Suárez",
				data_urodzenia="24.01.1987",
				czy_aktywny=True,
				klub_id="inter-miami",
				narodowosc="UY",
				ilosc_trofeow=0,  # Brak danych na Flashscore
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=6,
				wycena=8_800_000  # Wartość rynkowa: €2.0 mln
			)

			# Haaland
			self.simple_insert_one(kluby,
				id_klubu="manchester-city",
				pelna_nazwa="Manchester City",
				skrocona_nazwa="MCI"
			)
			self.simple_insert_one(statystyki_sportowcow,
			    ostatni_mecz=1,
				ilosc_wystapien=235,
				minut_gry=0,  # Brak danych o łącznym czasie gry
				gier_sum=235,
				goli_sum=178,
				asyst_sum=41,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=18,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="UmV9iQmE",
				imie="Erling",
				nazwisko="Haaland",
				data_urodzenia="21.07.2000",
				czy_aktywny=True,
				klub_id="manchester-city",  
				narodowosc="NO",
				ilosc_trofeow=0,  # Brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=7,
				wycena=777_500_000  # ~€178.7 mln
			)

			# Karim Benzema
			self.simple_insert_one(kluby,
				id_klubu="al-ittihad",
				pelna_nazwa="Al-Ittihad FC", #?
				skrocona_nazwa="RMA" #?
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=589,
				minut_gry=0,  # Brak danych
				gier_sum=589,
				goli_sum=305,
				asyst_sum=0,  
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=14,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="tpV0VX0S",
				imie="Karim",
				nazwisko="Benzema",
				data_urodzenia="19.12.1987",
				czy_aktywny=True,
				klub_id="al-ittihad",
				narodowosc="FR",
				ilosc_trofeow=0,  # Flashscore nie podaje
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=8,
				wycena=31_950_000  # €7.1 mln
			)

			# Sergio Aguero
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=443,
				minut_gry=0,  # Brak danych o czasie gry
				gier_sum=443,
				goli_sum=254,
				asyst_sum=38,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=47,
				czerwonych_kartek_sum=2,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="vw8ZV7HC",
				imie="Sergio",
				nazwisko="Agüero",
				data_urodzenia="02.06.1988",
				czy_aktywny=False,
				klub_id="undefined",
				narodowosc="AR",
				ilosc_trofeow=0,  # Brak danych 
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=9,
				wycena=0  # Zakończył karierę
			)

			# Edinson Cavani
			self.simple_insert_one(kluby,
				id_klubu="boca-juniors",
				pelna_nazwa="Boca Juniors", #?
				skrocona_nazwa="CAB" #?
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=507,
				minut_gry=0,  # Brak danych o czasie gry
				gier_sum=507,
				goli_sum=273,
				asyst_sum=62,
				interwencji_sum=0,
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=3,
				czerwonych_kartek_sum=0,
				wygranych_sum=0,  # Brak danych
				przegranych_sum=0,  # Brak danych
				remisow_sum=0,  # Brak danych
				wynik_sum=0,  # Brak danych
				meczow_do_wynikow_sum=0  # Brak danych
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="Qgx2trzH",
				imie="Edinson",
				nazwisko="Cavani",
				data_urodzenia="14.02.1987",
				czy_aktywny=True,
				klub_id="boca-juniors",
				narodowosc="UY",
				ilosc_trofeow=0,
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=10,
				wycena=4_212_000  # PLN
			)

			# Radamel Falcao
			self.simple_insert_one(kluby,
				id_klubu="millonarios",
				pelna_nazwa="Millonarios",
				skrocona_nazwa="MLA" #?
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=360,
				minut_gry=0,  # brak danych o czasie gry
				gier_sum=360,
				goli_sum=170,
				asyst_sum=17,
				interwencji_sum=54,
				nieobronionych_interwencji_sum=1,
				zoltych_kartek_sum=0,  # brak danych
				czerwonych_kartek_sum=0,
				wygranych_sum=0,
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="2oMimkAU",
				imie="Radamel",
				nazwisko="Falcao",
				data_urodzenia="10.02.1986",  
				czy_aktywny=True,
				klub_id="millonarios",
				narodowosc="CO",
				ilosc_trofeow=0,  # brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=11,
				wycena=1_084_500 #PLN
			)

			# Wayne Rooney
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=568,
				minut_gry=0,  # brak danych o czasie gry
				gier_sum=568,
				goli_sum=234,
				asyst_sum=47,
				interwencji_sum=0,  # brak danych
				nieobronionych_interwencji_sum=0,  # brak danych
				zoltych_kartek_sum=105,
				czerwonych_kartek_sum=4,
				wygranych_sum=0,  # brak danych
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="WfXv1DCa",
				imie="Wayne",
				nazwisko="Rooney",
				data_urodzenia="24.10.1985",  
				czy_aktywny=False,  # zakończył karierę
				klub_id="undefined",  
				narodowosc="ENG",
				ilosc_trofeow=0,  # brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=12,
				wycena=0  # brak wyceny
			)

			# Robin van Persie
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=374,
				minut_gry=0,  # brak danych o czasie gry
				gier_sum=374,
				goli_sum=190,
				asyst_sum=16,
				interwencji_sum=0,  # brak danych
				nieobronionych_interwencji_sum=0,  # brak danych
				zoltych_kartek_sum=54,
				czerwonych_kartek_sum=3,
				wygranych_sum=0,  # brak danych
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="0vgcq6un",
				imie="Robin",
				nazwisko="van Persie",
				data_urodzenia="06.08.1983",
				czy_aktywny=False,
				klub_id="undefined",  # zakończył karierę
				narodowosc="NED",
				ilosc_trofeow=0,  # brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=13,
				wycena=0  # zakończył karierę
			)

			# Harry Kane
			self.simple_insert_one(kluby,
				id_klubu="bayern",
				pelna_nazwa="Bayern Monachium",
				skrocona_nazwa="BAY"
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=439,
				minut_gry=0,  # brak danych o czasie gry
				gier_sum=439,
				goli_sum=295,
				asyst_sum=64,
				interwencji_sum=0,  # brak danych
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=48,
				czerwonych_kartek_sum=1,
				wygranych_sum=0,  # brak danych
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="v5HSlEAa",
				imie="Harry",
				nazwisko="Kane",
				data_urodzenia="28.07.1993",
				czy_aktywny=True,
				klub_id="bayern",
				narodowosc="ENG",
				ilosc_trofeow=0,  # brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=14,
				wycena=344_700_000  # PLN
			)

			# Ciro Immobile
			self.simple_insert_one(kluby,
				id_klubu="besiktas",
				pelna_nazwa="Besiktas",
				skrocona_nazwa="BES"
			)
			self.simple_insert_one(statystyki_sportowcow,
				ostatni_mecz=1,
				ilosc_wystapien=455,
				minut_gry=0,  # brak danych o czasie gry
				gier_sum=455,
				goli_sum=250,
				asyst_sum=51,
				interwencji_sum=0,  # brak danych
				nieobronionych_interwencji_sum=0,
				zoltych_kartek_sum=71,
				czerwonych_kartek_sum=3,
				wygranych_sum=0,
				przegranych_sum=0,
				remisow_sum=0,
				wynik_sum=0,
				meczow_do_wynikow_sum=0
			)
			self.simple_insert_one(sportowcy,
				zewnetrzne_id_zawodnika="4S9fNUYh",
				imie="Ciro",
				nazwisko="Immobile",
				data_urodzenia="20.02.1990",
				czy_aktywny=True,
				klub_id="besiktas",
				narodowosc="IT",
				ilosc_trofeow=0,  # brak danych
				pierwszy_mecz_id=1,
				ostatni_gol_dla_id="undefined",
				statystyki_id=15,
				wycena=12_600_000  # PLN
			)


			session.commit()
			return 0

		return 1
