import sqlite3

from PyQt6.QtCore import QThread
from PyQt6.QtCore import pyqtSignal as Signal
from src.backend import Database

from src.logic.webrequest import BibTextTransformer, WebRequest


class BookGrabber(QThread):
    updateSignal = Signal(int, int)
    done = Signal()

    def __init__(self, appnr):
        super(BookGrabber, self).__init__(parent=None)
        self.is_Running = True
        logger.info("Starting worker thread")
        self.data = None
        self.app_id = None
        self.prof_id = None
        self.mode = None
        self.book_id = None
        self.use_any = False
        self.use_exact = False
        self.appnr = appnr
        self.tstate = (self.app_id, self.prof_id, self.mode, self.data)

    def add_values(self, app_id, prof_id, mode, data, any_book=False, exact=False):
        self.app_id = app_id
        self.prof_id = prof_id
        self.mode = mode
        self.data = data
        self.use_any = any_book
        self.use_exact = exact
        logger.info(f"Working on {len(self.data)} entries")
        self.tstate = (self.app_id, self.prof_id, self.mode, self.data)
        logger.debug("State: " + str(self.tstate))
        # print(self.tstate)

    def run(self):
        self.db = Database()
        item = 0
        iterdata = self.data
        # print(iterdata)
        if self.prof_id is None:
            self.prof_id = self.db.getProfNameByApparat(self.app_id)
        for entry in iterdata:
            # print(entry)
            signature = str(entry)
            logger.info("Processing entry: " + signature)

            webdata = WebRequest().set_apparat(self.appnr).get_ppn(entry)
            if self.use_any:
                webdata = webdata.use_any_book
            webdata = webdata.get_data()

            if webdata == "error":
                continue

            bd = BibTextTransformer(self.mode)
            print(webdata)
            if self.mode == "ARRAY":
                if self.use_exact:
                    bd = bd.use_signature(entry)
            bd = bd.get_data(webdata).return_data()
            print(bd)
            if bd is None:
                # bd = BookData
                continue
            bd.signature = entry
            transformer = (
                BibTextTransformer("RDS").get_data(webdata).return_data("rds_data")
            )

            # confirm lock is acquired
            self.db.addBookToDatabase(bd, self.app_id, self.prof_id)
            # get latest book id
            self.book_id = self.db.getLastBookId()
            logger.info("Added book to database")
            state = 0
            for result in transformer.RDS_DATA:
                # print(result.RDS_LOCATION)
                if str(self.app_id) in result.RDS_LOCATION:
                    state = 1
                    break

            logger.info(f"State of {signature}: {state}")
            # print("updating availability of " + str(self.book_id) + " to " + str(state))
            try:
                self.db.setAvailability(self.book_id, state)
            except sqlite3.OperationalError as e:
                logger.error(f"Failed to update availability: {e}")

            # time.sleep(5)
            item += 1
            self.updateSignal.emit(item, len(self.data))
        logger.info("Worker thread finished")
        # self.done.emit()
        self.quit()

    def stop(self):
        self.is_Running = False


# class BookGrabber(object):
#     updateSignal = Signal(int, int)
#     done = Signal()

#     def __init__(self, app_id, prof_id, mode, data, parent=None):
#         super(BookGrabber, self).__init__(parent=None)
#         self.is_Running = True
#         logger = MyLogger("Worker")
#         logger.info("Starting worker thread")
#         self.data = data
#         logger.info(f"Working on {len(self.data)} entries")
#         self.app_id = app_id
#         self.prof_id = prof_id
#         self.mode = mode
#         self.book_id = None
#         self.state = (self.app_id, self.prof_id, self.mode, self.data)
#         # print(self.state)
#         logger.info("state: " + str(self.state))
#         # time.sleep(2)

#     def resetValues(self):
#         self.app_id = None
#         self.prof_id = None
#         self.mode = None
#         self.data = None
#         self.book_id = None

#     def run(self):
#         while self.is_Running:
#             self.db = Database()
#             item = 0
#             iterdata = self.data
#             # print(iterdata)
#             for entry in iterdata:
#                 # print(entry)
#                 signature = str(entry)
#                 logger.info("Processing entry: " + signature)

#                 webdata = WebRequest().get_ppn(entry).get_data()
#                 if webdata == "error":
#                     continue
#                 bd = BibTextTransformer(self.mode).get_data(webdata).return_data()
#                 transformer = BibTextTransformer("RDS")
#                 rds = transformer.get_data(webdata).return_data("rds_availability")
#                 bd.signature = entry
#                 # confirm lock is acquired
#                 self.db.addBookToDatabase(bd, self.app_id, self.prof_id)
#                 # get latest book id
#                 self.book_id = self.db.getLastBookId()
#                 logger.info("Added book to database")
#                 state = 0
#                 # print(len(rds.items))
#                 for rds_item in rds.items:
#                     sign = rds_item.superlocation
#                     loc = rds_item.location
#                     # logger.debug(sign, loc)
#                     # logger.debug(rds_item)
#                     if self.app_id in sign or self.app_id in loc:
#                         state = 1
#                         break

#                 logger.info(f"State of {signature}: {state}")
#                 # print(
#                     "updating availability of "
#                     + str(self.book_id)
#                     + " to "
#                     + str(state)
#                 )
#                 try:
#                     self.db.setAvailability(self.book_id, state)
#                 except sqlite3.OperationalError as e:
#                     logger.error(f"Failed to update availability: {e}")

#                 # time.sleep(5)
#                 item += 1
#                 self.updateSignal.emit(item, len(self.data))
#             logger.info("Worker thread finished")
#             # self.done.emit()
#             self.stop()
#             if not self.is_Running:
#                 break

#     def stop(self):
#         self.is_Running = False
