# from __future__ import absolute_import

import os
import shutil
import sys
import pcbnew
import wx
import pathlib
import logging

_log=logging.getLogger("board2pdf")

dirname = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
_package = os.path.basename(dirname)

try:
    from . _version import __version__
except ImportError:
    # sys.path.insert(0, os.path.dirname(dirname))
    sys.path.append(os.path.dirname(dirname))
    # Pretend we are part of a module
    # Avoids: ImportError: attempted relative import with no known parent package
    __package__ = _package
    __import__(__package__)
    _log.debug("Package: %s\tDir: %s", __package__, dirname)

from . _version import __version__
from . import plot
from . import dialog
from . import persistence
_log.debug("File: %s\tVersion: %s", __file__, __version__)

_board = None
def set_board(board: pcbnew.BOARD):
    global _board
    assert isinstance(board, pcbnew.BOARD)
    _board = board

def get_board() -> pcbnew.BOARD:
    if _board is None:
        set_board(pcbnew.GetBoard())
    return _board


def run_with_dialog():
    board = get_board()
    pcb_file_name = board.GetFileName()
    board2pdf_dir = os.path.dirname(os.path.abspath(__file__))
    pcb_file_dir = os.path.dirname(os.path.abspath(pcb_file_name))
    default_configfile = os.path.join(board2pdf_dir, "default_config.ini")
    global_configfile = os.path.join(board2pdf_dir, "board2pdf.config.ini")
    local_configfile = os.path.join(pcb_file_dir, "board2pdf.config.ini")

    # Not sure it this is needed any more.
    if not pcb_file_name:
        wx.MessageBox('Please save the board file before plotting the pdf.')
        return

    # If local config.ini file doesn't exist, use global. If global doesn't exist, use default.
    if os.path.exists(local_configfile):
        configfile = local_configfile
        configfile_name = "local"
    elif os.path.exists(global_configfile):
        configfile = global_configfile
        configfile_name = "global"
    else:
        configfile = default_configfile
        configfile_name = "default"

    config = persistence.Persistence(configfile)
    config.load()
    config.default_settings_file_path = default_configfile
    config.global_settings_file_path = global_configfile
    config.local_settings_file_path = local_configfile

    def perform_export(dialog_panel):
        plot.plot_pdfs(board, dialog_panel.outputDirPicker.Path, config.templates,
                          dialog_panel.templatesSortOrderBox.GetItems(),
                          dialog_panel.m_checkBox_delete_temp_files.IsChecked(),
                          dialog_panel.m_checkBox_create_svg.IsChecked(),
                          dialog_panel.m_checkBox_delete_single_page_files.IsChecked(), dialog_panel,
                          assembly_file_extension=config.assembly_file_extension,
                          page_info=dialog_panel.m_textCtrl_page_info.GetValue(),
                          info_variable=str(dialog_panel.m_comboBox_info_variable.GetCurrentSelection()))
        dialog_panel.m_progress.SetValue(100)
        dialog_panel.Refresh()
        dialog_panel.Update()

    def load_saved(dialog_panel, config):
        # Update dialog with data from saved config.
        dialog_panel.outputDirPicker.Path = config.output_path
        dialog_panel.templatesSortOrderBox.SetItems(config.enabled_templates)
        dialog_panel.disabledTemplatesSortOrderBox.SetItems(config.disabled_templates)
        dialog_panel.m_checkBox_delete_temp_files.SetValue(config.del_temp_files)
        dialog_panel.m_checkBox_create_svg.SetValue(config.create_svg)
        dialog_panel.m_checkBox_delete_single_page_files.SetValue(config.del_single_page_files)
        dialog_panel.m_textCtrl_page_info.SetValue(config.page_info)
        if not config.info_variable:
            info_variable_int = 0
        else:
            info_variable_int = int(config.info_variable)
        dlg.panel.m_comboBox_info_variable.SetSelection(info_variable_int)
        dialog_panel.ClearTemplateSettings()
        dialog_panel.hide_template_settings()

    dlg = dialog.SettingsDialog(config, perform_export, load_saved, version=__version__, board=get_board())
    try:
        icon_path = os.path.join(os.path.dirname(__file__), 'icon.png')
        icon = wx.Icon(icon_path)
        dlg.SetIcon(icon)
    except Exception:
        pass

    # Update dialog with data from saved config.
    dlg.panel.outputDirPicker.Path = config.output_path
    dlg.panel.templatesSortOrderBox.SetItems(config.enabled_templates)
    dlg.panel.disabledTemplatesSortOrderBox.SetItems(config.disabled_templates)
    dlg.panel.m_checkBox_delete_temp_files.SetValue(config.del_temp_files)
    dlg.panel.m_checkBox_create_svg.SetValue(config.create_svg)
    dlg.panel.m_checkBox_delete_single_page_files.SetValue(config.del_single_page_files)
    dlg.panel.m_textCtrl_page_info.SetValue(config.page_info)
    if not config.info_variable:
        info_variable_int = 0
    else:
        info_variable_int = int(config.info_variable)
    dlg.panel.m_comboBox_info_variable.SetSelection(info_variable_int)
    dlg.panel.m_staticText_status.SetLabel(f'Status: loaded {configfile_name} settings')

    # Check if able to import PyMuPDF.
    has_pymupdf = True
    try:
        import pymupdf  # This imports PyMuPDF

    except ImportError:
        try:
            import fitz as pymupdf  # This imports PyMuPDF using old name
            _log.info("pymupdf old version found")

        except ImportError:
            try:
                import fitz_old as pymupdf # This imports PyMuPDF using temporary old name
                _log.info("pymupdf found")


            except ImportError:
                _log.info("pymupdf not found, using pypdf")
                has_pymupdf = False

    # after pip uninstall PyMuPDF the import still works, but not `open()`
    # check if it's possible to call pymupdf.open()
    if has_pymupdf:
        try:
            pymupdf.open()
        except Exception as e:
            _log.error("pymupdf partially initialized, falling back on pypdf. Error: %s", str(e))
            has_pymupdf = False

    # If it was possible to import and open PyMuPdf, select pymupdf otherwise select pypdf.
    if has_pymupdf:
        dlg.panel.m_radio_pymupdf.SetValue(True)
        dlg.panel.m_radio_merge_pymupdf.SetValue(True)
    else:
        dlg.panel.m_radio_pypdf.SetValue(True)
        dlg.panel.m_radio_merge_pypdf.SetValue(True)

    # Check if able to import pdfCropMargins.
    has_pdfcropmargins = True
    try:
        from pdfCropMargins import crop  # This imports pdfCropMargins
    except:
        has_pdfcropmargins = False

    if has_pdfcropmargins:
        dlg.panel.m_staticText_pdfCropMargins.SetLabel(f'pdfCropMargins Status: Installed')
    else:
        dlg.panel.m_staticText_pdfCropMargins.SetLabel(f'pdfCropMargins Status: NOT Installed')

    dlg.ShowModal()
    dlg.Destroy()


class board2pdf(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = f"Board2Pdf\nversion {__version__}"
        self.category = "Plot"
        self.description = "Plot pcb to pdf."
        self.show_toolbar_button = True  # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'icon.png')  # Optional

    def Run(self):
        run_with_dialog()


def main():
    if not wx.App.Get():
        _log.debug("No existing app found, creating App")
        app = wx.App()
    run_with_dialog()


if __name__ == "__main__":
    logging.basicConfig()
    _log.setLevel(logging.DEBUG)
    board = None
    try:
        board_path = pathlib.Path(sys.argv[1]).absolute()
        assert board_path.exists()
        board = pcbnew.LoadBoard(str(board_path))
    except IndexError:
        _log.info("No board path passed as argument, trying kicad environment")
        board = pcbnew.GetBoard()

    if board is not None:
        set_board(board)
        main()
    else:
        _log.error("No board path passed or found in environment")
