#!/usr/bin/env python3.12
# Eryn Wells <eryn@erynwells.me>

import argparse
import datetime
import os
import subprocess
from typing import Optional
from . import blog, commands, dates, paths
from .scripting import Command


class WeeknotesCommand(Command):
    @staticmethod
    def weeknotes_filename(year: str, week: str) -> str:
        return f'weeknotes-{year}w{week}.md'

    @staticmethod
    def weeknotes_path(*, week_number: Optional[int] = None):
        if week_number:
            year = datetime.datetime.now().year
            week_number_str = str(week_number)
        else:
            next_sunday = dates.next_sunday_noon()
            year = next_sunday.year
            week_number_str = next_sunday.strftime('%V')

        return blog.post_path(WeeknotesCommand.weeknotes_filename(
            str(year),
            week_number_str
        ))

    @property
    def help(self) -> str:
        return 'Work with weeknotes posts'

    def add_arguments(self, parser: argparse.ArgumentParser):
        commands = parser.add_subparsers(title='Weeknotes', required=True)

        convert_command = commands.add_parser(
            'convert',
            help='Convert a post from a single file to a page bundle and vice versa'
        )
        convert_command.set_defaults(handler=self.handle_convert_command)

        edit_command = commands.add_parser(
            'edit',
            help="Edit the current week's weeknotes post"
        )
        edit_command.add_argument(
            '--editor', '-e',
            default=os.environ.get('EDITOR', 'nvim'),
        )
        edit_command.add_argument('--week', '-w')
        edit_command.set_defaults(handler=self.handle_edit_command)

        show_command = commands.add_parser(
            'show',
            aliases=['print'],
            help="Print a path to the current week's weeknotes post",
        )
        show_command.add_argument('--week', '-w')
        show_command.add_argument('--date', action='store_true')
        show_command.set_defaults(handler=self.handle_show_command)

    def handle_convert_command(self, _: argparse.Namespace):
        raise NotImplementedError()

    def handle_edit_command(self, args: argparse.Namespace):
        path = WeeknotesCommand.weeknotes_path(week_number=args.week)

        if not os.path.isfile(path):
            if not self._create_weeknotes_page(week_number=args.week):
                return -1

        relpath = os.path.relpath(path, paths.content_path())
        print(f'Editing {relpath}')

        commands.edit_file(path, editor=args.editor)

    def handle_show_command(self, args: argparse.Namespace):
        if args.date:
            if args.week:
                raise NotImplementedError('Cannot print date with specified week number')
            print(dates.next_sunday_noon().isoformat())
        else:
            print(WeeknotesCommand.weeknotes_path(week_number=args.week))

    def _create_weeknotes_page(self, week_number):
        next_sunday_noon = dates.next_sunday_noon()

        page_path = WeeknotesCommand.weeknotes_path(week_number=week_number)

        try:
            print("Creating weeknotes page...", end='')
            subprocess.run(
                [
                    'hugo', 'new', '-k', 'weeknotes',
                    '--clock', next_sunday_noon.isoformat(),
                    '--contentDir', paths.content_path(),
                    page_path,
                ],
                env=os.environ
            ).check_returncode()
        except subprocess.CalledProcessError:
            print('Failed')
            return False
        else:
            print('OK')

        try:
            print("Processing weeknotes page...", end='')
            week_number = next_sunday_noon.strftime('%V')
            subprocess.run(
                f'sed -I -e "s/%%WEEK_NUMBER%%/{week_number}/" "{page_path}"',
                env=os.environ,
                shell=True
            ).check_returncode()
        except subprocess.CalledProcessError:
            print("Failed")
            return False
        else:
            print('OK')

        return True


