import os
import re
import logging
from packaging import version
from flask import current_app

class ContentManager:
    def __init__(self, app=None):
        self.app = app
        if app:
            self.init_app(app)

    def init_app(self, app):
        self.app = app

        # Controleer of het pad bestaat
        # if not os.path.exists(app.config['CONTENT_DIR']):
        #     logger.warning(f"Content directory not found at: {app.config['CONTENT_DIR']}")
        # else:
        #     logger.info(f"Content directory configured at: {app.config['CONTENT_DIR']}")

    def get_content_path(self, content_type, major_minor=None, patch=None):
        """
        Geef het volledige pad naar een contentbestand

        Args:
            content_type (str): Type content (bv. 'changelog', 'terms')
            major_minor (str, optional): Major.Minor versie (bv. '1.0')
            patch (str, optional): Patchnummer (bv. '5')

        Returns:
            str: Volledige pad naar de content map of bestand
        """
        content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)

        if major_minor:
            content_path = os.path.join(content_path, major_minor)

            if patch:
                content_path = os.path.join(content_path, f"{major_minor}.{patch}.md")

        return content_path

    def _parse_version(self, filename):
        """Parse een versienummer uit een bestandsnaam"""
        match = re.match(r'(\d+\.\d+)\.(\d+)\.md', filename)
        if match:
            return match.group(1), match.group(2)
        return None, None

    def get_latest_version(self, content_type, major_minor=None):
        """
        Verkrijg de laatste versie van een bepaald contenttype

        Args:
            content_type (str): Type content (bv. 'changelog', 'terms')
            major_minor (str, optional): Specifieke major.minor versie, anders de hoogste

        Returns:
            tuple: (major_minor, patch, full_version) of None als niet gevonden
        """
        try:
            # Basispad voor dit contenttype
            content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)

            if not os.path.exists(content_path):
                current_app.logger.error(f"Content path does not exist: {content_path}")
                return None

            # Als geen major_minor opgegeven, vind de hoogste
            if not major_minor:
                available_versions = [f for f in os.listdir(content_path) if not f.startswith('.')]
                if not available_versions:
                    return None

                # Sorteer op versienummer (major.minor)
                available_versions.sort(key=lambda v: version.parse(v))
                major_minor = available_versions[-1]

            # Nu we major_minor hebben, zoek de hoogste patch
            major_minor_path = os.path.join(content_path, major_minor)
            current_app.logger.debug(f"Major/Minor path: {major_minor_path}")

            if not os.path.exists(major_minor_path):
                current_app.logger.error(f"Version path does not exist: {major_minor_path}")
                return None

            files = [f for f in os.listdir(major_minor_path) if not f.startswith('.')]
            current_app.logger.debug(f"Files in version path: {files}")
            version_files = []

            for file in files:
                mm, p = self._parse_version(file)
                current_app.logger.debug(f"File: {file}, mm: {mm}, p: {p}")
                if mm == major_minor and p:
                    version_files.append((mm, p, f"{mm}.{p}"))

            if not version_files:
                return None

            # Sorteer op patch nummer
            version_files.sort(key=lambda v: int(v[1]))

            current_app.logger.debug(f"Latest version: {version_files[-1]}")
            return version_files[-1]

        except Exception as e:
            current_app.logger.error(f"Error finding latest version for {content_type}: {str(e)}")
            return None

    def read_content(self, content_type, major_minor=None, patch=None):
        """
        Lees content met versieondersteuning

        Als major_minor en patch niet zijn opgegeven, wordt de laatste versie gebruikt.
        Als alleen major_minor is opgegeven, wordt de laatste patch van die versie gebruikt.

        Args:
            content_type (str): Type content (bv. 'changelog', 'terms')
            major_minor (str, optional): Major.Minor versie (bv. '1.0')
            patch (str, optional): Patchnummer (bv. '5')

        Returns:
            dict: {
                'content': str,
                'version': str,
                'content_type': str
            } of None bij fout
        """
        try:
            current_app.logger.debug(f"Reading content {content_type}")
            # Als geen versie opgegeven, vind de laatste
            if not major_minor:
                version_info = self.get_latest_version(content_type)
                if not version_info:
                    current_app.logger.error(f"No versions found for {content_type}")
                    return None

                major_minor, patch, full_version = version_info

            # Als geen patch opgegeven, vind de laatste patch voor deze major_minor
            elif not patch:
                version_info = self.get_latest_version(content_type, major_minor)
                if not version_info:
                    current_app.logger.error(f"No versions found for {content_type} {major_minor}")
                    return None

                major_minor, patch, full_version = version_info
            else:
                full_version = f"{major_minor}.{patch}"

            # Nu hebben we major_minor en patch, lees het bestand
            file_path = self.get_content_path(content_type, major_minor, patch)
            current_app.logger.debug(f"Content File path: {file_path}")

            if not os.path.exists(file_path):
                current_app.logger.error(f"Content file does not exist: {file_path}")
                return None

            with open(file_path, 'r', encoding='utf-8') as file:
                content = file.read()

            current_app.logger.debug(f"Content read: {content}")

            return {
                'content': content,
                'version': full_version,
                'content_type': content_type
            }

        except Exception as e:
            current_app.logger.error(f"Error reading content {content_type} {major_minor}.{patch}: {str(e)}")
            return None

    def list_content_types(self):
        """Lijst alle beschikbare contenttypes op"""
        try:
            return [d for d in os.listdir(self.app.config['CONTENT_DIR']) 
                   if os.path.isdir(os.path.join(self.app.config['CONTENT_DIR'], d))]
        except Exception as e:
            current_app.logger.error(f"Error listing content types: {str(e)}")
            return []

    def list_versions(self, content_type):
        """
        Lijst alle beschikbare versies voor een contenttype

        Returns:
            list: Lijst van dicts met versie-informatie
                  [{'version': '1.0.0', 'path': '/path/to/file', 'date_modified': datetime}]
        """
        versions = []
        try:
            content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)

            if not os.path.exists(content_path):
                return []

            for major_minor in os.listdir(content_path):
                major_minor_path = os.path.join(content_path, major_minor)

                if not os.path.isdir(major_minor_path):
                    continue

                for file in os.listdir(major_minor_path):
                    mm, p = self._parse_version(file)
                    if mm and p:
                        file_path = os.path.join(major_minor_path, file)
                        mod_time = os.path.getmtime(file_path)
                        versions.append({
                            'version': f"{mm}.{p}",
                            'path': file_path,
                            'date_modified': mod_time
                        })

            # Sorteer op versienummer
            versions.sort(key=lambda v: version.parse(v['version']))
            return versions

        except Exception as e:
            current_app.logger.error(f"Error listing versions for {content_type}: {str(e)}")
            return []
