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
import sys
from loguru import logger as log

logger = log
logger.remove()
logger.add("logs/bookgrabber_thread.log", rotation="1 week", enqueue=True)
log.add(
    "logs/application.log",
    rotation="1 day",
    compression="zip",
)

# logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
logger.add(sys.stdout)


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

    def __init__(self, appnr: int):
        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: int, prof_id: int, mode: str, 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)
                print("Added book to database")
            except Exception as e:
                logger.error(f"Failed to update availability: {e}")
                print("Failed to update availability: " + str(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 BookGrabberTest(QThread):
    updateSignal = Signal(int, int)
    done = Signal()

    def __init__(self, appnr: int):
        super(BookGrabberTest, 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)
        self.results = []

    def add_values(
        self, app_id: int, prof_id: int, mode: str, 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):
        item = 0
        iterdata = self.data
        # print(iterdata)
        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)
            if self.mode == "ARRAY":
                if self.use_exact:
                    bd = bd.use_signature(entry)
            bd = bd.get_data(webdata).return_data()
            if bd is None:
                # bd = BookData
                continue
            bd.signature = entry
            transformer = (
                BibTextTransformer("RDS").get_data(webdata).return_data("rds_data")
            )

            # confirm lock is acquired
            # get latest book id
            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))
            self.results.append(bd)

            # 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
