#!/usr/bin/env python3
import os
import sys
import re
from pathlib import Path
from lxml import etree
from urllib.parse import unquote


class SimpleInjector:
    def __init__(self, svg_directory="./"):
        self.svg_directory = Path(svg_directory)

    def get_svg_path(self, url):
        separated_url = url.split('/wp-content/')
        decoded_path = unquote(separated_url[1])
        return os.path.join(self.svg_directory, decoded_path)

    def inject_svg_content(self, main_svg_path, output_path):
        """
        Inject SVG content: replace <image> elements with actual SVG content,
        apply proper positioning transforms, and remove clipPath elements
        """
        try:
            # Parse main SVG
            parser = etree.XMLParser(huge_tree=True)
            tree = etree.parse(main_svg_path, parser)
            root = tree.getroot()

            # Find image elements that reference SVGs
            images_to_replace = []
            clipPaths = []
            clipPathIdsToRemove = set()

            for elem in root.iter():
                if elem.tag == '{http://www.w3.org/2000/svg}image':
                    href = elem.get('{http://www.w3.org/1999/xlink}href')
                    if href and href.endswith('.svg'):
                        images_to_replace.append(elem)
                # Collect clipPath elements
                elif elem.tag == '{http://www.w3.org/2000/svg}clipPath':
                    clipPaths.append(elem)

            # Process each image
            for image in images_to_replace:
                href = image.get('{http://www.w3.org/1999/xlink}href')
                svg_file_path = self.get_svg_path(href)
                filename = os.path.basename(svg_file_path)

                if os.path.exists(svg_file_path):
                    print(f"Injecting: {filename}")

                    # Get positioning from original image
                    x = image.get('x', '0')
                    y = image.get('y', '0')
                    clippath_attr = image.get('clip-path')

                    # Extract clipPath ID from url(#id) format
                    if clippath_attr:
                        # clip-path="url(#imageCrop_2)" -> extract "imageCrop_2"
                        match = re.search(r'url\(#([^)]+)\)', clippath_attr)
                        if match:
                            clippath_id = match.group(1)
                            clipPathIdsToRemove.add(clippath_id)
                            print(f"Will remove clipPath: {clippath_id}")

                    # Load the SVG content
                    svg_content = self._load_svg_content(svg_file_path)

                    # Get the parent and position
                    parent = image.getparent()
                    image_index = list(parent).index(image)

                    # Remove the image
                    parent.remove(image)

                    # Create wrapper group with translation
                    wrapper_group = etree.Element('{http://www.w3.org/2000/svg}g')
                    wrapper_group.set('transform', f"translate({x}, {y})")

                    # Add SVG content to wrapper
                    for element in svg_content:
                        wrapper_group.append(element)

                    # Insert wrapper at the image's position
                    parent.insert(image_index, wrapper_group)

                else:
                    print(f"Warning: SVG file not found: {svg_file_path}")

            # Remove only the clipPath elements that were used by images
            for clipPath in clipPaths:
                clippath_id = clipPath.get('id')
                if clippath_id in clipPathIdsToRemove:
                    parent = clipPath.getparent()
                    if parent is not None:
                        parent.remove(clipPath)
                        print(f"Removed clipPath: {clippath_id}")

            # Remove clip-path attributes only from elements that reference removed clipPaths
            for elem in root.iter():
                clippath_attr = elem.get('clip-path')
                if clippath_attr:
                    match = re.search(r'url\(#([^)]+)\)', clippath_attr)
                    if match and match.group(1) in clipPathIdsToRemove:
                        del elem.attrib['clip-path']
                        print(f"Removed clip-path attribute from {elem.tag}")

            # Write result
            tree.write(output_path, encoding='utf-8', xml_declaration=True, pretty_print=True)
            print(f"Injected SVG saved to: {output_path}")
            return output_path

        except Exception as e:
            print(f"Error: {e}")
            raise

    def _load_svg_content(self, svg_path):
        """
        Load SVG file and return its child elements (excluding the root svg element)
        """
        parser = etree.XMLParser()
        svg_tree = etree.parse(svg_path, parser)
        svg_root = svg_tree.getroot()

        # Return all child elements from the SVG (defs, groups, paths, etc.)
        return list(svg_root)


def main():
    if len(sys.argv) < 3:
        print("Usage: python svg_processor.py <file_path> <new_path> <relative_wp_upload_path> [output_path]", file=sys.stderr)
        sys.exit(1)

    main_svg = sys.argv[1]
    new_svg_path = sys.argv[2]
    content_path = sys.argv[3]

#   standard path is base websitefolder goes out one level from the main.svg
    standard_relative_path = '../wp-content/'

    relative_wp_uploads = sys.argv[3] if len(sys.argv) > 3 else standard_relative_path
    svg_dir = sys.argv[1] if len(sys.argv) > 1 else "./"

    injector = SimpleInjector(content_path)
    injector.inject_svg_content(main_svg, new_svg_path)


if __name__ == "__main__":
    main()
