import inspect
from pathlib import Path

import chevron
from numpydoc.docscrape import NumpyDocString

import remedapy as R


def _parse_groupings(path: Path) -> list[dict[str, object]]:
    groups: list[dict[str, object]] = []
    current: dict[str, object] | None = None

    for raw in path.read_text(encoding='utf-8').splitlines():
        line = raw.strip()
        if not line:
            continue
        if line.endswith(':') and not line.startswith('-'):
            current = {'name': line[:-1], 'functions': []}
            groups.append(current)
            continue
        if line.startswith('- '):
            if current is None:
                continue
            fn_name = line[2:].strip()
            casted = current['functions']
            assert isinstance(casted, list)
            casted.append(fn_name)

    return groups


def main() -> None:
    readme_path = Path(__file__).parent.parent / 'README.md'
    groupings_path = Path(__file__).parent / 'Grouping.md'
    template_path = Path(__file__).parent / 'README.mustache'

    groups = _parse_groupings(groupings_path)

    for group in groups:
        fn_names = group['functions']
        assert isinstance(fn_names, list)
        fn_docs: list[dict[str, str]] = []
        for fn_name in fn_names:
            fn = getattr(R, fn_name, None)
            if fn is None:
                fn_docs.append({'name': str(fn_name), 'summary': '', 'examples': '', 'parameters': '', 'returns': '', 'yields': '', 'see_also': ''})
                continue

            doc = inspect.getdoc(fn) or ''
            lines = {
                'Summary': [],
                'Parameters': [],
                'Returns': [],
                'Yields': [],
                'See Also': [],
                'Examples': []
            }
            current = 'Summary'
            for line in doc.split("\n"):
                if line in lines:
                    current = line
                    continue
                if all(x == '-' for x in line):
                    continue
                lines[current].append(line)
            def merge(x):
                return '\n'.join(x)
            parsed = NumpyDocString(doc)
            fn_docs.append(
                {
                    'name': fn_name,
                    'summary': merge(lines['Summary']),
                    'examples': merge(lines['Examples']),
                    'parameters': merge( lines['Parameters']),
                    'returns': merge(lines['Returns']),
                    'yields': merge(lines['Yields']),
                    'see_also': lines['See Also'],
                }
            )

        group['functions'] = fn_docs

    groupings_text = ''
    for group in groups:
        groupings_text += group['name'] + ':\n\n'
        for fn in group['functions']:
            groupings_text += f"- [{fn['name']}](#{fn['name']})\n"
        groupings_text += '\n'

    data = {'groups': groups, 'groupings': groupings_text}
    template = template_path.read_text(encoding='utf-8')
    rendered = chevron.render(template=template, data=data)
    readme_path.write_text(rendered, encoding='utf-8')


if __name__ == '__main__':
    main()