"""Module for handling user readable rendering of output reports."""

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from rizomuvbridge_ultimate.operators.rizom_import import UVTransferTracker
    from rizomuvbridge_ultimate.preferences import RizomUVBridgePreferences


class Reporter:
    """Class for handling user readable rendering of output reports."""

    column_separator = " │ "

    def __init__(self, prefs: "RizomUVBridgePreferences", tracker: "UVTransferTracker") -> None:
        """Initialize reporter.

        Args:
        ----
            prefs: Addon preferences.
            tracker: Tracker containing all of the data from the UV process.

        """
        self.tracker = tracker
        self.prefs = prefs

    def main(self):
        """Print output report for the user."""
        if self.prefs.replace_objects:
            return

        if self.tracker.updated_uvmaps:
            self.print_updated_uvmaps()
        if not self.prefs.add_uvsets and self.tracker.missing_uvmaps:
            self.print_updated_uvmaps()
        if self.tracker.missing_objects:
            self.print_missing_objects()
        if self.tracker.invalid_geometry:
            self.print_invalid_geometry()

    def _get_horizontal_divider(self, *col_widths) -> str:
        col_count = len(col_widths)
        total_width = sum(col_widths)
        vertical_separator_width = len(self.column_separator)
        return (total_width + (vertical_separator_width * col_count)) * "─"

    def print_updated_uvmaps(self):
        """Format and print output report for updated UV maps.

        Object | Updated, UV, Maps

        """
        col1_header = "Objects"
        col2_header = "Updated UV Maps"

        # The longest object name
        if not self.tracker.updated_uvmaps:
            return

        col1_width = len(max([obj.name for obj in self.tracker.updated_uvmaps.keys()], key=len))
        horizontal_divider = self._get_horizontal_divider(col1_width, len(col2_header))

        print("\nRizomUV Bridge - Updated UV Maps - Report")
        print("The following objects & UV Maps were updated.\n")

        print(f"{col1_header:{col1_width}}{self.column_separator}{col2_header}")
        print(horizontal_divider)
        for obj, uvmaps in self.tracker.updated_uvmaps.items():
            col1 = obj.name
            col2 = ", ".join(uvmaps)
            print(f"{col1:{col1_width}}{self.column_separator}{col2}")
        print(horizontal_divider)

    def missing_uvmaps(self):
        """Format and print output report for missing UV maps.

        Object | Missing UV Maps

        """
        col1_header = "Objects"
        col2_header = "Missing UV Maps"

        # The longest object name
        col1_width = len(max([obj.name for obj in self.tracker.missing_uvmaps.keys()], key=len))
        horizontal_divider = self._get_horizontal_divider(col1_width, len(col2_header))

        print("\nRizomUV Bridge - Missing UV Maps - Report")
        print("The following UV Maps were not found.\n")

        print(f"{col1_header:{col1_width}}{self.column_separator}{col2_header}")
        print(horizontal_divider)
        for obj, uvmaps in self.tracker.missing_uvmaps.items():
            col1 = obj.name
            col2 = ", ".join(uvmaps)
            print(f"{col1:{col1_width}}{self.column_separator}{col2}")
        print(horizontal_divider)

    def print_missing_objects(self):
        """Format and print output report for missing objects.

        Missing Object

        """
        col1_header = "Missing Objects"

        # The longest object name
        col1_width = len(max(self.tracker.missing_objects, key=len))
        horizontal_divider = self._get_horizontal_divider(col1_width)

        print("\nRizomUV Bridge - Missing Objects - Report")
        print("The following objects could not be found in Blender.\n")

        print(f"{col1_header:{col1_width}}")
        print(horizontal_divider)
        for obj in self.tracker.missing_objects:
            print(obj)
        print(horizontal_divider)

    def print_invalid_geometry(self):
        """Format and print output report for invalid geometry."""
        col1_header = "Objects"

        # The longest object name
        col1_width = len(max(self.tracker.invalid_geometry, key=len))
        horizontal_divider = self._get_horizontal_divider(col1_width)

        print("\nRizomUV Bridge - Invalid Geometry - Report")

        print(
            (
                "\nThe following objects did not have identical geometry to the matched object "
                "imported from RizomUV, "
                "this means that their UV maps likely were not correctly transferred, "
                "verify they are correct before overwriting your Rizom scene. "
                "\nThis can occasionally happen due to a bug with the Blender FBX plugin. "
                "You can import your meshes by using the 'Replace Objects' setting in "
                "the RizomUV Bridge import settings.\n"
            )
        )

        print(f"{col1_header:{col1_width}}")
        print(horizontal_divider)
        for obj in self.tracker.invalid_geometry:
            print(obj.name)
