import numpy as np
import os
import csv
import secrets

from datetime import datetime
import calendar
import pprint
import time
import pandas as pd
from ubuntuFiles import PATH_UBUNTU
from flask import jsonify

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


def obtener_Dias(estrategiaNumber):
    estrategia_archivo_map = {
        '1': 'IBData0940NoResults.csv',
        '2': 'IBData1030NoResults.csv',
        '3': 'IBData1100NoResults.csv',
        '4': 'IBData1130NoResults.csv',
        '5': 'IBData0932NoResults.csv'

    }
    archivo_csv = PATH_UBUNTU + estrategia_archivo_map[estrategiaNumber]
    df = pd.read_csv(archivo_csv, header=0, dtype=str)
    dfLista = df.columns.tolist()
    solo_Fechas = dfLista[0::4]
    return solo_Fechas


def listaParaGrafico(fecha_str, estrategiaNumber, offset):
    estrategia_archivo_map = {
        '1': 'IBData0940NoResults.csv',
        '2': 'IBData1030NoResults.csv',
        '3': 'IBData1100NoResults.csv',
        '4': 'IBData1130NoResults.csv',
        '5': 'IBData0932NoResults.csv'

    }
    archivo_csv = PATH_UBUNTU + estrategia_archivo_map[estrategiaNumber]

    indice_fecha_especifica = 0
    fecha_str = fecha_str.replace("-", "/")
    df = pd.read_csv(archivo_csv, low_memory=False)
    dfLista = df.columns.tolist()
    solo_Fechas = dfLista[0::4]
    if fecha_str in solo_Fechas:
        indice_fecha_especifica = dfLista.index(fecha_str)

    cantidad_filas = df.iloc[:, indice_fecha_especifica].count()
    onlyDF = df.iloc[:cantidad_filas,
                     indice_fecha_especifica:indice_fecha_especifica+4]
    elprimero = onlyDF.iloc[0, 1] - offset
    onlyDF.iloc[:, 0] = onlyDF.iloc[:, 0].apply(
        lambda x: '0' + x if len(x) == 7 else x)
    onlyDF['P/L'] = elprimero - onlyDF.iloc[:, 1]
    onlyDF['P/L%'] = onlyDF.iloc[:, 4] / elprimero
    onlyDF['VIX%'] = onlyDF.iloc[:, 3] / 100

    return onlyDF


def obtener_Datos(tp, sl, contracts, estrategiaNumber, offset, dollarOrPerc):

    data = []
    estrategia_info = {
        '1': {'archivo_csv': 'IBData0940NoResults.csv', 'HoraComienzo': '09:40:00'},
        '2': {'archivo_csv': 'IBData1030NoResults.csv', 'HoraComienzo': '10:30:00'},
        '3': {'archivo_csv': 'IBData1100NoResults.csv', 'HoraComienzo': '11:00:00'},
        '4': {'archivo_csv': 'IBData1130NoResults.csv', 'HoraComienzo': '11:30:00'},
        '5': {'archivo_csv': 'IBData0932NoResults.csv', 'HoraComienzo': '09:31:00'},
        '6': {'archivo_csv': 'IBData0933NoResults.csv', 'HoraComienzo': '09:31:00'},
    }

    estrategia = estrategia_info.get(estrategiaNumber)
    archivo_csv = PATH_UBUNTU + estrategia['archivo_csv']
    HoraComienzo = estrategia['HoraComienzo']

    df = pd.read_csv(archivo_csv, low_memory=False)
    dfLista = df.columns.tolist()
    solo_Fechas = dfLista[0::4]
    columna_indice = 0

    for fecha in solo_Fechas:
        cantidad_filas = df.iloc[:, columna_indice].count()
        onlyDF = df.iloc[0:cantidad_filas, columna_indice:columna_indice+3]

        diaSemana = calendar.day_name[datetime.strptime(
            fecha, "%m/%d/%Y").date().weekday()]  # obtiene el dia de la semana
        holiday = verificarFeriados(fecha)

        elprimero = onlyDF.iloc[0, 1] - offset
        onlyDF['P/L'] = elprimero - onlyDF.iloc[:, 1]
        onlyDF['P/L%'] = onlyDF.iloc[:, 3] / elprimero

        TPTime, SLTime, BadOrGood, credito, TPMinutes, SLMinutes, ProfitOrLossNoContracts, ocurrencias = goodOrBadDay(
            tp, sl, onlyDF, HoraComienzo, dollarOrPerc, offset)
        ProfitOrLoss = f"$ {float(ProfitOrLossNoContracts * contracts):.2f}"

        nuevos_datos = [fecha, diaSemana, holiday, TPTime, TPMinutes,
                        ocurrencias, SLTime, SLMinutes, credito, ProfitOrLoss, "", "", BadOrGood]
        data.append(nuevos_datos)
        columna_indice += 4

    return data


def goodOrBadDay(takeProfit, stopLoss, onlydf1, HoraComienzo, dollarOrPerc, offset):

    # Multiplica los valores por 100 si es en porcentaje
    multiplier = 100 if dollarOrPerc == "D" else 1
    takeProfit *= multiplier
    stopLoss *= multiplier

    # Busca la hora del 1er TP
    if dollarOrPerc == "P":
        fila_indiceTP = (onlydf1.iloc[:, 4] > takeProfit).idxmax()
    else:
        fila_indiceTP = (onlydf1.iloc[:, 3] > takeProfit).idxmax()

    HoraTP = onlydf1.iloc[fila_indiceTP, 0]

    # Busca la hora del 1er SL
    if dollarOrPerc == "P":
        fila_indiceSL = (onlydf1.iloc[:, 4] < stopLoss).idxmax()
    else:
        fila_indiceSL = (onlydf1.iloc[:, 3] < stopLoss).idxmax()

    HoraSL = onlydf1.iloc[fila_indiceSL, 0]

    # Busca el primer precio del IB, osea el credito otorgado
    credito = round(float(onlydf1.iloc[0, 1]), 2)-offset
    credito_formatted = f"$ {float(credito):.2f}"
    # Busca la cantidad de ocurrencias

    if fila_indiceSL == 0:
        fila_indiceSL = 999999

    if fila_indiceTP == 0:
        fila_indiceTP = 999999

    if dollarOrPerc == "P":
        countMayorATakeProfit = (onlydf1.iloc[:, 4] > takeProfit).sum()
        countParcialATakeProfift = (
            onlydf1.iloc[fila_indiceTP:fila_indiceSL, 4] > takeProfit).sum()
    else:
        countMayorATakeProfit = (onlydf1.iloc[:, 3] > takeProfit).sum()
        countParcialATakeProfift = (
            onlydf1.iloc[fila_indiceTP:fila_indiceSL, 3] > takeProfit).sum()

    occurrencias = str(countParcialATakeProfift) + \
        "/" + str(countMayorATakeProfit)

    TPMinutes = calcular_diferencia_horas(HoraTP, HoraComienzo)
    SLMinutes = calcular_diferencia_horas(HoraSL, HoraComienzo)

    if fila_indiceTP < fila_indiceSL:
        BadOrGood = "GOOD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit
    else:
        BadOrGood = "BAD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    if fila_indiceSL == 999999:
        BadOrGood = "GOOD"
        HoraSL = "-"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit

    if fila_indiceTP == 999999:
        BadOrGood = "BAD"
        HoraTP = "-"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    return HoraTP, HoraSL, BadOrGood, credito_formatted, TPMinutes, SLMinutes, ProfitOrLoss, occurrencias


def calcular_diferencia_horas(hora1_str, hora2_str):
    # Convertir las horas a objetos datetime
    hora1 = datetime.strptime(hora1_str, "%H:%M:%S")
    hora2 = datetime.strptime(hora2_str, "%H:%M:%S")
    # Calcular la diferencia entre las horas
    diferencia = hora1 - hora2

    # Obtener la diferencia en horas y minutos
    diferencia_horas = diferencia.seconds // 3600
    diferencia_minutos = (diferencia.seconds // 60) % 60

    # Formatear el resultado en formato "hh:mm"
    diferencia_str = "{:02d}:{:02d}".format(
        diferencia_horas, diferencia_minutos)

    if diferencia_str == "00:00":
        diferencia_str = "-"

    return diferencia_str


def verificarFeriados(fecha_verificar):
    archivo_csv = PATH_UBUNTU + "holidays.csv"
    df1 = pd.read_csv(archivo_csv, header=None)
    # Convertir la primera columna en datetime
    df1[0] = pd.to_datetime(df1[0])

    # Buscar la fecha en la columna de fechas
    mask = df1[0] == fecha_verificar
    if mask.any():
        # Si la fecha está en el DataFrame, obtener el valor de la segunda columna
        valor_columna_2 = df1.loc[mask, 1].values[0]
        return valor_columna_2
    else:
        # Si la fecha no se encuentra, devolver una cadena vacía
        return "No News"


def listaParaGraficoDiario(estrategiaNumber, offset):
    preNombreArchivo = "Intraday_"
    fecha_actual = datetime.now()
    postNombreArchivo = fecha_actual.strftime('%Y-%m-%d')
    archivo_csv = ""

    # creando el nombre del archivo en base al dia
    if estrategiaNumber == '1':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB0940_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '2':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB1030_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '3':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB1100_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '4':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB1130_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '5':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB0932_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '6':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IB0932_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '7':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IC0932_" + postNombreArchivo + ".csv"
    if estrategiaNumber == '8':
        archivo_csv = PATH_UBUNTU + preNombreArchivo + "IC1030_" + postNombreArchivo + ".csv"

    dfDatos = pd.read_csv(archivo_csv, skiprows=1, header=None)
    dfCabecera = pd.read_csv(archivo_csv, nrows=1, header=None)
    # dfDatos = pd.read_csv(archivo_csv, header=None)
    dfDatos[0] = dfDatos[0].str[-8:]
    elprimero = dfDatos.iloc[0, 1] - float(offset)
    dfDatos.iloc[:, 0] = dfDatos.iloc[:, 0].apply(
        lambda x: '0' + x if len(x) == 7 else x)
    dfDatos['P/L'] = elprimero - dfDatos.iloc[:, 1]
    dfDatos['P/L%'] = dfDatos.iloc[:, 4] / elprimero

    return dfDatos, dfCabecera


def listaComparativa(takeProfit1, takeProfit2, takeProfit3, takeProfit4, stopLoss1, stopLoss2, stopLoss3, stopLoss4, offset, contracts, miniComparative, IBList, dollarOrPercen):

    listaParcial1, listaCreditos1, TPMinutesParcial1, profitOrLoss1 = listaComparativaPorEstrategia(
        IBList[0], takeProfit1, stopLoss1, offset, contracts, miniComparative, dollarOrPercen)
    listaParcial2, listaCreditos2, TPMinutesParcial2, profitOrLoss2 = listaComparativaPorEstrategia(
        IBList[1], takeProfit2, stopLoss2, offset, contracts, miniComparative, dollarOrPercen)
    listaParcial3, listaCreditos3, TPMinutesParcial3, profitOrLoss3 = listaComparativaPorEstrategia(
        IBList[2], takeProfit3, stopLoss3, offset, contracts, miniComparative, dollarOrPercen)
    listaParcial4, listaCreditos4, TPMinutesParcial4, profitOrLoss4 = listaComparativaPorEstrategia(
        IBList[3], takeProfit4, stopLoss4, offset, contracts, miniComparative, dollarOrPercen)

    # para obtener las fechas. Se usa 1130 porque es la que tiene mas data
    archivo_csv = PATH_UBUNTU + 'IBData1130NoResults.csv'
    if miniComparative == 'true':
        df = pd.read_csv(archivo_csv, nrows=1, low_memory=False, usecols=range(100))
    else:
        df = pd.read_csv(archivo_csv, nrows=1, low_memory=False)

    dfLista = df.columns.tolist()
    listaFechas = dfLista[0::4]

    # para obtener los dias de noticias
    listaNews = []
    archivo_csv = PATH_UBUNTU + 'holidays.csv'
    for fecha in listaFechas:
        holiday = verificarFeriados(fecha)
        listaNews.append(holiday)

    return listaFechas, listaNews, listaParcial1, listaParcial2, listaParcial3, listaParcial4, listaCreditos1, listaCreditos2, listaCreditos3, listaCreditos4, TPMinutesParcial1, TPMinutesParcial2, TPMinutesParcial3, TPMinutesParcial4, profitOrLoss1, profitOrLoss2, profitOrLoss3, profitOrLoss4


def listaComparativaPorEstrategia(estrategiaNumber, takeProfit, stopLoss, offset, contracts, miniComparative, dollarOrPercen):
    estrategia_info = {
        '1': {'archivo_csv': 'IBData0940NoResults.csv', 'HoraComienzo': '09:40:00'},
        '2': {'archivo_csv': 'IBData1030NoResults.csv', 'HoraComienzo': '10:30:00'},
        '3': {'archivo_csv': 'IBData1100NoResults.csv', 'HoraComienzo': '11:00:00'},
        '4': {'archivo_csv': 'IBData1130NoResults.csv', 'HoraComienzo': '11:30:00'},
        '5': {'archivo_csv': 'IBData0932NoResults.csv', 'HoraComienzo': '09:31:00'},

    }

    estrategia = estrategia_info.get(estrategiaNumber)
    archivo_csv = PATH_UBUNTU + estrategia['archivo_csv']
    HoraComienzo = estrategia['HoraComienzo']

    if miniComparative == 'true':
        df = pd.read_csv(archivo_csv, low_memory=False, usecols=range(100))
    else:
        df = pd.read_csv(archivo_csv, low_memory=False)

    listaparcial = []
    TPMinutesParcial = []
    profitOrLossParcial = []

    dfLista = df.columns.tolist()
    solo_Fechas = dfLista[0::4]
    creditoParcial = (df.iloc[0, 1::4]-offset).astype(int).tolist()

    columna_indice = 0
    for fecha in solo_Fechas:
        cantidad_filas = df.iloc[:, columna_indice].count()
        onlyDF = df.iloc[0:cantidad_filas, columna_indice:columna_indice+3]

        elprimero = onlyDF.iloc[0, 1] - offset
        onlyDF['P/L'] = elprimero - onlyDF.iloc[:, 1]
        onlyDF['P/L%'] = onlyDF.iloc[:, 3] / elprimero

        columna_indice += 4
        if dollarOrPercen == "P":
            indice_fila_TP = onlyDF.index[onlyDF['P/L%'] >= takeProfit].min()
        else:
            indice_fila_TP = onlyDF.index[onlyDF['P/L'] >= takeProfit].min()

        if np.isnan(indice_fila_TP):
            indice_fila_TP = 99999

        if dollarOrPercen == "P":
            indice_fila_SL = onlyDF.index[onlyDF['P/L%'] < stopLoss].min()
        else:
            indice_fila_SL = onlyDF.index[onlyDF['P/L'] < stopLoss].min()

        if np.isnan(indice_fila_SL):
            indice_fila_SL = 99999

        if indice_fila_TP < indice_fila_SL:
            listaparcial.append("G")
            HoraTP = onlyDF.iloc[indice_fila_TP, 0]
            TPMinutes = calcular_diferencia_horas(HoraTP, HoraComienzo)
            TPMinutesParcial.append(TPMinutes)

            if dollarOrPercen == "P":
                profitOrLoss = elprimero * float(takeProfit) * contracts
            else:
                profitOrLoss = takeProfit * contracts

            profitOrLossParcial.append("{:.2f}".format(profitOrLoss))
        else:
            listaparcial.append("B")
            TPMinutesParcial.append("")

            if dollarOrPercen == "P":
                profitOrLoss = elprimero * float(stopLoss) * contracts
            else:
                profitOrLoss = stopLoss * contracts

            profitOrLossParcial.append("{:.2f}".format(profitOrLoss))

    return listaparcial, creditoParcial, TPMinutesParcial, profitOrLossParcial


# def obtenerBestPair(estrategia, dollarOrPerc, newsDays, resultsIn, contracts, offset, sinceDate, untilDate):

#     print ("estraaaa",estrategia)
#     estrategia_archivo_map = {
#         '1': 'IBData0940NoResults.csv',
#         '2': 'IBData1030NoResults.csv',
#         '3': 'IBData1100NoResults.csv',
#         '4': 'IBData1130NoResults.csv',
#         '5': 'IBData0932NoResults.csv',
#         '6': 'IBData0933NoResults.csv',
#         '7': 'ICData0932NoResults.csv',
#         '8': 'ICData1030NoResults.csv'

#     }
#     archivo_csv = PATH_UBUNTU + estrategia_archivo_map[estrategia]
#     resultsList = []

#     if dollarOrPerc == "P":
#         listaTP = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
#         listaSL = [-5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19]
#         # listaTP = [5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16, 16.5, 17, 17.5, 18, 18.5, 19]
#         # listaSL = [-5, -5.5, -6, -6.5, -7, -7.5, -8, -8.5, -9, -9.5, -10, -10.5, -11, -11.5, -12, -12.5, -13, -13.5, -14, -14.5, -15, -15.5, -16, -16.5, -17, -17.5, -18, -18.5, -19]
#     else:
#         # listaTP = [60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450]
#         # listaSL = [-60, -70, -80, -90, -100, -110, -120, -130, -140, -150, -160, -170, -180, -190, -200, -210, -220, -230, -240,-250,-260,-270,-280,-290,-300,-310,-320,-330,-340,-350,-360,-370,-380,-390,-400,-410,-420,-430,-440,-450]

#         listaTP = [40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320]
#         listaSL = [-50, -70, -90, -110, -130, -150, -170, -190, -210, -230, -250, -270, -290, -310, -330]

#     archivo_holidays = PATH_UBUNTU + "holidays.csv"
#     df1 = pd.read_csv(archivo_holidays, header=None)
#     lista_de_fechas = df1.iloc[:, 0].tolist()
#     df = pd.read_csv(archivo_csv, low_memory=False)
#     dfLista = df.columns.tolist()
#     solo_Fechas = dfLista[0::4]
#     fecha_begin_obj = datetime.strptime(sinceDate, "%m/%d/%Y")
#     fecha_end_obj = datetime.strptime(untilDate, "%m/%d/%Y")
#     rangoCreditoDesde = 0
#     rangoCreditoHasta = 999999
#     for tp1 in listaTP:
#         for sl1 in listaSL:
#             totalGOODs = 0
#             totalBADs = 0
#             sumGOODs = 0
#             sumBADs = 0
#             columna_indice = 0
#             dataIB = []
#             for fecha in solo_Fechas:
#                 fecha_obj = datetime.strptime(fecha, "%m/%d/%Y")
#                 if fecha_obj >= fecha_begin_obj and fecha_obj <= fecha_end_obj:
#                     if (newsDays or (not newsDays and fecha not in lista_de_fechas)):
#                         cantidad_filas = df.iloc[:, columna_indice].count()
#                         onlyDF = df.iloc[0:cantidad_filas,
#                                          columna_indice:columna_indice+3]
#                         elprimero = onlyDF.iloc[0, 1] - offset
#                         if elprimero > rangoCreditoDesde and elprimero < rangoCreditoHasta:
#                             onlyDF['P/L'] = elprimero - onlyDF.iloc[:, 1]
#                             onlyDF['P/L%'] = onlyDF.iloc[:, 3] / elprimero
#                             profitOrLoss, goodOrBad = getTotals(tp1, sl1, onlyDF, offset, dollarOrPerc)

#                             if goodOrBad == "GOOD":
#                                 totalGOODs = totalGOODs + 1
#                                 sumGOODs = sumGOODs + profitOrLoss
#                             else:
#                                 totalBADs = totalBADs + 1
#                                 sumBADs = sumBADs + profitOrLoss

#                             dataIB.append(profitOrLoss*contracts)

#                 columna_indice += 4

#             if resultsIn == 'EV':
#                 # Obteniendo el EV de cada par !!!
#                 expectationValue = 0
#                 totalDays = totalGOODs + totalBADs
#                 aciertosPercent = totalGOODs / totalDays
#                 erroresPercent = totalBADs / totalDays
#                 if totalGOODs > 0:
#                     mediaGOODs = sumGOODs / totalGOODs

#                 if totalBADs > 0:
#                     mediaBADs = abs(sumBADs / totalBADs)

#                 ratio = mediaGOODs / mediaBADs
#                 expectationValue = (ratio * aciertosPercent) - erroresPercent
#                 # Son necesarios los extra parentesis!!!
#                 resultsList.append((tp1, sl1, expectationValue))
#             else:
#                 # Son necesarios los extra parentesis!!!
#                 resultsList.append((tp1, sl1, sum(dataIB)))

#     return resultsList


def getTotals(takeProfit, stopLoss, onlyDF, offset, dollarOrPerc):

    multiplier = 1 if dollarOrPerc == "D" else 0.01

    takeProfit *= multiplier
    stopLoss *= multiplier

    # Busca la hora del 1er TP
    if dollarOrPerc == "P":
        fila_indiceTP = (onlyDF.iloc[:, 4] > takeProfit).idxmax()
    else:
        fila_indiceTP = (onlyDF.iloc[:, 3] > takeProfit).idxmax()

    # Busca la hora del 1er SL
    if dollarOrPerc == "P":
        fila_indiceSL = (onlyDF.iloc[:, 4] < stopLoss).idxmax()
    else:
        fila_indiceSL = (onlyDF.iloc[:, 3] < stopLoss).idxmax()

    credito = round(float(onlyDF.iloc[0, 1]), 2) - offset

    if fila_indiceSL == 0:
        fila_indiceSL = 999999

    if fila_indiceTP == 0:
        fila_indiceTP = 999999

    if fila_indiceTP < fila_indiceSL:
        goodOrBad = "GOOD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit
    else:
        goodOrBad = "BAD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    if fila_indiceSL == 999999:
        goodOrBad = "GOOD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit

    if fila_indiceTP == 999999:
        goodOrBad = "BAD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    return (ProfitOrLoss, goodOrBad)


def obtenerBestPair(estrategia, dollarOrPerc, newsDays, resultsIn, contracts, offset, sinceDate, untilDate):

    estrategia_archivo_map = {
        '1': 'IBData0940NoResults.csv',
        '2': 'IBData1030NoResults.csv',
        '3': 'IBData1100NoResults.csv',
        '4': 'IBData1130NoResults.csv',
        '5': 'IBData0932NoResults.csv',
        '6': 'IBData0933NoResults.csv',
        '7': 'ICData0932NoResults.csv',
        '8': 'ICData1030NoResults.csv',
        '9': 'ICData0933NoResults.csv',
        '10': 'ICData1031NoResults.csv'
    }
    archivo_csv = PATH_UBUNTU + estrategia_archivo_map[estrategia]
    resultsList = []

    if dollarOrPerc == "P":
        listaTP = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
        listaSL = [-5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19]
        # listaTP = [5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16, 16.5, 17, 17.5, 18, 18.5, 19]
        # listaSL = [-5, -5.5, -6, -6.5, -7, -7.5, -8, -8.5, -9, -9.5, -10, -10.5, -11, -11.5, -12, -12.5, -13, -13.5, -14, -14.5, -15, -15.5, -16, -16.5, -17, -17.5, -18, -18.5, -19]
    else:
        # listaTP = [60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230,240,250,260,270,280,290,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450]
        # listaSL = [-60, -70, -80, -90, -100, -110, -120, -130, -140, -150, -160, -170, -180, -190, -200, -210, -220, -230, -240,-250,-260,-270,-280,-290,-300,-310,-320,-330,-340,-350,-360,-370,-380,-390,-400,-410,-420,-430,-440,-450]

        listaTP = [40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320]
        listaSL = [-50, -70, -90, -110, -130, -150, -170, -190, -210, -230, -250, -270, -290, -310, -330]

    archivo_holidays = PATH_UBUNTU + "holidays.csv"
    df1 = pd.read_csv(archivo_holidays, header=None)
    lista_de_fechas = df1.iloc[:, 0].tolist()
    df = pd.read_csv(archivo_csv, low_memory=False)
    dfLista = df.columns.tolist()
    # dfCreditos = df.iloc[0].tolist()

    solo_Fechas = dfLista[0::4]

    # solo_Creditos = dfCreditos[1::4]
    # solo_Creditos = dfCreditos[1::4]

    fecha_begin = sinceDate
    fecha_end = untilDate
    fecha_begin_obj = datetime.strptime(fecha_begin, "%m/%d/%Y")
    fecha_end_obj = datetime.strptime(fecha_end, "%m/%d/%Y")
    rangoCreditoDesde = 0
    rangoCreditoHasta = 999999
    for tp1 in listaTP:
        for sl1 in listaSL:
            totalGOODs = 0
            totalBADs = 0
            sumGOODs = 0
            sumBADs = 0
            columna_indice = 0
            dataIB = []
            for fecha in solo_Fechas:
                fecha_obj = datetime.strptime(fecha, "%m/%d/%Y")
                if fecha_obj >= fecha_begin_obj and fecha_obj <= fecha_end_obj:
                    if (newsDays or (not newsDays and fecha not in lista_de_fechas)):
                        cantidad_filas = df.iloc[:, columna_indice].count()
                        onlyDF = df.iloc[0:cantidad_filas,
                                         columna_indice:columna_indice+3]
                        elprimero = onlyDF.iloc[0, 1] - offset
                        if elprimero > rangoCreditoDesde and elprimero < rangoCreditoHasta:
                            onlyDF['P/L'] = elprimero - onlyDF.iloc[:, 1]
                            onlyDF['P/L%'] = onlyDF.iloc[:, 3] / elprimero
                            profitOrLoss, goodOrBad = getTotals(
                                tp1, sl1, onlyDF, offset, dollarOrPerc)

                            if goodOrBad == "GOOD":
                                totalGOODs = totalGOODs + 1
                                sumGOODs = sumGOODs + profitOrLoss
                            else:
                                totalBADs = totalBADs + 1
                                sumBADs = sumBADs + profitOrLoss

                            dataIB.append(profitOrLoss*contracts)

                columna_indice += 4

            if resultsIn == 'EV':
                # Obteniendo el EV de cada par !!!
                expectationValue = 0
                totalDays = totalGOODs + totalBADs
                aciertosPercent = totalGOODs / totalDays
                erroresPercent = totalBADs / totalDays
                if totalGOODs > 0:
                    mediaGOODs = sumGOODs / totalGOODs

                if totalBADs > 0:
                    mediaBADs = abs(sumBADs / totalBADs)

                ratio = mediaGOODs / mediaBADs
                expectationValue = (ratio * aciertosPercent) - erroresPercent
                # Son necesarios los extra parentesis!!!
                resultsList.append((tp1, sl1, expectationValue))
            else:
                # Son necesarios los extra parentesis!!!
                resultsList.append((tp1, sl1, sum(dataIB)))

    return resultsList


def getTotals(takeProfit, stopLoss, onlyDF, offset, dollarOrPerc):

    multiplier = 1 if dollarOrPerc == "D" else 0.01

    takeProfit *= multiplier
    stopLoss *= multiplier

    # Busca la hora del 1er TP
    if dollarOrPerc == "P":
        fila_indiceTP = (onlyDF.iloc[:, 4] > takeProfit).idxmax()
    else:
        fila_indiceTP = (onlyDF.iloc[:, 3] > takeProfit).idxmax()

    # Busca la hora del 1er SL
    if dollarOrPerc == "P":
        fila_indiceSL = (onlyDF.iloc[:, 4] < stopLoss).idxmax()
    else:
        fila_indiceSL = (onlyDF.iloc[:, 3] < stopLoss).idxmax()

    credito = round(float(onlyDF.iloc[0, 1]), 2) - offset

    if fila_indiceSL == 0:
        fila_indiceSL = 999999

    if fila_indiceTP == 0:
        fila_indiceTP = 999999

    if fila_indiceTP < fila_indiceSL:
        goodOrBad = "GOOD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit
    else:
        goodOrBad = "BAD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    if fila_indiceSL == 999999:
        goodOrBad = "GOOD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * takeProfit
        else:
            ProfitOrLoss = takeProfit

    if fila_indiceTP == 999999:
        goodOrBad = "BAD"
        if dollarOrPerc == "P":
            ProfitOrLoss = credito * stopLoss
        else:
            ProfitOrLoss = stopLoss

    return (ProfitOrLoss, goodOrBad)


def obtener_datos_best_pair():
    # Lee el archivo CSV utilizando pandas
    archivo_csv = '/var/www/html/spxbutterflies/resultados.csv'
    try:

        df = pd.read_csv(archivo_csv)
    except FileNotFoundError:
        return jsonify({"error": "Archivo CSV no encontrado"})

    fecha_creacion = os.path.getctime(archivo_csv)
    fecha_formateada = datetime.fromtimestamp(
        fecha_creacion).strftime('%m/%d/%Y')

    # Convierte el DataFrame a un diccionario en formato JSON
    datos = df.to_dict(orient='records')
    # Agregar la fecha de creación al diccionario
    datos = {"fecha_creacion": fecha_formateada, "datos": datos}

    return jsonify(datos)


def registrar_log(user_id):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_data = [user_id, timestamp]
    archivo_csv = '/var/www/html/spxbutterflies/static/data/ingresos.csv'
    # Escribe la información en el archivo CSV
    with open(archivo_csv, 'a', newline='') as csvfile:
        csv_writer = csv.writer(csvfile)
        csv_writer.writerow(log_data)


def send_email_(subject, body, username, token, tipoEmail):
    # Configura tu servidor de correo electrónico y credenciales
    email_server = 'smtp.titan.email'
    email_port = 587
    email_username = 'info@spxbutterflies.com'
    email_password = 'Daleriver11$s'
    print("SENDING EMAIL...")

    # Configura el correo electrónico
    sender_name = 'SPX Butterflies'
    sender_email = 'info@spxbutterflies.com'
    receiver_email = username

    message = MIMEMultipart()
    message['From'] = f'{sender_name} <{sender_email}>'
    message['To'] = receiver_email
    message['Subject'] = subject

    if tipoEmail == "ResetPassword":
        reset_password_link = f"https://spxbutterflies.com/reset_password?token={token}"
    if tipoEmail == "FreeTrial":
        # reset_password_link = f"http://127.0.0.1:5000/validate_email?token={token}&username={username}"
        reset_password_link = f"https://spxbutterflies.com/validate_email?token={token}&username={username}"

    body_with_link = f"{body}\n{reset_password_link}"

    message.attach(MIMEText(body_with_link, 'plain'))

    # Conéctate al servidor de correo electrónico y envía el mensaje
    with smtplib.SMTP(email_server, email_port) as server:
        server.starttls()
        server.login(email_username, email_password)
        server.sendmail(sender_email, receiver_email, message.as_string())


def send_email_general(subject, firstName, lastName, receiptEmail, body):
    # Configura tu servidor de correo electrónico y credenciales
    email_server = 'smtp.titan.email'
    email_port = 587
    email_username = 'info@spxbutterflies.com'
    email_password = 'Daleriver11$s'

    # Configura el correo electrónico
    sender_name = firstName + " " + lastName
    sender_email = email_username
    receiver_email = receiptEmail

    message = MIMEMultipart()
    message['From'] = f'{sender_name} <{sender_email}>'
    message['To'] = receiver_email
    message['Subject'] = subject

    message.attach(MIMEText(body, 'plain'))

    # Conéctate al servidor de correo electrónico y envía el mensaje
    with smtplib.SMTP(email_server, email_port) as server:
        server.starttls()
        server.login(email_username, email_password)
        server.sendmail(sender_email, receiver_email, message.as_string())


def get_alert_data():
    archivo_csv = PATH_UBUNTU + "/alerts/alerts.csv"

    # Leer el contenido del archivo CSV y convertirlo a una lista de diccionarios
    with open(archivo_csv, 'r', newline='') as file:
        csv_reader = csv.DictReader(file)
        csv_data = list(csv_reader)

    # Devolver los datos como JSON
    return jsonify(csv_data)
