import sqlite3
from datetime import datetime, timedelta
import pandas as pd
import json
import time

class Past_Market_Movers:
    def __init__(self):
        self.con = sqlite3.connect('backup_db/stocks.db')
        self.cursor = self.con.cursor()
        self.cursor.execute("PRAGMA journal_mode = wal")
        self.symbols = self.get_stock_symbols()

    def get_stock_symbols(self):
        self.cursor.execute("SELECT DISTINCT symbol FROM stocks WHERE symbol != ?", ('%5EGSPC',))
        return [row[0] for row in self.cursor.fetchall()]

    @staticmethod
    def check_if_holiday():
        holidays = {
            datetime(2023, 5, 29): 'memorial_day',
            datetime(2023, 6, 19): 'independence_day',
            datetime(2023, 6, 20): 'independence_day+1',
            datetime(2023, 9, 4): 'labor_day',
        }

        current_datetime = datetime.today()
        for holiday_date, holiday_name in holidays.items():
            if current_datetime == holiday_date:
                return holiday_name
        return None

    def correct_weekday_interval(self, prev_day):
        holiday = self.check_if_holiday()
        if holiday:
            if holiday == 'memorial_day':
                start_date = datetime(2023, 5, 26)
            elif holiday in ('independence_day', 'independence_day+1'):
                start_date = datetime(2023, 6, 16)
            else:
                start_date = datetime(2023, 9, 1)
        else:
            current_date = datetime.today() - timedelta(prev_day)
            current_weekday = current_date.weekday()
            if current_weekday in (5, 6):  # Saturday or Sunday
                start_date = current_date - timedelta(days=current_weekday % 5 + 1)
            else:
                start_date = current_date
        return start_date.strftime("%Y-%m-%d")

    def run(self, time_periods=[7,30,90,180]):
        performance_data = []
        query_template = """
            SELECT date, close, volume FROM "{ticker}" WHERE date >= ?
        """
        query_fundamental_template = """
            SELECT marketCap, name FROM stocks WHERE symbol = ?
        """
        gainer_json = {}
        loser_json = {}
        active_json = {}

        for time_period in time_periods:
            performance_data = []
            high_volume = []
            gainer_data = []
            loser_data = []
            active_data = []

            start_date = self.correct_weekday_interval(time_period)
            for ticker in self.symbols:
                try:
                    query = query_template.format(ticker=ticker)
                    df = pd.read_sql_query(query, self.con, params=(start_date,))
                    if not df.empty:
                        fundamental_data = pd.read_sql_query(query_fundamental_template, self.con, params=(ticker,))
                        avg_volume = df['volume'].mean()
                        if avg_volume > 1E6 and df['close'].mean() > 1:
                            changes_percentage = ((df['close'].iloc[-1] - df['close'].iloc[0]) / df['close'].iloc[0]) * 100
                            performance_data.append((ticker, fundamental_data['name'].iloc[0], df['close'].iloc[-1], changes_percentage, avg_volume, int(fundamental_data['marketCap'].iloc[0])))
                except:
                    pass

            # Sort the stocks by percentage change in descending order
            performance_data.sort(key=lambda x: x[3], reverse=True)
            high_volume = sorted(performance_data, key=lambda x: x[4], reverse=True)

            for symbol, name, price, changes_percentage, volume, market_cap in performance_data[:20]:
                gainer_data.append({'symbol': symbol, 'name': name, 'price': price, 'changesPercentage': changes_percentage, 'volume': volume, 'marketCap': market_cap})
            for symbol, name, price, changes_percentage, volume, market_cap in performance_data[-20:]:
                loser_data.append({'symbol': symbol, 'name': name, 'price': price, 'changesPercentage': changes_percentage, 'volume': volume, 'marketCap': market_cap})
            for symbol, name, price, changes_percentage, volume, market_cap in high_volume[:20]:
                active_data.append({'symbol': symbol, 'name': name, 'price': price, 'changesPercentage': changes_percentage, 'volume': volume, 'marketCap': market_cap})

            
            if time_period == 7:
                gainer_json['1W'] = gainer_data
                loser_json['1W'] = loser_data
                active_json['1W'] = active_data
            elif time_period == 30:
                gainer_json['1M'] = gainer_data
                loser_json['1M'] = loser_data
                active_json['1M'] = active_data
            elif time_period == 90:
                gainer_json['3M'] = gainer_data
                loser_json['3M'] = loser_data
                active_json['3M'] = active_data
            elif time_period == 180:
                gainer_json['6M'] = gainer_data
                loser_json['6M'] = loser_data
                active_json['6M'] = active_data

        return gainer_json, loser_json, active_json


    def create_table(self):
        """
        Create the 'market_movers' table if it doesn't exist and add 'gainer', 'loser', and 'most_active' columns.
        """
        query_drop = "DROP TABLE IF EXISTS market_movers"
        self.con.execute(query_drop)
        query_create = """
        CREATE TABLE IF NOT EXISTS market_movers (
            gainer TEXT,
            loser TEXT,
            most_active TEXT
        )
        """
        self.con.execute(query_create)
        self.con.commit()


    def update_database(self, gainer_json, loser_json, active_json):
        """
        Update the 'gainer', 'loser', and 'most_active' columns in the 'market_movers' table with the provided JSON data.
        """
        query = "INSERT INTO market_movers (gainer, loser, most_active) VALUES (?, ?, ?)"
        gainer_json_str = json.dumps(gainer_json)
        loser_json_str = json.dumps(loser_json)
        active_json_str = json.dumps(active_json)
        self.con.execute(query, (gainer_json_str, loser_json_str, active_json_str))
        self.con.commit()

    def close_database_connection(self):
        self.con.close()

if __name__ == "__main__":
    analyzer = Past_Market_Movers()
    analyzer.create_table()  # Create the 'market_movers' table with the 'gainer', 'loser', and 'most_active' columns
    gainer_json, loser_json, active_json = analyzer.run()  # Retrieve the gainer_json, loser_json, and active_json data
    analyzer.update_database(gainer_json, loser_json, active_json)  # Update the 'gainer', 'loser', and 'most_active' columns with the respective data
    analyzer.close_database_connection()
