#!/usr/bin/env python3
"""
List all Home Assistant entities and their states

This script queries Home Assistant and displays all entities with their current states.
Can filter by domain (e.g., light, switch, sensor) and format output.

Usage:
    # List all entities
    python3 list_entities.py --url http://homeassistant.local:8123 --token YOUR_TOKEN

    # List only lights
    python3 list_entities.py --url http://homeassistant.local:8123 --token YOUR_TOKEN --domain light

    # Output as JSON
    python3 list_entities.py --url http://homeassistant.local:8123 --token YOUR_TOKEN --format json

Environment variables:
    HA_URL: Home Assistant URL
    HA_TOKEN: Long-lived access token
"""

import argparse
import json
import os
import sys
import urllib.request


def get_entities(url: str, token: str):
    """Get all entity states from Home Assistant."""
    api_url = f"{url.rstrip('/')}/api/states"
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    req = urllib.request.Request(api_url, headers=headers)

    try:
        with urllib.request.urlopen(req) as response:
            return json.loads(response.read().decode('utf-8'))
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(description='List Home Assistant entities')
    parser.add_argument('--url', help='Home Assistant URL',
                       default=os.getenv('HA_URL'))
    parser.add_argument('--token', help='Long-lived access token',
                       default=os.getenv('HA_TOKEN'))
    parser.add_argument('--domain', help='Filter by domain (e.g., light, switch, sensor)')
    parser.add_argument('--format', choices=['table', 'json', 'list'],
                       default='table', help='Output format')

    args = parser.parse_args()

    if not args.url or not args.token:
        print("Error: URL and token are required", file=sys.stderr)
        sys.exit(1)

    entities = get_entities(args.url, args.token)

    # Filter by domain if specified
    if args.domain:
        entities = [e for e in entities if e['entity_id'].startswith(f"{args.domain}.")]

    if args.format == 'json':
        print(json.dumps(entities, indent=2))
    elif args.format == 'list':
        for entity in entities:
            print(entity['entity_id'])
    else:  # table format
        print(f"{'Entity ID':<40} {'State':<20} {'Last Changed':<20}")
        print("-" * 80)
        for entity in entities:
            entity_id = entity['entity_id']
            state = entity['state']
            last_changed = entity.get('last_changed', 'N/A')[:19]  # Truncate timestamp
            print(f"{entity_id:<40} {state:<20} {last_changed:<20}")

        print(f"\nTotal: {len(entities)} entities")


if __name__ == '__main__':
    main()
