import os
import re
import csv
import json
import pandas as pd
from pymongo import MongoClient
from datetime import datetime, timedelta

def get_credentials(env='live', filepath=r'/var/www/html/trade_iq/db_updater/credentials.json'):
    """
    Access credentials from a JSON file.

    Args:
    - env (str): Environment to fetch the credentials from ('local' or 'live'). Default is 'local'.
    - filepath (str): Path to the JSON file containing credentials. Default is 'creds.json'.

    Returns:
    - dict: Credentials for the specified environment.
    """
    try:
        # Open and load the JSON file
        with open(filepath, 'r') as f:
            data = json.load(f)

        # Fetch credentials based on environment
        credentials = data.get(env)

        if credentials:
            return credentials
        else:
            raise ValueError(f"No credentials found for environment: {env}")

    except FileNotFoundError:
        print(f"File not found: {filepath}")
    except json.JSONDecodeError:
        print(f"Error decoding JSON in file: {filepath}")
    except Exception as e:
        print(f"An error occurred: {e}")

def getNSEdata():
    creds = get_credentials()

    # Credentials
    mongoDB_creds = creds.get("mongoDB_creds")
    connection_url = mongoDB_creds.get("connection_str")
    mongo_database = mongoDB_creds.get("database")
    nse_collection = mongoDB_creds.get("nse_collection")

    mongo_client = MongoClient(connection_url)  # Replace with your MongoDB connection string
    db = mongo_client[mongo_database]  # Replace with your database name
    collection = db[nse_collection]

    # Read the original CSV file to get the initial data
    df = pd.read_csv(r'/var/www/html/trade_iq/db_updater/files/zerodha_nse.csv')

    # Define the date ranges
    date_ranges = {
        "YESTERDAY'S CLOSING": 1,
        "7 DAYS BEFORE PRICE": 7,
        "14 DAYS BEFORE PRICE": 14,
        "1 MONTH BEFORE PRICE": 30,
        "3 MONTH BEFORE PRICE": 90,
        "6 MONTH BEFORE PRICE": 180,
        "1 YEAR BEFORE PRICE": 365,
        "2 YEAR BEFORE PRICE": 730,
        "3 YEAR BEFORE PRICE": 1095,
        "4 YEAR BEFORE PRICE": 1460,
        "5 YEAR BEFORE PRICE": 1825,
        "7 YEAR BEFORE PRICE": 2555,
        "10 YEAR BEFORE PRICE": 3650
    }

    def get_price_for_date(prices, target_date):
        # Convert target_date to string format
        target_date_str = target_date.strftime("%Y-%m-%d")

        # If the exact date is available, return its close price
        if target_date_str in prices:
            return prices[target_date_str].get('close')

        # If not, find the closest earlier date
        earlier_dates = [date for date in prices.keys() if date <= target_date_str]
        if earlier_dates:
            closest_date = max(earlier_dates)
            return prices[closest_date].get('close')

        # If no earlier date is found, return None
        return None

    # Process each row in the DataFrame
    for index, row in df.iterrows():
        symbol = row['Symbol.1']  # Assuming 'Symbol.1' is the column with the symbol to be used for API calls
        print(f"Processing {symbol}")

        # Fetch data from MongoDB
        document = collection.find_one({'symbol': symbol})

        if document:
            prices = document.get('prices', {})
            today = datetime.now().date()

            # Get today's price
            today_price = get_price_for_date(prices, today)

            for column, days in date_ranges.items():
                target_date = today - timedelta(days=days)
                price = get_price_for_date(prices, target_date)
                df.at[index, column] = price

                # Calculate percentage change
                if column != "YESTERDAY'S CLOSING" and today_price and price:
                    percent_change_column = column.replace("PRICE", "CHANGE %")
                    percent_change = ((today_price - price) / price) * 100
                    df.at[index, percent_change_column] = round(percent_change, 2)
        else:
            print(f"No data found for {symbol}")

    # Save the updated DataFrame
    selected_columns = [
        "exchange_token", "instrument_token", "Symbol.1", "name", "last_price", "expiry", "strike", "tick_size",
        "lot_size", "instrument_type", "segment", "exchange",
        "YESTERDAY'S CLOSING", "7 DAYS BEFORE PRICE", "14 DAYS BEFORE PRICE", "1 MONTH BEFORE PRICE",
        "3 MONTH BEFORE PRICE", "6 MONTH BEFORE PRICE", "1 YEAR BEFORE PRICE", "2 YEAR BEFORE PRICE",
        "3 YEAR BEFORE PRICE", "4 YEAR BEFORE PRICE", "5 YEAR BEFORE PRICE", "7 YEAR BEFORE PRICE", "10 YEAR BEFORE PRICE",
        "7 DAYS BEFORE CHANGE %", "14 DAYS BEFORE CHANGE %", "1 MONTH BEFORE CHANGE %", "3 MONTH BEFORE CHANGE %",
        "6 MONTH BEFORE CHANGE %", "1 YEAR BEFORE CHANGE %", "2 YEAR BEFORE CHANGE %", "3 YEAR BEFORE CHANGE %",
        "4 YEAR BEFORE CHANGE %", "5 YEAR BEFORE CHANGE %", "7 YEAR BEFORE CHANGE %", "10 YEAR BEFORE CHANGE %"
    ]
    df = df[selected_columns]
    output_file = f'/var/www/html/trade_iq/db_updater/daily_files/NSE_UPDATED_{datetime.now().date()}.csv'

    # Check if the file exists
    if os.path.exists(output_file):
        try:
            # If file exists, proceed with opening the file
            with open(output_file, mode='r') as file:
                reader = csv.reader(file)
                for row in reader:
                    print(row)
        except FileNotFoundError as e:
            print(f"Error: {e}")
    else:
        # Handle the case where the file doesn't exist
        print(f"File not found: {output_file}")
        # Optionally, create the file if necessary
        with open(output_file, mode='w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['Header1', 'Header2', 'Header3'])  # Add appropriate headers
            print(f"New file created at: {output_file}")

    df.to_csv(output_file, index=False)
    print(f"Processing completed. Results saved to '{output_file}'")

    # Close the MongoDB connection
    mongo_client.close()

if __name__ == "__main__":
    getNSEdata()
