# Copyright (C) 2024,2025,2026 Kian-Meng Ang
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

"""Auto subcommand."""

from __future__ import annotations

import argparse
import logging
from pathlib import Path
from typing import Any

import fotolab.subcommands.animate
import fotolab.subcommands.contrast
import fotolab.subcommands.resize
import fotolab.subcommands.sharpen
import fotolab.subcommands.watermark
from fotolab import open_image

from .common import add_common_arguments, log_args_decorator

log = logging.getLogger(__name__)


def build_subparser(subparsers: argparse._SubParsersAction[Any]) -> None:
    """Build the subparser."""
    auto_parser = subparsers.add_parser(
        "auto",
        help="auto adjust (resize, contrast, and watermark) a photo",
    )

    auto_parser.set_defaults(func=run)

    add_common_arguments(auto_parser)

    auto_parser.add_argument(
        "-t",
        "--title",
        dest="title",
        help="set the tile (default: '%(default)s')",
        type=str,
        default=None,
        metavar="TITLE",
    )

    auto_parser.add_argument(
        "-w",
        "--watermark",
        dest="watermark",
        help="set the watermark (default: '%(default)s')",
        type=str,
        default="kianmeng.org",
        metavar="WATERMARK_TEXT",
    )


def _get_base_filename(
    title: str | None,
    image_file: Path,
    *,
    multi: bool = False,
) -> str:
    """Generate a sanitized base filename from title or image filename."""
    if title:
        sanitized = title.lower().replace(",", "").replace(" ", "_")
        if multi:
            return f"{sanitized}_{image_file.stem}"
        return sanitized
    return image_file.stem


@log_args_decorator
def run(args: argparse.Namespace) -> None:
    """Run auto subcommand.

    Args:
        args (argparse.Namespace): Config from command line arguments

    Returns:
        None
    """
    text = args.watermark
    if args.title and args.watermark:
        text = f"{args.title}\n{args.watermark}"

    extra_args = {
        "width": 600,
        "height": 277,
        "cutoff": 1,
        "radius": 1,
        "percent": 100,
        "threshold": 2,
        "text": text,
        "position": "bottom-left",
        "font_size": 12,
        "font_color": "white",
        "outline_width": 2,
        "outline_color": "black",
        "padding": 15,
        "padding_x": None,
        "padding_y": None,
        "camera": False,
        "canvas": False,
        "lowercase": True,
        "before_after": False,
        "alpha": 128,
        "aspect_ratio": None,
    }

    # Base configuration for all steps
    base_args_dict = {**vars(args), **extra_args}
    base_args_dict["open"] = False  # Disable opening intermediates

    processed_paths = []
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    is_multi = len(args.image_paths) > 1

    for image_path_str in args.image_paths:
        image_path = Path(image_path_str)
        base_name = _get_base_filename(args.title, image_path, multi=is_multi)
        final_filename = f"{base_name}{image_path.suffix.lower()}"
        final_output_path = output_dir / final_filename

        # Step 1: Resize (Read original, save to output directory)
        step_args = argparse.Namespace(**base_args_dict)
        step_args.image_paths = [str(image_path)]
        step_args.output_filename = final_filename
        step_args.overwrite = False
        fotolab.subcommands.resize.run(step_args)

        # Subsequent Steps: Contrast, Sharpen, Watermark
        # (Cumulatively overwrite)
        step_args.image_paths = [str(final_output_path)]
        step_args.overwrite = True
        step_args.output_filename = None

        fotolab.subcommands.contrast.run(step_args)
        fotolab.subcommands.sharpen.run(step_args)
        fotolab.subcommands.watermark.run(step_args)

        processed_paths.append(final_output_path)

    # Final actions
    if is_multi:
        # Create animation from processed images
        gif_base = _get_base_filename(
            args.title,
            Path("animation"),
            multi=False,
        )
        gif_filename = f"{gif_base}.gif"

        animate_args = argparse.Namespace(**base_args_dict)
        animate_args.image_paths = [str(p) for p in processed_paths]
        animate_args.format = "gif"
        animate_args.duration = 2500
        animate_args.loop = 0
        animate_args.output_filename = gif_filename
        animate_args.overwrite = False
        fotolab.subcommands.animate.run(animate_args)

        if args.open:
            open_image(output_dir / gif_filename)
    elif args.open and processed_paths:
        open_image(processed_paths[0])
