#!/usr/bin/env python3
import csv
import sys
import time
import logging
import argparse
import requests

WEBHOOK_URL = "https://brandize.app.n8n.cloud/webhook/VAT"
BATCH_SIZE = 50
REQUEST_TIMEOUT = 60

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)-7s %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)
log = logging.getLogger("send")


def load_rows(csv_file):
    with open(csv_file, "r", newline="", encoding="utf-8-sig") as file:
        return list(csv.DictReader(file))


def send_batch(batch):
    response = requests.post(
        WEBHOOK_URL,
        json=batch,
        headers={"Content-Type": "application/json"},
        timeout=REQUEST_TIMEOUT,
    )
    response.raise_for_status()
    return response


def send_csv(csv_file, batch_size):
    try:
        rows = load_rows(csv_file)
    except FileNotFoundError:
        log.error("CSV file not found: %s", csv_file)
        return 1
    except OSError as e:
        log.error("Could not read %s: %s", csv_file, e)
        return 1

    total = len(rows)
    if total == 0:
        log.warning("No data rows found in %s", csv_file)
        return 0

    num_batches = (total + batch_size - 1) // batch_size
    log.info("Loaded %d rows from %s", total, csv_file)
    log.info("Sending in %d batch(es) of up to %d rows", num_batches, batch_size)

    sent = 0
    failed = 0
    start_time = time.time()

    for index in range(num_batches):
        batch = rows[index * batch_size:(index + 1) * batch_size]
        first_row = index * batch_size + 1
        last_row = first_row + len(batch) - 1

        log.info(
            "Batch %d/%d (rows %d-%d, %d rows) ...",
            index + 1, num_batches, first_row, last_row, len(batch),
        )

        try:
            response = send_batch(batch)
            sent += len(batch)
            log.info(
                "Batch %d/%d OK (HTTP %d) | Progress: %d/%d rows (%.2f%%)",
                index + 1, num_batches, response.status_code,
                sent, total, sent / total * 100,
            )
        except requests.RequestException as e:
            failed += 1
            log.error(
                "Batch %d/%d FAILED: %s | Progress: %d/%d rows (%.2f%%)",
                index + 1, num_batches, e,
                sent, total, sent / total * 100,
            )

    elapsed = time.time() - start_time
    log.info(
        "Done in %.1fs. %d/%d rows sent, %d batch(es) failed. Progress: %.2f%%",
        elapsed, sent, total, failed, sent / total * 100,
    )
    return 1 if failed else 0


def main():
    parser = argparse.ArgumentParser(
        description="Send all rows of a CSV file to an n8n webhook in batches."
    )
    parser.add_argument("csv_file", help="Path to the CSV file")
    parser.add_argument(
        "--batch-size",
        type=int,
        default=BATCH_SIZE,
        help="Number of rows per request (default: %(default)s)",
    )
    args = parser.parse_args()

    if args.batch_size < 1:
        parser.error("--batch-size must be at least 1.")

    sys.exit(send_csv(args.csv_file, args.batch_size))


if __name__ == "__main__":
    main()
