#!/usr/bin/env python3

import argparse
import datetime
import json
import os
import subprocess

from wcwidth import wcswidth

from clboss.alias_cache import lookup_alias

def run_lightning_cli_command(lightning_dir, network_option, command, *args):
    full_cmd = ['lightning-cli', network_option] \
        + ([command] if command else []) + list(args)
    if lightning_dir:
        full_cmd = full_cmd[:2] \
            + [f'--lightning-dir={lightning_dir}'] \
            + full_cmd[2:]
    try:
        result = subprocess.run(full_cmd, capture_output=True, text=True, check=True)
        return json.loads(result.stdout)
    except subprocess.CalledProcessError:
        return None  # suppress error output

def format_datetime(ts):
    return datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') if ts else "-"

def short_nodeid(nodeid):
    return nodeid[:12] if nodeid else "-"

def display_pad(text, width):
    display_len = wcswidth(str(text))
    pad = width - display_len
    return str(text) + " " * max(pad, 0)

def main():
    parser = argparse.ArgumentParser(description="Show recently closed channels")
    parser.add_argument("--days", type=int, default=30,
                        help="Limit to channels closed within the last N days")
    parser.add_argument("--mainnet", action="store_true", help="Run on mainnet")
    parser.add_argument("--testnet", action="store_true", help="Run on testnet")
    parser.add_argument("--signet", action="store_true", help="Run on signet")
    parser.add_argument("--regtest", action="store_true", help="Run on regtest")
    parser.add_argument("--network", help="Set the network explicitly")
    parser.add_argument("--lightning-dir", help="lightning data location")
    args = parser.parse_args()

    # Reconcile network option (mirror clboss-earnings-history)
    if args.network:
        network_option = f"--network={args.network}"
    elif args.testnet:
        network_option = "--network=testnet"
    elif args.signet:
        network_option = "--network=signet"
    elif args.regtest:
        network_option = "--network=regtest"
    else:
        network_option = "--network=bitcoin"  # lightning-cli wants "bitcoin" for mainnet

    lightning_dir = args.lightning_dir
    if lightning_dir and not os.path.isdir(lightning_dir):
        parser.error(f"--lightning-dir {lightning_dir} is not a directory")

    cutoff = None
    if args.days:
        cutoff = datetime.datetime.now().timestamp() - args.days * 86400

    data = run_lightning_cli_command(lightning_dir, network_option,
                                     'listclosedchannels')
    if not data or "closedchannels" not in data or not data["closedchannels"]:
        print("No closed channels found.")
        return

    entries = []
    for ch in sorted(data["closedchannels"], key=lambda c: c.get("last_stable_connection", 0)):
        ts = ch.get("last_stable_connection", 0)
        if cutoff and ts < cutoff:
            continue

        dt_str = format_datetime(ts)
        peer_id = ch.get("peer_id", "-")
        alias = lookup_alias(run_lightning_cli_command, lightning_dir,
                             network_option, peer_id)
        alias_display = alias if alias != peer_id else short_nodeid(peer_id)

        short_id = ch.get("short_channel_id", "-")
        closer = ch.get("closer", "-")
        cause = ch.get("close_cause", "-")
        height = ch.get("close_height", "-")
        to_us_sat = int(ch.get("final_to_us_msat", 0)) // 1000

        entries.append([dt_str, alias_display, short_id, closer, cause, height, to_us_sat])

    if not entries:
        print("No closed channels found within the specified timeframe.")
        return

    headers = ["CLOSED AT", "ALIAS", "SHORT CHAN ID", "CLOSER", "CAUSE", "BLOCK", "TO US (sat)"]
    col_widths = [max(wcswidth(str(row[i])) for row in entries + [headers]) for i in range(len(headers))]

    print("  ".join(display_pad(h, col_widths[i]) for i, h in enumerate(headers)))
    print("-" * (sum(col_widths) + 2 * (len(headers) - 1)))

    for row in entries:
        print("  ".join(display_pad(row[i], col_widths[i]) for i in range(len(headers))))

if __name__ == "__main__":
    main()
