import pandas as pd
import logging
from thefirstock import thefirstock
from utils.dbConnector import mySqlConnector
from utils.config import MasterDetails, GENRIC
import sys
import time
import os
import pprint
from datetime import datetime
import pytz

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

class ISTFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        # Set timezone to IST
        ist = pytz.timezone('Asia/Kolkata')
        record_time = datetime.fromtimestamp(record.created, tz=ist)
        return record_time.strftime(datefmt or '%Y-%m-%d %H:%M:%S')

class MasterManager:
    def __init__(self):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.setLevel(logging.INFO)  
        self.logger.propagate = False

        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        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)  
        self.logger.addHandler(console_handler)
        
        # File handler
        file_handler = logging.FileHandler('/var/www/html/log/master_manager.log')
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)

        self.logger.info("Initializing MasterManager")

        self.user_id = MasterDetails.userId
        self.password = MasterDetails.password
        self.TOTP = MasterDetails.TOTP
        self.vendor_code = MasterDetails.vendorCode
        self.api_key = MasterDetails.apiKey

        self.clientRootFolder = GENRIC.clientRootFolder.replace(GENRIC.replace_str, self.user_id )
        os.system(f'mkdir -p {self.clientRootFolder}')
        os.system(f'chmod 777 {self.clientRootFolder}')

        self.positionInputFile = os.path.join(self.clientRootFolder, GENRIC.positionInputFile)
        self.positionProcessedFile = os.path.join(self.clientRootFolder, GENRIC.positionProcessedFile)

        os.chdir(self.clientRootFolder)

        self.login()

        self.db_connector = mySqlConnector()
        self.setUpDatabase()
        


    def login(self):
        self.logger.info("Attempting to login")
        login_response = thefirstock.firstock_login(
            userId=self.user_id,
            password=self.password,
            TOTP=self.TOTP,
            vendorCode=self.vendor_code,
            apiKey=self.api_key
        )
        if login_response['status'] == 'success':
            self.logger.info("Login successful")
        else:
            self.logger.error("Login failed: %s", login_response)
            sys.exit(1)

    def setUpDatabase(self):
        self.logger.info("Setting up database")
        self.db_connector.createPrimaryOrderBookTable()

    def storePostition(self):
        self.logger.debug("Fetching position data")

        try:
            position_book = thefirstock.firstock_PositionBook(self.user_id)
            
            if position_book['status'] == 'success':
                df = pd.DataFrame(position_book['data'])
                self.logger.debug("Position book data:\n%s", df)
                df.to_csv(self.positionInputFile, index=False)
                os.system(f'cp {self.positionInputFile} {self.positionProcessedFile}')
            else:
                self.logger.info(f"Position book data status is not success. {position_book['status']}")

        except Exception as e:
            self.logger.error("An exception occurred while storing the position: %s", str(e))


    def fetch_order_book(self):

        self.logger.debug("Fetching order book data")
        dataInsertedOrUpdated = False
        
        try:
            order_book = thefirstock.firstock_orderBook(self.user_id)

            if order_book['status'] == 'success':
                # Check if data count is more than zero
                if len(order_book['data']) > 0:
                    # Convert data to DataFrame and log it
                    df = pd.DataFrame(order_book['data'])
                    df_sorted = df.sort_values(by='orderNumber')
                    df_markdown = df_sorted.to_markdown(index=False)
                    self.logger.debug("Order book data:\n%s", df_markdown)

                    try:
                        # Insert data into the database
                        dataInsertedOrUpdated = self.db_connector.insertOrUpdatePrimaryOrderBookData(df_sorted)
                    except Exception as e:
                        self.logger.error("An exception occurred while inserting order book data: %s", str(e))
                else:
                    self.logger.debug(f"Order book data status is success but empty. {order_book}")
            else:
                self.logger.error(f"Order book data status is NOT success. {order_book}")
        
        except Exception as e:
            self.logger.error("An exception occurred while fetching the order book: %s", str(e))


        
        return dataInsertedOrUpdated



# Usage
if __name__ == "__main__":

    master_manager = MasterManager()
    counter = 0
    

    while True:
        logging.debug(f"counter =. {counter}")
        dataInsertedOrUpdated = master_manager.fetch_order_book()
        
        if counter % GENRIC.postionRefreshElapseIterations == 0 or dataInsertedOrUpdated:
            master_manager.storePostition()
            counter = 0
        else:
            counter += 1

        time.sleep(GENRIC.masterDetailsRefreshTimeout)


