import time
import os
#import subprocess
import sys
#import webbrowser

os.environ['OPENBLAS_NUM_THREADS'] = '1'

#import pandas as pd

#import Tickers
import Data
import Screener
#import DiscordAndUtilities
from DiscordAndUtilities import *

import asyncio
from apscheduler.schedulers.asyncio import AsyncIOScheduler


#--------------------------
ON_UI_OFFICIAL=False

SCHEDULER_ON=False #IF FALSE => 1 time TASK only then define weekly and monthly screening according the needs
weekly_screening=True
monthly_screening=True

CAP_QUANTILE=0.2
VOL_QUANTILE=0.4
MAX_LISTED=20

ACCEPTABLE_NR_OF_INVALID_TICKERS=1000
#--------------------------


#SERVEUR DISCORD PERSO
TOKEN_PERSO = "MTA5MTczMjg3OTU3NjQxMjI3MA.Gs42zb.gonFNMfxDLVpUOB5y6K2K18mB-si6zl9bQa8FI" # Jerome
# TOKEN_PERSO = "MTA2MjE2NTMwMzEzNzY4MTUxOQ.GkJrJ7.w8sx9YM17NGrXAfTjwO3Unxr3i_VYd7DqL62nU"
CHANNEL_ID_PERSO = 1101740958669877268
CHANNEL_ID_PERSO2 = 1091736379504996377
# CHANNEL_ID_PERSO = 1175744266681724949
# CHANNEL_ID_PERSO2 = 1175744266681724949
TOKEN_FOR_LOG=TOKEN_PERSO
CHANNEL_ID_FOR_LOG = CHANNEL_ID_PERSO

#SERVEUR DISCORD UI
# TOKEN_UI = "MTA5OTc0Nzc1MzAwMjgwMzI2MA.GmAHV0._Q5Q8Pzs08MLwPg-HRIM9D_7F8Be_FaGuLgeEg" #prod
TOKEN_UI = "MTA2MjE2NTMwMzEzNzY4MTUxOQ.GkJrJ7.w8sx9YM17NGrXAfTjwO3Unxr3i_VYd7DqL62nU" #mk
# -- UI CHANNEL TEST-TRADING ID
# CHANNEL_ID_UI_TESTS_ADMIN_ONLY = 1099986033241755699 #prod
CHANNEL_ID_UI_TESTS_ADMIN_ONLY = 1175744266681724949 #mk
# -- UI CHANNEL OFFICIAL ID
# CHANNEL_ID_UI_OFFICIAL = 1098959808478072844 #prod
CHANNEL_ID_UI_OFFICIAL = 1175744266681724949 #mk

#SELECTED TOKENS
if ON_UI_OFFICIAL:
    TOKEN = TOKEN_UI
    CHANNEL_ID = CHANNEL_ID_UI_OFFICIAL
else:
    TOKEN = TOKEN_PERSO
    CHANNEL_ID = CHANNEL_ID_PERSO2



#INPUTS FOLDER - IF PDF
#REEXTRACT_TICKER_FROM_PDF=False 
#LIMITED_TO_NR_OF_TICKERS=0 #if nr of ticker TO BE ANALYZED should be limited, 0 if not # IF PDF
# link to file is https://content.ftserussell.com/sites/default/files/ru3000_membershiplist_20210628.pdf 
# (if link changed : search on Google for "FTSE RUSSEL3000 MEMBERSHIP LIST")
#source_pdf = '0-INPUTS/ru3000_PURIFIED.pdf' #IF PDF

#INPUTS FOLDER - IF CSV
#tickers_csv = '0-INPUTS/0-Tickers_extracted-limited.csv'
tickers_csv = '0-INPUTS/0-Tickers_extracted.csv'
SEPARATOR=";" 

#INTERMEDIATE FOLDER
REDOWNLOAD_DATA=True  #IF FALSE -> WILL REUSE the Data-retrieved file in INTERMEDIATE FOLDER
FORCED_TO_REDOWNLOAD = False #IF TRUE, WILL REDOWNLOAD EVEN IF the data were retrieved for less than 3 hours ago
extracted_data = '1-INTERMEDIATE/2-SCLV-Data-retrieved.csv'
REDIRECT_LOG=True
log_file="1-INTERMEDIATE/1-Log.txt"
#log_file_xl="1-INTERMEDIATE/1-Log IF SCRIPT ENDED.xlsx"

#OUTPUT FOLDER
#OPEN_FILES=False #only for 1 shot main task i.e. when schedule is OFF i.e. for debug
W_output_csv = '2-OUTPUTS/3-SCLV-Weekly-screened.csv' 
M_output_csv = '2-OUTPUTS/3-SCLV-Monthly-screened.csv' 
W_output_image="2-OUTPUTS/3-SCLV-Weekly-screened.png"
M_output_image="2-OUTPUTS/3-SCLV-Monthly-screened.png"
Delivery_directory = '2-OUTPUTS/z-DeliveryHistory/'

async def my_main_task(p_weekly_screening, p_monthly_screening, p_TOKEN, p_CHANNEL_ID):

    if REDIRECT_LOG==True:
        #open and clear the log file
        log = open(log_file, "w")
        sys.stdout = log

    data_already_extracted=False
    try:
        file_modified_time = os.path.getmtime(extracted_data)
        current_time = time.time()
        data_already_extracted=os.path.getsize(extracted_data) > 0

    except Exception as e:
        None

    error = None
    if REDOWNLOAD_DATA == True and (FORCED_TO_REDOWNLOAD or not data_already_extracted or ((current_time - file_modified_time) >= 3 * 60 * 60)):
        # extract tickers from PDF 
        #if REEXTRACT_TICKER_FROM_PDF==True:
        #    Tickers.extract_tickers_from_pdf(source_pdf, extracted_csv, LIMITED_TO_NR_OF_TICKERS) 

        # get stock data and screen 
        error = await asyncio.to_thread(Data.get_data, tickers_csv, SEPARATOR, extracted_data, ACCEPTABLE_NR_OF_INVALID_TICKERS)     
        
        
    if error==None:
        # screen and format 
        unused_df, error_w, error_m = await asyncio.to_thread(Screener.screen, extracted_data, SEPARATOR, W_output_csv, M_output_csv, Delivery_directory, CAP_QUANTILE, VOL_QUANTILE,p_weekly_screening, p_monthly_screening, MAX_LISTED)

        # Notify
        if p_weekly_screening:
            if error_w==None:
                result = await generate_image(W_output_csv, W_output_image, SEPARATOR)
                if result == 0:
                    await send_discord_notification(p_TOKEN, p_CHANNEL_ID, f"@everyone - Résulats screening HEBDO", W_output_image)
                else:
                    print (f"Problem for creating picture for Hebdo results : {W_output_image}")
                    await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, f"Problem for creating picture for Hebdo results : {W_output_image}")
            else:
                print ("Hebdo screened list is empty, no ticker to be reported")
                await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, "Hebdo screened list is empty, no ticker to be reported")
                await send_discord_notification(p_TOKEN, p_CHANNEL_ID, f"@everyone - Résulats screening HEBDO : aucun titre à reporter cette semaine")
            
            
        if p_monthly_screening:
            
            if error_m==None:
                result = await generate_image(M_output_csv, M_output_image, SEPARATOR)
                if result == 0:
                    await send_discord_notification(p_TOKEN, p_CHANNEL_ID, f"@everyone - Résulats screening MENSUEL", M_output_image)
                else:
                    print (f"Problem for creating picture for Monthly results : {M_output_image}")
                    await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, f"Problem for creating picture for Monthly results : {M_output_image}")
            else:
                print ("Monthly screened list is empty, no ticker to be reported")
                await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, "Monthly screened list is empty, no ticker to be reported")
                await send_discord_notification(p_TOKEN, p_CHANNEL_ID, f"@everyone - Résulats screening MENSUEL : aucun titre à reporter ce mois-ci")

        if REDIRECT_LOG==True:
            log.close()
            sys.stdout = sys.__stdout__
        
        await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, f"LOG", file_path=log_file)
    else:
        await send_discord_notification(TOKEN_FOR_LOG, CHANNEL_ID_FOR_LOG, f"LOG -> Too many invalid tickers, screening aborted", file_path=log_file)


#MAIN PROGRAM

#pythoncom.CoInitialize()

if not SCHEDULER_ON:
    asyncio.run(my_main_task(weekly_screening, monthly_screening, TOKEN, CHANNEL_ID))

else:
    scheduler = AsyncIOScheduler(timezone="Europe/Berlin")

    #WATCH DOG
    scheduler.add_job(my_main_task, 'cron', day_of_week='Mon-Fri', hour=8, minute=00, second='00-05', args=[True, True, TOKEN_PERSO, CHANNEL_ID_PERSO])
    #scheduler.add_job(my_main_task, 'cron', day_of_week='Mon-Fri', hour=20, minute=00, second='00-05', args=[False, True, TOKEN_PERSO, CHANNEL_ID_PERSO])

    #OFFICIAL DELIVERY
    #End of the week
    scheduler.add_job(my_main_task, 'cron', day_of_week='Sat', hour=8, minute=00, second='00-05', args=[True, False, TOKEN, CHANNEL_ID])
    #End of the month
    scheduler.add_job(my_main_task, 'cron', day='last', hour=22, minute=15, second='00-05', args=[False, True, TOKEN, CHANNEL_ID])  

    scheduler.start()

    # Use an asyncio.Event to keep the script running indefinitely
    stop_event = asyncio.Event()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(
        stop_event.wait()
    ))
