import csv
import os
import weakref

from lib.db import Archive as ArchiveDbModel
from lib.db import Users
from PyQt5.QtWidgets import QAbstractItemView, QFileDialog
from ui.crud import Crud, Json_External_Dialog_Cell_Widget
from ui.helpers import replace_widget
from ui.widget import Widget


class Archive(Widget):
    def __init__(self, printer=None, hide_cloud_image=False):
        super().__init__()
        self.printer = printer
        # session = Users.get_session()
        # if session is not None and session.is_admin:
        #     crud_aliases = {
        #         "id": "Id",
        #         "time": "Data e ora",
        #         "user": "Operatore",
        #         "test_data.recipe.name": "Ricetta",
        #         "result": "Esito",
        #         "overridden": "Esito forzato",
        #         "test_data": "Dati del test",
        #         "archived": "Archiviato sul portale",
        #         "uploaded": "Immagine in cloud",
        #     }
        #     readonly = ["id"]
        # else:
        crud_aliases = {
            "time": "Data e ora",
            "user": "Operatore",
            "test_data.recipe.name": "Ricetta",
            "result": "Esito",
            "overridden": "Esito forzato",
            "test_data": "Dati del test",
        }
        #     readonly = True
        self.crud = Crud(
            "archive",
            display_name="Archivio",
            readonly=True,
            select=list(crud_aliases.keys()),
            fields_aliases=crud_aliases,
            widget_classes={
                "test_data": Json_External_Dialog_Cell_Widget,
            },
        )
        replace_widget(self, "crud_w", self.crud)
        self.selected = None
        self.print_b.setEnabled(False)
        self.crud.db_tw.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.crud.db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
        self.crud.db_tw.itemSelectionChanged.connect(self.check)
        self.print_b.clicked.connect(self.print_label)
        self.export_b.clicked.connect(lambda checked, self=weakref.ref(self): self().export())

    def check(self):
        if not self.crud.modified:
            selected = self.crud.get_selected_rows()
            if len(selected) == 1:
                selected = selected[0] - 1   # - 1 because rn starts from 1 (filters line)
                if selected >= 0 and selected < len(self.crud.data_index):
                    selected = self.crud.data_index[selected]
                    self.selected = self.crud.db.table_model.get_by_id(selected)
                    self.print_b.setEnabled(True)
                    return
        self.selected = None
        self.print_b.setEnabled(False)

    def print_label(self):
        self.check()
        if self.selected is not None and self.printer is not None:
            self.printer.print_archive_label(self.selected)

    def export(self, csv_path=None):
        if csv_path is None:
            csv_path, _ = QFileDialog.getSaveFileName(
                None,
                "Esportazione archivio",
                "archivio.csv",
                "CSV data (*.csv);;All Files (*)",
            )
        csv_path = str(csv_path)
        if not len(csv_path):
            return
        if not csv_path.lower().endswith(".csv"):
            csv_path += ".csv"
        csv_dir = os.path.dirname(csv_path)
        if len(csv_dir):
            os.makedirs(csv_dir, exist_ok=True)
        data = []
        fieldnames = [
            # "id",
            "time",
            "user",
            "result",
            "overridden",
            "test_data",
            "label",
            # "archived",
            # "uploaded",
        ]
        for archived in list(ArchiveDbModel.select()):
            exportable = {
                # "id": archived.id,
                "time": archived.time,
                "user": archived.user,
                "result": archived.result,
                "overridden": archived.overridden,
                "test_data": archived.test_data,
                # "label": archived.label,
                # "archived": archived.archived,
                # "uploaded": archived.uploaded,
            }
            data.append(exportable)
        if len(data):
            with open(csv_path, "w", newline="") as f:
                w = csv.DictWriter(f, fieldnames, extrasaction="ignore")
                w.writeheader()
                w.writerows(data)
