import json
import sys
import base64
import time
from __config import CONFIG
from datetime import datetime, timezone, timedelta
import math
import re
import os


hideDisplayingPrice = False


ohlcRow = '''
    <div class="row mt-4 mb-4 justify-content-center removableRow">
        <div class="col-md-2 mt-2 border border-dark border-thick">
            <div class="row justify-content-center border-bottom border-dark">
                <div class="col text-center border-info bg-info text-white"><strong>Price</strong></div>
            </div>
            <div class="row justify-content-center border-bottom border-dark">
                <div class="col text-center border-info bg-info text-white"><strong>__currentPrice__</strong></div>
            </div>
        </div>
    </div>
    <div class="row justify-content-center removableRow">
        <div class="col-md-6 mt-2 border border-dark">
            <div class="row justify-content-center border-bottom border-dark">
                <div class="col text-center border-right border-dark"><strong>Close</strong></div>
                <div class="col text-center border       border-warning border-thick"><strong>Open</strong></div>
                <div class="col text-center border-right border-dark"><strong>High</strong></div>
                <div class="col text-center border-dark"><strong>Low</strong></div>
            </div>
            <div class="row justify-content-center border-bottom border-dark ">
                <div class="col text-center border-right border-dark"><strong>__close__</strong></div>
                <div class="col text-center border       border-warning border-thick"><strong>__open__</strong></div>
                <div class="col text-center border-right border-dark"><strong>__high__</strong></div>
                <div class="col text-center border-dark"><strong>__low__</strong></div>
            </div>
        </div>
    </div>
    '''

row1 = '''
    <div class="row border border-dark mt-4 ">
        <div class="col-4 border-right border-dark"> <!-- Empty cell for spacing --></div>
        <div class="col-4 border-bottom border-right border-dark __bg1__"><strong>__expiry1__</strong></div>
        <div class="col-4 border-bottom border-dark __bg3__"><strong>__expiry2__</strong></div>
    </div>
    '''

rowXHeader = '''
    <div class="row border border-dark">
        <div class="col-4 border-right border-dark"><strong>Strike Price</strong></div>
        <div class="col-2 border-right border-dark"><strong>Call</strong></div>
        <div class="col-2 border-right border-dark"><strong>Put</strong></div>
        <div class="col-2 border-right border-dark"><strong>Call</strong></div>
        <div class="col-2 border-dark"><strong>Put</strong></div>
    </div>
        '''

rowX = '''
    <div class="row border __border_color__">
        <div class="col-4 border-right border-dark border-thick">__StrikePrice__</div>
        <div class="col-2 border-right border-dark __rowCEPEMatch1__ __colorSchemaCE1__ __prevNextCE1__" sym="__expiryCE1__">__expiryPriceCE1__</div>
        <div class="col-2 border-right border-dark border-thick __rowCEPEMatch1__ __colorSchemaPE1__ __prevNextPE1__" sym="__expiryPE1__">__expiryPricePE1__</div>
        <div class="col-2 border-right border-dark __rowCEPEMatch2__ __colorSchemaCE2__ __prevNextCE2__" sym="__expiryCE2__">__expiryPriceCE2__</div>
        <div class="col-2 border-right border-dark border-thick __rowCEPEMatch2__ __colorSchemaPE2__ __prevNextPE2__" sym="__expiryPE2__">__expiryPricePE2__</div>
    </div>
        '''




class DATAHANDLER():

    def __init__(self, inputData):
        inputData = json.loads( base64.b64decode(inputData) ) 
        self.stockOptionsFile = self.getOriginalFileName( inputData["instrument"])
        self.isCloseBased = int(inputData["isCloseBased"])

        self.json_data = self.read_json_file(self.stockOptionsFile)

        self.setFactor()
        self.expirySymbolPreList = []
        self.strikePriceList = []


        self.debug = ''


    def read_json_file(self, file_path):
        with open(file_path, 'r') as file:
            data = json.load(file)
        return data

    def getOriginalFileName(self, formatted_instrument):
        # Parse the formatted instrument to extract name and date
        instrument, formatted_date = formatted_instrument.split(' (')
        formatted_date = formatted_date.rstrip(')')  # Remove closing parenthesis

        # Convert the formatted date back to the original format
        date_part = datetime.strptime(formatted_date, '%d%b%Y').strftime('%Y%m%d')

        # Reconstruct the original file name
        original_file_name = f"{date_part}_{instrument}.json"
        original_file_name = os.path.join(CONFIG.stock_options_folder , original_file_name)

        return original_file_name

    def getExpiryData(self):

        expiryDetails = self.json_data['expiry_date_list']
        
        returnData = row1
        i=1
        for expiry in expiryDetails:
            expiryReplaceStr = '__expiry'+ str(i) + '__'
            self.expirySymbolPreList.append(expiry)
            returnData = returnData.replace(expiryReplaceStr, expiry)
            i = i +1



        return returnData
    
    def getStikePriceData(self):
        strikePriceDetails = self.json_data['strike_prices']
        for strikePrice in strikePriceDetails:
            self.strikePriceList.append(strikePrice)

    def setFactor(self):
        self.factor = int(self.json_data['strike_prices'][1]) - int(self.json_data['strike_prices'][0])

    def nearest_multiple(self, value):
        factor = self.factor
        rounded_value = math.floor(value / factor) * factor
        if value % factor > factor / 2:
            rounded_value += factor
        #print(value , int(rounded_value), self.factor)
        return int(rounded_value)
    
    def round_decimal_places(self, value):
        decimal_places = value - int(value)
        rounded_decimal = round(decimal_places, 2)
        return rounded_decimal
    
    def getComplement(self):

        retVal = 0.0
        if self.sigDecimalClose == 0.0:
            retVal = 0.0
        else:
            retVal = 1.0 - self.sigDecimalClose
        self.sigDecimalCloseComplement = self.round_decimal_places(retVal)

    def getData(self):

       
        self.open = round(float(self.json_data['nearest_future']['ohlc']['open']), 2)
        self.high = round(float(self.json_data['nearest_future']['ohlc']['high']), 2)
        self.low = round(float(self.json_data['nearest_future']['ohlc']['low']), 2)
        self.close = round(float(self.json_data['nearest_future']['ohlc']['close']), 2)
        self.curPrice = round(float(self.json_data['nearest_future']['last_price']), 2)


        self.OpenStike = self.nearest_multiple(self.open)
        self.highStike = self.nearest_multiple(self.high)
        self.lowStike = self.nearest_multiple(self.low)
        self.curStike = self.nearest_multiple(self.curPrice)
        if self.isCloseBased:
            self.sigDecimalClose = self.round_decimal_places(self.close)
        else:
            self.sigDecimalClose = self.round_decimal_places(self.open)

        
        
        self.getComplement()


        myOhlcRow = ohlcRow.replace('__currentPrice__', str(self.curPrice))
        myOhlcRow = myOhlcRow.replace('__open__', str(self.open))
        myOhlcRow = myOhlcRow.replace('__high__', str(self.high))
        myOhlcRow = myOhlcRow.replace('__low__', str(self.low))
        myOhlcRow = myOhlcRow.replace('__close__', str(self.close))

        
        htmlCode = myOhlcRow + self.getExpiryData() + rowXHeader
      
        self.getStikePriceData()

        

        for strikePrice in self.strikePriceList:

            curRow = rowX.replace('__StrikePrice__',str(strikePrice))

            border_color = ' border-dark '

            if int(strikePrice) >= self.lowStike and int(strikePrice) <= self.highStike:
                border_color = ' border-dark bg-dark '
            
            if self.OpenStike == int(strikePrice):
                border_color = ' border-warning bg-dark border-thick'

            if self.curStike == int(strikePrice):
                border_color = ' border-dark bg-info text-white border-thick'
                if self.OpenStike == int(strikePrice):
                    border_color = ' border-warning bg-info text-white border-thick'


            curRow = curRow.replace('__border_color__',str(border_color))
            
            i=1
            for SymbolPre in self.expirySymbolPreList:
                
                symbolPrefix = str(strikePrice) +'_'+ SymbolPre 
                callDecimal = ''
                putDecimal = ''
                for symbolSuffix in ['CE', 'PE']:
                    symbol = symbolPrefix +'_' + symbolSuffix
                    
                    expiryReplaceStr = '__expiry' + str(symbolSuffix) + str(i)  + '__'
                    expiryPriceReplaceStr = '__expiryPrice' + str(symbolSuffix) + str(i)  + '__'
                    expiryColorSchemaReplaceStr = '__colorSchema' + str(symbolSuffix) + str(i)  + '__'
                    expiryprevNextReplaceStr = '__prevNext' + str(symbolSuffix) + str(i)  + '__'
                    expiryRowCEPEMatchReplaceStr = '__rowCEPEMatch' + str(i)  + '__'


                    prevOtSymbol = symbol.replace(str(strikePrice), str(int(strikePrice) - int(self.factor)))
                    nextOtSymbol = symbol.replace(str(strikePrice), str(int(strikePrice) + int(self.factor)))

                    price = self.json_data['trading_prices'][symbol]['close']
                    curPriceDecimal = self.round_decimal_places(float(price))
                    
                    try:
                        prevOtprice = self.json_data['trading_prices'][prevOtSymbol]['close']
                        prevOtpriceDecimal = self.round_decimal_places(float(prevOtprice))
                    except:
                        prevOtpriceDecimal = self.round_decimal_places(0.01)

                    try:
                        nextOtprice = self.json_data['trading_prices'][nextOtSymbol]['close']
                        nextOtpriceDecimal = self.round_decimal_places(float(nextOtprice))
                    except:
                        nextOtpriceDecimal = self.round_decimal_places(0.01)

                    prevNextValue = " "
                    if curPriceDecimal == self.sigDecimalClose or curPriceDecimal == self.sigDecimalCloseComplement:
                        if prevOtpriceDecimal == curPriceDecimal  or  nextOtpriceDecimal == curPriceDecimal:

                            if ( symbolSuffix == 'CE' and self.low < strikePrice ) or ( symbolSuffix == 'PE' and self.high > strikePrice):
                                prevNextValue = " bg-danger text-white "


                    curRow = curRow.replace(expiryprevNextReplaceStr, prevNextValue)

                    if symbolSuffix == 'CE':
                        callDecimal = self.round_decimal_places(float(price))
                    else:
                        putDecimal = self.round_decimal_places(float(price))
                        rowCEPEMatch = ' '
                        if callDecimal == putDecimal and (self.sigDecimalClose == callDecimal or self.sigDecimalCloseComplement == callDecimal):  
                            rowCEPEMatch = ' bg-danger text-white '

                        curRow = curRow.replace(expiryRowCEPEMatchReplaceStr, rowCEPEMatch)


                    curRow = curRow.replace(expiryReplaceStr, symbol)
                    if hideDisplayingPrice:
                        curRow = curRow.replace(expiryPriceReplaceStr, '')
                    else:
                        curRow = curRow.replace(expiryPriceReplaceStr, str(price))

                    colorSchema = ' '

                    if self.sigDecimalClose == self.round_decimal_places(float(price)):
                        colorSchema = ' bg-success text-white '
                    elif self.sigDecimalCloseComplement == self.round_decimal_places(float(price)):
                        colorSchema = ' bg-primary text-white '


                        

                    curRow = curRow.replace(expiryColorSchemaReplaceStr, colorSchema)

                i = i + 1

            htmlCode = htmlCode + curRow



        return htmlCode





    def getDebug(self):
        return str(self.debug)



if __name__== "__main__":

    returnDict = {}
    returnDict['status'] = 'OK'
    returnDict['remarks'] = ''
    returnDict['htmlData'] = ''

    try:
        handler = DATAHANDLER(sys.argv[1])
    except Exception as e:
        returnDict['status'] = 'KO'
        returnDict['remarks'] = str(e)
        print (json.dumps(returnDict))
        sys.exit()

    try:
        returnDict['htmlData'] = handler.getData()
    except Exception as e:
        returnDict['status'] = 'KO'
        returnDict['remarks'] = str(e) + ' ' + handler.getDebug()

    print (json.dumps(returnDict))


    