# generar_deltas.py
# Manual Teradata -- Capitulo 12
# Descripcion: Genera los archivos CSV delta para los MultiLoad
#              de pedidos y pagos.
#
# Archivos generados:
#   pedidos_delta.csv  --> ~5.000 filas  (I/U/D sobre ecomm.pedidos)
#   pagos_delta.csv    --> ~3.000 filas  (I/U/D sobre ecomm.pagos)
#
# Logica de negocio simulada:
#   Pedidos:
#     I (40%) -- pedidos nuevos del dia (IDs desde 1.000.001)
#     U (45%) -- actualizacion de estado (ej: ENVIADO -> ENTREGADO)
#     D (15%) -- pedidos cancelados a eliminar
#   Pagos:
#     I (50%) -- pagos nuevos asociados a pedidos recientes
#     U (40%) -- cambio de estado (PENDIENTE -> APROBADO/RECHAZADO)
#     D (10%) -- pagos revertidos
#
# Uso:
#   python generar_deltas.py
#   python generar_deltas.py --fecha 20250615
#
# Requisitos: Python 3.8+, solo stdlib

import csv
import random
import datetime
import sys
from pathlib import Path

random.seed(99)

# ── Parametros ────────────────────────────────────────────────────────────────
FECHA_HOY  = datetime.date.today().strftime('%Y-%m-%d')
OUTPUT_DIR = Path('.')

# Rango de IDs existentes en la carga inicial
MAX_PEDIDO_ID_EXISTENTE = 1_000_000
MAX_PAGO_ID_EXISTENTE   =   950_000

# IDs nuevos (delta de hoy)
BASE_PEDIDO_ID_NUEVO = 1_000_001
BASE_PAGO_ID_NUEVO   =   950_001

# Volumen del delta diario
N_PEDIDOS_DELTA = 5_000
N_PAGOS_DELTA   = 3_000

# Datos de referencia -- mismos que el script principal
REGIONES = [
    'AMBA', 'Cordoba', 'Rosario', 'Mendoza', 'Tucuman',
    'Salta', 'Mar del Plata', 'Neuquen', 'Bariloche', 'La Plata'
]
CANALES      = ['WEB', 'APP', 'MKTPLACE', 'TELEVENTAS']
ESTADOS      = ['PENDIENTE', 'ENVIADO', 'ENTREGADO', 'CANCELADO']
ESTADOS_U    = ['ENVIADO', 'ENTREGADO']   # solo actualizaciones validas
METODOS_PAGO = ['TARJETA', 'MP', 'TRANSFERENCIA', 'CRYPTO']
CUOTAS       = [1, 3, 6, 12, 18, 24]
ESTADOS_PAGO = ['APROBADO', 'RECHAZADO', 'PENDIENTE']

def rand_date(start='2025-06-01', end=FECHA_HOY):
    d1 = datetime.date.fromisoformat(start)
    d2 = datetime.date.fromisoformat(end)
    delta = (d2 - d1).days
    if delta <= 0:
        return d2.strftime('%Y-%m-%d')
    return (d1 + datetime.timedelta(days=random.randint(0, delta))).strftime('%Y-%m-%d')


# ── PEDIDOS DELTA ─────────────────────────────────────────────────────────────
print(f"Generando pedidos_delta.csv ({N_PEDIDOS_DELTA} filas)...")

pedidos_delta_path = OUTPUT_DIR / 'pedidos_delta.csv'
nuevo_id = BASE_PEDIDO_ID_NUEVO

# Distribucion: 40% I, 45% U, 15% D
n_insert = int(N_PEDIDOS_DELTA * 0.40)
n_update = int(N_PEDIDOS_DELTA * 0.45)
n_delete = N_PEDIDOS_DELTA - n_insert - n_update

# IDs existentes para U y D (muestra aleatoria sin repeticion)
ids_para_update = random.sample(range(1, MAX_PEDIDO_ID_EXISTENTE + 1), n_update)
ids_para_delete = random.sample(range(1, MAX_PEDIDO_ID_EXISTENTE + 1), n_delete)

filas_pedidos = []

# INSERT -- pedidos nuevos del dia
for _ in range(n_insert):
    cid    = random.randint(1, 50000)
    pid    = random.randint(1, 5000)
    fecha  = FECHA_HOY
    qty    = random.randint(1, 5)
    precio = round(random.uniform(200, 50000), 2)
    desc   = random.choice([0, 0, 5, 10, 15, 20])
    bruto  = round(precio * qty, 2)
    dscto  = round(bruto * desc / 100, 2)
    total  = round(bruto - dscto, 2)
    filas_pedidos.append([
        nuevo_id, cid, pid, fecha, qty, precio, desc,
        bruto, dscto, total,
        'PENDIENTE', random.choice(CANALES), random.choice(REGIONES), 0,
        'I'
    ])
    nuevo_id += 1

# UPDATE -- cambio de estado de pedidos existentes
for ped_id in ids_para_update:
    qty    = random.randint(1, 5)
    precio = round(random.uniform(200, 50000), 2)
    desc   = random.choice([0, 5, 10, 15])
    bruto  = round(precio * qty, 2)
    dscto  = round(bruto * desc / 100, 2)
    total  = round(bruto - dscto, 2)
    nuevo_estado  = random.choice(ESTADOS_U)
    tiempo_entrega = random.randint(1, 15) if nuevo_estado == 'ENTREGADO' else 0
    filas_pedidos.append([
        ped_id, random.randint(1, 50000), random.randint(1, 5000),
        rand_date(), qty, precio, desc,
        bruto, dscto, total,
        nuevo_estado, random.choice(CANALES), random.choice(REGIONES),
        tiempo_entrega, 'U'
    ])

# DELETE -- pedidos a eliminar
for ped_id in ids_para_delete:
    filas_pedidos.append([
        ped_id, 0, 0, FECHA_HOY, 0, 0, 0, 0, 0, 0,
        'CANCELADO', '', '', 0,
        'D'
    ])

# Mezclar para que no vayan todos los I juntos
random.shuffle(filas_pedidos)

with open(pedidos_delta_path, 'w', newline='', encoding='utf-8') as f:
    w = csv.writer(f)
    w.writerow([
        'pedido_id','cliente_id','producto_id','fecha_pedido',
        'cantidad','precio_unitario','descuento_pct',
        'monto_bruto','monto_descuento','monto_total',
        'estado','canal','region','tiempo_entrega','tipo_op'
    ])
    w.writerows(filas_pedidos)

print(f"  OK -- {n_insert} INSERT | {n_update} UPDATE | {n_delete} DELETE")


# ── PAGOS DELTA ───────────────────────────────────────────────────────────────
print(f"\nGenerando pagos_delta.csv ({N_PAGOS_DELTA} filas)...")

pagos_delta_path = OUTPUT_DIR / 'pagos_delta.csv'
nuevo_pago_id = BASE_PAGO_ID_NUEVO

# Distribucion: 50% I, 40% U, 10% D
n_insert_p = int(N_PAGOS_DELTA * 0.50)
n_update_p = int(N_PAGOS_DELTA * 0.40)
n_delete_p = N_PAGOS_DELTA - n_insert_p - n_update_p

ids_para_update_p = random.sample(range(1, MAX_PAGO_ID_EXISTENTE + 1), n_update_p)
ids_para_delete_p = random.sample(range(1, MAX_PAGO_ID_EXISTENTE + 1), n_delete_p)

filas_pagos = []

# INSERT -- pagos nuevos (asociados a pedidos nuevos del delta)
for _ in range(n_insert_p):
    ped_id = random.randint(BASE_PEDIDO_ID_NUEVO, nuevo_id - 1)
    cli_id = random.randint(1, 50000)
    monto  = round(random.uniform(200, 100000), 2)
    filas_pagos.append([
        nuevo_pago_id, ped_id, cli_id, FECHA_HOY,
        monto, random.choice(METODOS_PAGO),
        random.choice(CUOTAS), 'PENDIENTE',
        'I'
    ])
    nuevo_pago_id += 1

# UPDATE -- cambio de estado PENDIENTE -> APROBADO o RECHAZADO
for pago_id in ids_para_update_p:
    monto = round(random.uniform(200, 100000), 2)
    filas_pagos.append([
        pago_id, random.randint(1, MAX_PEDIDO_ID_EXISTENTE),
        random.randint(1, 50000), FECHA_HOY,
        monto, random.choice(METODOS_PAGO),
        random.choice(CUOTAS),
        random.choice(['APROBADO', 'APROBADO', 'RECHAZADO']),  # mayoria aprobados
        'U'
    ])

# DELETE -- pagos revertidos
for pago_id in ids_para_delete_p:
    filas_pagos.append([
        pago_id, 0, 0, FECHA_HOY,
        0, '', 0, 'RECHAZADO',
        'D'
    ])

random.shuffle(filas_pagos)

with open(pagos_delta_path, 'w', newline='', encoding='utf-8') as f:
    w = csv.writer(f)
    w.writerow([
        'pago_id','pedido_id','cliente_id','fecha_pago',
        'monto_pagado','metodo_pago','cuotas','estado_pago','tipo_op'
    ])
    w.writerows(filas_pagos)

print(f"  OK -- {n_insert_p} INSERT | {n_update_p} UPDATE | {n_delete_p} DELETE")

# ── Resumen ───────────────────────────────────────────────────────────────────
print(f"""
=== Deltas generados exitosamente ===
  pedidos_delta.csv  --> {N_PEDIDOS_DELTA} filas
  pagos_delta.csv    --> {N_PAGOS_DELTA} filas

Proximo paso: ejecutar los MultiLoad
  mload < multiload_pedidos_delta.ml
  mload < multiload_pagos_delta.ml
""")
