import argparse
import json
import os
import sys

import matplotlib.pyplot as plt


def load_json_data(file_path):
    """
    Load and validate JSON data from a file.
    Expected format:
    {
        "label1": value1,
        "label2": value2,
        ...
    }
    """
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"File not found: {file_path}")

    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)

    if not isinstance(data, dict):
        raise ValueError(
            "JSON must be an object with key-value pairs (labels: values)."
        )

    for key, value in data.items():
        if not isinstance(key, str):
            raise ValueError("All keys must be strings (labels).")
        if not isinstance(value, (int, float)):
            raise ValueError("All values must be numeric (int or float).")

    return data


def create_bar_graph(
    data, title="Bar Graph", x_label="Labels", y_label="Values", output=None
):
    """
    Create a bar graph from a dictionary of data.
    """
    labels = list(data.keys())
    values = list(data.values())

    plt.figure(figsize=(10, 6))
    plt.bar(labels, values)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.title(title)
    plt.xticks(rotation=45)
    plt.tight_layout()

    if output:
        plt.savefig(output)
        print(f"Graph saved to: {output}")
    else:
        plt.show()


def main():
    parser = argparse.ArgumentParser(
        description="Generate a bar graph from a JSON file containing key-value pairs."
    )
    parser.add_argument(
        "json_path",
        type=str,
        help="Path to the JSON file (e.g., data.json)",
    )
    parser.add_argument(
        "--title",
        type=str,
        default="Bar Graph",
        help="Title of the bar graph",
    )
    parser.add_argument(
        "--x_label",
        type=str,
        default="Labels",
        help="Label for the x-axis",
    )
    parser.add_argument(
        "--y_label",
        type=str,
        default="Values",
        help="Label for the y-axis",
    )
    parser.add_argument(
        "--output",
        type=str,
        default=None,
        help="Optional output file path (e.g., graph.png). If not provided, the graph will be displayed.",
    )

    args = parser.parse_args()

    try:
        data = load_json_data(args.json_path)
        create_bar_graph(
            data,
            title=args.title,
            x_label=args.x_label,
            y_label=args.y_label,
            output=args.output,
        )
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
