#!/usr/bin/env python
# coding: utf-8

# ESTE PYTHON ES PARA IMPORTAR LOS DATOS SE QUEDA TAL COMO ESTA NO MODIFICICAR OJO
import pandas as pd
import sys
import os
import unicodedata
from openpyxl import load_workbook
from openpyxl.styles import Border, Side

# ========== 1. Leer argumentos ==========
if len(sys.argv) < 4:
    print("Error: Faltan argumentos. Se requieren: archivo_origen, archivo_destino, hoja_destino.")
    sys.exit(1)

archivo_origen = sys.argv[1]
archivo_destino = sys.argv[2]
hoja_destino = sys.argv[3]
hoja_origen = "Reports"

if not os.path.isfile(archivo_origen):
    print(f"Error: El archivo origen '{archivo_origen}' no existe.")
    sys.exit(1)

# ========== Helpers de normalización/búsqueda ==========
def _norm(s: str) -> str:
    if s is None:
        return ""
    s = str(s)
    s = unicodedata.normalize("NFD", s)
    s = "".join(ch for ch in s if unicodedata.category(ch) != "Mn")
    return s.casefold().strip()

def _to_float(x):
    try:
        v = pd.to_numeric(x, errors="coerce")
        return float(v) if pd.notna(v) else None
    except Exception:
        return None

def _buscar_valor_alrededor(df_any: pd.DataFrame, r: int, c: int):
    # 1) derecha hasta 3 celdas
    for cc in range(c+1, min(c+4, df_any.shape[1])):
        val = _to_float(df_any.iat[r, cc])
        if val is not None:
            return val
    # 2) izquierda hasta 3 celdas
    for cc in range(c-1, max(-1, c-4), -1):
        if cc < 0: break
        val = _to_float(df_any.iat[r, cc])
        if val is not None:
            return val
    # 3) debajo hasta 3 celdas
    for rr in range(r+1, min(r+4, df_any.shape[0])):
        val = _to_float(df_any.iat[rr, c])
        if val is not None:
            return val
    return None

def _buscar_global_por_texto(df_any: pd.DataFrame, texto: str) -> float:
    texto = _norm(texto)
    # dataframe de strings normalizados
    df_norm = df_any.astype(str).applymap(_norm)
    for r in range(df_norm.shape[0]):
        for c in range(df_norm.shape[1]):
            if texto in df_norm.iat[r, c]:
                val = _buscar_valor_alrededor(df_any, r, c)
                if val is not None:
                    return val
    return 0.00

# ========== 2. Leer hoja completa sin encabezado ==========
df = pd.read_excel(archivo_origen, sheet_name=hoja_origen, header=None)

# ========== 3. Correcciones (se conserva aunque no se use en salida) ==========
df_corr_raw = df.iloc[42:48, 0:3].copy()
df_corr_raw.columns = df_corr_raw.iloc[0]
df_corr = df_corr_raw.iloc[1:].reset_index(drop=True)
df_corr.columns = ["Nombre (Correcciones)", "Recuento (Corr)", "Importe (Corr)"]

# ========== 4. Propinas: intentar bloque típico y dejar fallback global ==========
# (muchos reportes traen Propinas en D:E; si en tu archivo están en A:B, igual hay fallback global)
# Primero intentamos A18:B24 como tenías:
df_temp = df.iloc[17:24, [0, 1]].copy()
if df_temp.notna().values.any():
    df_temp.columns = ["Nombre (Propinas)", "Importe (Propinas)"]
    df_temp["Importe (Propinas)"] = pd.to_numeric(df_temp["Importe (Propinas)"], errors="coerce").fillna(0.00).round(2)
    df_propinas = df_temp.reset_index(drop=True)
else:
    df_propinas = pd.DataFrame(columns=["Nombre (Propinas)", "Importe (Propinas)"])

def _buscar_propina_local(subtexto: str) -> float:
    if df_propinas.empty:
        return 0.00
    mask = df_propinas["Nombre (Propinas)"].astype(str).apply(lambda x: subtexto in _norm(x))
    if mask.any():
        return float(df_propinas.loc[mask, "Importe (Propinas)"].iloc[0])
    return 0.00

# ========== 5. Medios de pago ==========
idx_medios_pago = df[df.apply(
    lambda row: row.astype(str).str.contains("Ejecutar informe de tema de medios de pago", case=False, na=False).any(),
    axis=1
)].index

if not idx_medios_pago.empty:
    start = idx_medios_pago[0] + 2
    df_pago = df.iloc[start:start + 6, 0:3].copy()
    df_pago.columns = ["TIPO_MEDIO_PAGO", "TOTAL_PAGO", "RECUENTO_PAGO"]
    df_pago = df_pago.reset_index(drop=True)
    df_pago["TIPO_MEDIO_PAGO"] = df_pago["TIPO_MEDIO_PAGO"].astype(str).str.strip()
else:
    df_pago = pd.DataFrame(columns=["TIPO_MEDIO_PAGO", "TOTAL_PAGO", "RECUENTO_PAGO"])

def _valor_pago(nombre: str) -> float:
    if df_pago.empty:
        return 0.00
    serie = df_pago.loc[df_pago["TIPO_MEDIO_PAGO"].apply(_norm) == _norm(nombre), "TOTAL_PAGO"]
    return float(serie.iloc[0]) if not serie.empty else 0.00

# ========== 6. Columnas finales (incluye Pago Cortesia exacto) ==========
columnas_finales = [
    "Total Revenue", "Tarjeta", "Efectivo", "Funcionario2", "Yape", "Transferencia",
    "Pago Cortesia", "Cargos por servicio"
]

# Medios
valores_finales = [
    _valor_pago("Total"),
    _valor_pago("Tarjeta"),
    _valor_pago("Efectivo"),
    _valor_pago("Funcionario2"),
    _valor_pago("Yape"),
    _valor_pago("Transferencia"),
]

# Pago Cortesia (primero intentar en propinas; si no, búsqueda global)
pago_cortesia_val = _buscar_propina_local("cortesia")
if pago_cortesia_val == 0.00:
    pago_cortesia_val = _buscar_global_por_texto(df, "pago cortesia")
valores_finales.append(pago_cortesia_val)

# Cargos por servicio (local y si no, global)
cargos_servicio_val = _buscar_propina_local("cargos por servicio")
if cargos_servicio_val == 0.00:
    cargos_servicio_val = _buscar_global_por_texto(df, "cargos por servicio")
valores_finales.append(cargos_servicio_val)

# DataFrame final con una sola fila y encabezados fijos
df_final = pd.DataFrame([valores_finales], columns=columnas_finales)

# ========== 7. Reemplazar datos en hoja destino ==========
if not os.path.exists(archivo_destino):
    print(f"Error: El archivo destino '{archivo_destino}' no existe.")
    sys.exit(1)

wb = load_workbook(archivo_destino)
if hoja_destino not in wb.sheetnames:
    print(f"Error: La hoja '{hoja_destino}' no existe en el archivo destino.")
    sys.exit(1)

ws = wb[hoja_destino]
ws.delete_rows(2, ws.max_row - 1 if ws.max_row > 1 else 0)

# ========== 8. Estilo de bordes ==========
thin_border = Border(
    left=Side(style='thin'),
    right=Side(style='thin'),
    top=Side(style='thin'),
    bottom=Side(style='thin')
)

# ========== 9. Encabezados ==========
for j, col in enumerate(df_final.columns, start=1):
    ws.cell(row=1, column=j, value=col)

# ========== 10. Datos ==========
for i, fila in df_final.iterrows():
    for j, valor in enumerate(fila):
        celda = ws.cell(row=i + 2, column=j + 1, value=valor)
        celda.border = thin_border

wb.save(archivo_destino)
print(f"✅ Datos reemplazados correctamente en: {archivo_destino} - Hoja: {hoja_destino}")
