"""Command-line interface for Zotero2Readwise.

This module provides the CLI entry point for running the Zotero to Readwise
synchronization from the command line.

Example:
    $ zotero2readwise <readwise_token> <zotero_key> <zotero_library_id>
    $ zotero2readwise --include_notes y --filter_color "#ffd400"

Environment Variables:
    READWISE_TOKEN: Readwise API access token
    ZOTERO_KEY: Zotero API key
    ZOTERO_LIBRARY_ID: Zotero user or group library ID
    ZOTERO_LIBRARY_TYPE: Library type ("user" or "group")
"""

from argparse import ArgumentParser
from os import environ

from zotero2readwise.helper import read_library_version, write_library_version
from zotero2readwise.zt2rw import Zotero2Readwise


def strtobool(val: str) -> int:
    """Convert a string representation of truth to 1 or 0.

    This is a replacement for the deprecated distutils.util.strtobool.

    Args:
        val: String value to convert. Accepts 'y', 'yes', 't', 'true',
            'on', '1' for True and 'n', 'no', 'f', 'false', 'off', '0'
            for False (case-insensitive).

    Returns:
        1 for truthy values, 0 for falsy values.

    Raises:
        ValueError: If val is not a recognized truth value.

    Example:
        >>> strtobool("yes")
        1
        >>> strtobool("no")
        0
    """
    val = val.lower()
    if val in ("y", "yes", "t", "true", "on", "1"):
        return 1
    elif val in ("n", "no", "f", "false", "off", "0"):
        return 0
    else:
        raise ValueError(f"invalid truth value {val}")


def main() -> None:
    """Main entry point for the Zotero2Readwise CLI.

    Parses command-line arguments and environment variables, then runs
    the synchronization process. Credentials can be provided either as
    positional arguments or via environment variables.
    """
    parser = ArgumentParser(
        description="Sync Zotero annotations and notes to Readwise",
        epilog="Credentials can be provided via arguments or environment variables "
        "(READWISE_TOKEN, ZOTERO_KEY, ZOTERO_LIBRARY_ID, ZOTERO_LIBRARY_TYPE).",
    )
    parser.add_argument(
        "readwise_token",
        nargs="?",
        default=environ.get("READWISE_TOKEN"),
        help="Readwise Access Token (or set READWISE_TOKEN env var)",
    )
    parser.add_argument(
        "zotero_key",
        nargs="?",
        default=environ.get("ZOTERO_KEY"),
        help="Zotero API key (or set ZOTERO_KEY env var)",
    )
    parser.add_argument(
        "zotero_library_id",
        nargs="?",
        default=environ.get("ZOTERO_LIBRARY_ID"),
        help="Zotero User ID (or set ZOTERO_LIBRARY_ID env var)",
    )
    parser.add_argument(
        "--library_type",
        default=environ.get("ZOTERO_LIBRARY_TYPE", "user"),
        help="Zotero Library type ('user': for personal library (default), 'group': for shared library)",
    )
    parser.add_argument(
        "--include_annotations",
        type=str,
        default="y",
        help="Include Zotero annotations (highlights + comments) | Options: 'y'/'yes' (default), 'n'/'no'",
    )
    parser.add_argument(
        "--include_notes",
        type=str,
        default="n",
        help="Include Zotero notes | Options: 'y'/'yes', 'n'/'no' (default)",
    )
    parser.add_argument(
        "--filter_color",
        choices=[
            "#ffd400",
            "#ff6666",
            "#5fb236",
            "#2ea8e5",
            "#a28ae5",
            "#e56eee",
            "#f19837",
            "#aaaaaa",
        ],
        action="append",
        default=[],
        help="Filter Zotero annotations by given color | Options: '#ffd400' (yellow), '#ff6666' (red), '#5fb236' (green), '#2ea8e5' (blue), '#a28ae5' (purple), '#e56eee' (magenta), '#f19837' (orange), '#aaaaaa' (gray)",
    )
    parser.add_argument(
        "--filter_tags",
        action="append",
        default=[],
        help="Filter Zotero annotations by given tags",
    )
    parser.add_argument(
        "--include_filter_tags",
        action="store_true",
        help="Include the tags used for --filter_tags in the Zotero annotations.",
    )
    parser.add_argument(
        "--use_since", action="store_true", help="Include Zotero items since last run"
    )
    parser.add_argument(
        "--suppress_failures",
        action="store_true",
        help="Do not write annotations that failed to port to a report file.",
    )
    parser.add_argument(
        "--custom_tag",
        type=str,
        default=None,
        help="Add a custom tag to all highlights (e.g., 'zotero' will add '.zotero' tag to all highlights)",
    )

    args = vars(parser.parse_args())

    # Validate required credentials
    if not args["readwise_token"]:
        parser.error(
            "readwise_token is required (provide as argument or set READWISE_TOKEN env var)"
        )
    if not args["zotero_key"]:
        parser.error("zotero_key is required (provide as argument or set ZOTERO_KEY env var)")
    if not args["zotero_library_id"]:
        parser.error(
            "zotero_library_id is required (provide as argument or set ZOTERO_LIBRARY_ID env var)"
        )

    # Cast str to bool values for bool flags
    for bool_arg in ["include_annotations", "include_notes"]:
        try:
            args[bool_arg] = bool(strtobool(args[bool_arg]))
        except ValueError:
            raise ValueError(f"Invalid value for --{bool_arg}. Use 'n' or 'y' (default).") from None

    since = read_library_version() if args["use_since"] else 0
    zt2rw = Zotero2Readwise(
        readwise_token=args["readwise_token"],
        zotero_key=args["zotero_key"],
        zotero_library_id=args["zotero_library_id"],
        zotero_library_type=args["library_type"],
        include_annotations=args["include_annotations"],
        include_notes=args["include_notes"],
        filter_colors=tuple(args["filter_color"]),
        filter_tags=tuple(args["filter_tags"]),
        include_filter_tags=args["include_filter_tags"],
        since=since,
        write_failures=not args["suppress_failures"],
        custom_tag=args["custom_tag"],
    )
    zt2rw.run()
    if args["use_since"]:
        write_library_version(zt2rw.zotero_client)


if __name__ == "__main__":
    main()
