import streamlit as st
import requests
import pandas as pd
from datetime import datetime, timedelta

# Function to get current Tehran time from API
def get_tehran_time():
    response = requests.get('http://worldtimeapi.org/api/timezone/Asia/Tehran')
    time_data = response.json()
    return time_data['datetime']

# Function to get current Bitcoin price
@st.cache_data
def get_current_price(currency='USD'):
    url = f'https://api.coindesk.com/v1/bpi/currentprice/{currency}.json'
    response = requests.get(url)
    data = response.json()
    price = data['bpi'][currency]['rate_float']
    return price

# Function to calculate RSI
def calculate_rsi(prices, period=14):
    delta = prices.diff()
    gains = delta.where(delta > 0, 0)
    losses = -delta.where(delta < 0, 0)
    average_gain = gains.rolling(window=period).mean()
    average_loss = losses.rolling(window=period).mean()
    rs = average_gain / average_loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# Function to calculate MACD
def calculate_macd(prices, short_period=12, long_period=26, signal_period=9):
    short_ema = prices.ewm(span=short_period, adjust=False).mean()
    long_ema = prices.ewm(span=long_period, adjust=False).mean()
    macd = short_ema - long_ema
    signal = macd.ewm(span=signal_period, adjust=False).mean()
    histogram = macd - signal
    return macd, signal, histogram

# Function to generate buy/sell signals
def generate_signals(prices, rsi_period=14, macd_short_period=12, macd_long_period=26, macd_signal_period=9):
    signals = pd.DataFrame(index=prices.index)
    signals['rsi'] = calculate_rsi(prices, rsi_period)
    macd, signal, _ = calculate_macd(prices, macd_short_period, macd_long_period, macd_signal_period)
    signals['macd'] = macd
    signals['signal'] = signal
    signals['buy'] = (signals['rsi'] < 30) & (signals['macd'] > signals['signal'])
    signals['sell'] = (signals['rsi'] > 70) & (signals['macd'] < signals['signal'])
    return signals

# Set page configuration
st.set_page_config(page_title='Bitcoin Price Tracker', page_icon=':moneybag:', layout='wide')

# Header
st.header('Bitcoin Price Tracker :chart_with_upwards_trend:')

# Tehran time
tehran_time = get_tehran_time()
st.sidebar.write('Current time in Tehran:', tehran_time)

# Current Bitcoin price
currency = st.sidebar.selectbox('Select Currency', ['USD', 'EUR', 'GBP'])
price = get_current_price(currency)
st.write(f'Current Bitcoin Price in {currency}: **{price}**')

# Refresh button
if st.button('Refresh'):
    st.experimental_rerun()

# Trading signals subheader
st.subheader('Trading Signals :signal_strength:')

# Placeholder for data loading message
data_loading_text = st.empty()
data_loading_text.write('Loading data...')

# Load historical Bitcoin price data
try:
    start_date = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')  # Get data for the last 30 days
    url = f'https://api.coindesk.com/v1/bpi/historical/close.json?start={start_date}&end={datetime.now().strftime("%Y-%m-%d")}'
    response = requests.get(url)
    data = response.json()
    prices = pd.Series(data['bpi']).to_frame('close')
    prices.index = pd.to_datetime(prices.index)
except Exception as e:
    st.error(f'Error loading data: {e}')
else:
    data_loading_text.empty()

    # Generate trading signals
    signals = generate_signals(prices['close'])

    # Display buy/sell signals
    buy_count = (signals['buy'] == True).sum()
    sell_count = (signals['sell'] == True).sum()
    col1, col2 = st.columns(2)
    with col1:
        st.write('Buy signals :arrow_up:', buy_count)
    with col2:
        st.write('Sell signals :arrow_down:', sell_count)

    # Downloadable CSV for signals
    @st.cache_data
    def convert_df(df):
        return df.to_csv().encode('utf-8')
    csv = convert_df(signals.dropna())
    st.download_button(
        label="Download Signals CSV", data=csv, file_name='signals.csv', mime='text/csv')

    # Display historical data and signals
    st.subheader('Historical Prices and Trading Signals')
    if start_date == prices.index[0]:  # Check if data has been loaded for the last '30 days':
        start_index = max(0, -30) + 0
    else:
        start_index = 0
    signals_df = pd.concat([prices, signals['rsi'], signals['macd'] - signals['signal'],
                           signals.reindex(prices.index).ffill().buy.astype(int),
                           signals.reindex(prices.index).ffill().sell.astype(int)], axis=1)
    st.line_chart(data=signals_df.iloc[start_index:])

    # Parameter adjustment for signals
    st.subheader('Signals Adjustment Parameters')
    col1_adjust, col2_adjust = st.columns(2)

    with col1_adjust:
        rsi_period = st.number_input('RSI Period', min_value=5, max_value=100, value=14, step=1)
    with col2_adjust:
        short_period = st.number_input('MACD Short Period', min_value=2, max_value=50, value=12, step=1)
    st.subheader('Long Period :point_down:   Short Period: :point_up:')
    with st.columns(3):
        with st.column(1):
            l1 = st.number_input('', min_value=short_period + 1, max_value=100, value=26)
        with st.column(1):
            l0 = st.number_input(short_period)

    # Update trading signals with adjusted parameters
    if (buy_count + sell_count) > 0:
        st.warning('Warning: Parameter adjustments may impact previous signals.')
        if st.button('Regenerate Trading Signals with Adjusted Parameters'):
            signals = generate_signals(prices['close'], rsi_period=rsi_period, macd_short_period=short_period,
                                       macd_long_period=l1, macd_signal_period=9)

    # Display buy/sell signals with adjusted parameters and downloadable CSV
    try:
        buy_count = (signals['buy'] == True).sum()
        sell_count = (signals['sell'] == True).sum()

        col1_signals, col2_signals = st.columns(2)
        with col1_signals:
            st.write('Buy Signals with adjusted parameters: :arrow_up:', buy_count)
        with col2_signals:
            st.write('Sell Signals with adjusted parameters :arrow_down:', sell_count)

        csv = convert_df(signals[signals.index >= prices.index[-100]].reset_index().rename(columns={"close": "Close", 'macd': 'MACD',
                                                                                                    "signal": "MACD-Signal", 'rsi': 'RSI'}).dropna())

        st.subheader("Historical Prices and Trading Signals with Parameters Adjusted")
        signals_df_adj = pd.concat([prices, signals['buy'].astype(int), signals['sell'].astype(int)], axis=1)
        st.write("Note: The chart below reflects the last 100 data entries aligned with your parameter adjustments")
        st.line_chart(data=signals_df_adj, use_container_width=True)

        st.subheader('Download Trading Signals with Parameter Adjustments')
        st.download_button(label="Download Updated Signals CSV",
                           data=csv, file_name='signals_with_adjustments.csv', mime='text/csv')
    except Exception as e:
        st.info('Trading signals are generated on the basis of parameter adjustments.')