import os
import time
import logging
import hashlib
from datetime import datetime, timezone
from thefirstock import thefirstock  # Ensure you have the necessary imports
import pytz

# Global variables
MAX_TIME_DIFF_MINUTES = 3  # Set the maximum allowed time difference in minutes
SKIP_TIME_CHECK = False  # Flag to skip time check if set to True

# Setup logging
# Set IST timezone
ist = pytz.timezone('Asia/Kolkata')

# Custom formatter to convert time to IST
class ISTFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        record_time = datetime.fromtimestamp(record.created, tz=ist)
        return record_time.strftime(datefmt or '%Y-%m-%d %H:%M:%S')

# Set up global logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.propagate = False

formatter = ISTFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

# Directory to monitor
directory = '/var/www/html/BUY'


# Client details for login
clientDetails = ['DB1485', '$L10n-one', '14121985', 'DB1485_API', 'e64881301306ce087b1108a74e174e82']
clientDetails = ['TT1582', 'O9i8u7y6##', '15111982', 'TT1582_API', '2870345ba219a19d227e163efbe0a08b']
clientDetails = ['RA1383', 'O9i8u7y6##', '13061983', 'RA1383_API', '491bf9166cfe0e7c419ac071f3fca6e1']
userId = clientDetails[0]
clientRootFolder = f'/var/www/html/clientData/{userId}'

# Set to keep track of processed file hashes
processed_file_hashes = set()

def hash_filename(filename):
    """Generate a SHA-256 hash for the filename."""
    return hashlib.sha256(filename.encode()).hexdigest()

def login(client):
    userId = client[0]
    password = client[1]
    TOTP = client[2]
    vendorCode = client[3]
    apiKey = client[4]

    logger.info("Attempting to login")
    login_response = thefirstock.firstock_login(
        userId=userId,
        password=password,
        TOTP=TOTP,
        vendorCode=vendorCode,
        apiKey=apiKey
    )
    if login_response['status'] == 'success':
        logger.info("Login successful")
    else:
        logger.error("Login failed: %s", login_response)

def place_order(filename):
    parts = filename.split('_')
    
    if len(parts) >= 4:
        file_time = parts[0]
        trading_symbol = parts[1]
        open_price = parts[2]
        close_price = parts[3]
        
        # Generate the hash based on file_time, trading_symbol, and open_price
        hash_input = f"{file_time}_{trading_symbol}_{open_price}"
        file_hash = hash_filename(hash_input)
        
        # Check if the file has already been processed
        if file_hash in processed_file_hashes:
            logger.info(f"File {filename} already processed. Skipping.")
            return
        
        logger.info(f"File Time: {file_time}")
        logger.info(f"Trading Symbol: {trading_symbol}")
        logger.info(f"Open Price: {open_price}")
        logger.info(f"Close Price: {close_price}")
        
        # Add the file hash to the set of processed hashes
        processed_file_hashes.add(file_hash)

        if trading_symbol.startswith("BANKNIFTY"):
            quantity = "15"
        elif trading_symbol.startswith("FINNIFTY"):
            quantity = "25"
        elif trading_symbol.startswith("NIFTY"):
            quantity = "25"
        elif trading_symbol.startswith("MIDCPNIFTY"):
            quantity = "50"
        else:
            quantity = "10"  # Default quantity or handle as needed

        logger.info(f"Placing order with params: userId={userId}, exchange=NFO, tradingSymbol={trading_symbol}, quantity={quantity}, price={close_price}, product=M, transactionType=B, priceType=MKT, retention=DAY, triggerPrice=0, remarks=Python Package Order")

        placeOrder = thefirstock.firstock_placeOrder(
            userId=userId,
            exchange="NFO",
            tradingSymbol=trading_symbol,
            quantity=quantity,
            price="0.0",
            product="M",
            transactionType="B",
            priceType="MKT",
            retention="DAY",
            triggerPrice="0",
            remarks="Python Package Order"
        )

        logger.info(f"Order response: \n{placeOrder}")
        
    else:
        logger.warning(f"Filename format is unexpected: {filename}")


def get_file_info():
    current_time = datetime.now(timezone.utc)
    
    # List files in the directory
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        
        # Ensure it's a file
        if os.path.isfile(filepath):
            # Get the file creation time
            creation_time = os.path.getctime(filepath)
            creation_time_dt = datetime.fromtimestamp(creation_time, timezone.utc)
            
            # Calculate the time difference in minutes
            time_diff = current_time - creation_time_dt
            time_diff_minutes = time_diff.total_seconds() / 60
            
            # Check if the file should be processed based on time difference and flag
            if SKIP_TIME_CHECK or time_diff_minutes <= MAX_TIME_DIFF_MINUTES:
                logger.debug(f"Processing file: {filename}")
                logger.debug(f"Creation Time: {creation_time_dt.strftime('%Y-%m-%d %H:%M:%S %Z')}")
                logger.debug(f"Time Difference: {time_diff_minutes:.2f} minutes")
                
                # Call place_order function to handle filename splitting and processing
                place_order(filename)
            else:
                logger.debug(f"File: {filename} skipped (Time difference: {time_diff_minutes:.2f} minutes)")

if __name__ == "__main__":

    os.chdir(clientRootFolder)


    # Login before processing files
    login(clientDetails)
    
    # Monitor directory for files
    while True:
        get_file_info()
        # Sleep for a while before checking again
        time.sleep(10)
