#!/usr/bin/env python3
import requests
import pandas as pd
import json
from datetime import datetime, timedelta
import time
import os
import logging
from pathlib import Path

# Konfiguracja
API_KEY = 'csd6n91r01qi0n6eks0gcsd6n91r01qi0n6eks10'
BASE_DIR = '/var/www/html/analiza'
DATA_DIR = f'{BASE_DIR}/data'
LOG_DIR = f'{BASE_DIR}/logs'

# Konfiguracja headers dla API
HEADERS = {
    'X-Finnhub-Token': API_KEY
}

# Tworzenie katalogów jeśli nie istnieją
for dir_path in [DATA_DIR, LOG_DIR]:
    Path(dir_path).mkdir(parents=True, exist_ok=True)

# Konfiguracja logowania
logging.basicConfig(
    filename=f'{LOG_DIR}/data_fetcher.log',
    format='%(asctime)s - %(levelname)s - %(message)s',
    level=logging.INFO
)

# Konfiguracja instrumentów - potwierdzone dostępne symbole
INSTRUMENTS = {
    'GOLD': 'OANDA:XAU_USD',
    'SILVER': 'OANDA:XAG_USD',
    'PLATINUM': 'OANDA:XPT_USD'
}

TIMEFRAMES = {
    'W': {'resolution': 'W', 'days_back': 520},  # 10 lat tygodniowych
    'D': {'resolution': 'D', 'days_back': 365},  # 1 rok dziennych
    'H': {'resolution': '60', 'days_back': 30}   # 30 dni godzinowych
}

def test_api_connection():
    """Test połączenia z API dla każdego instrumentu"""
    logging.info("Testowanie połączenia API...")
    for symbol_name, symbol_code in INSTRUMENTS.items():
        try:
            url = 'https://finnhub.io/api/v1/forex/candle'
            params = {
                'symbol': symbol_code,
                'resolution': 'D',
                'from': int(time.time() - 86400),  # ostatnie 24h
                'to': int(time.time())
            }
            response = requests.get(url, params=params, headers=HEADERS)
            logging.info(f"Test {symbol_name}: Status {response.status_code}")
            if response.status_code != 200:
                logging.error(f"Błąd dostępu do {symbol_name}: {response.text}")
            time.sleep(1)  # Delay między zapytaniami
        except Exception as e:
            logging.error(f"Błąd podczas testu {symbol_name}: {str(e)}")

def get_unix_time(days_back):
    """Konwersja dat na unixtimestamp"""
    end_time = datetime.now()
    start_time = end_time - timedelta(days=days_back)
    return int(start_time.timestamp()), int(end_time.timestamp())

def fetch_data(symbol, resolution, from_time, to_time):
    """Pobieranie danych z Finnhub z obsługą błędów"""
    url = 'https://finnhub.io/api/v1/forex/candle'
    params = {
        'symbol': symbol,
        'resolution': resolution,
        'from': from_time,
        'to': to_time
    }
    
    try:
        response = requests.get(url, params=params, headers=HEADERS)
        
        if response.status_code == 429:
            logging.warning("Przekroczono limit API - oczekiwanie 60s")
            time.sleep(60)
            return None
            
        response.raise_for_status()
        data = response.json()
        
        if data.get('s') == 'no_data':
            logging.warning(f"Brak danych dla {symbol} {resolution}")
            return None
            
        if 's' not in data or 't' not in data:
            logging.error(f"Nieprawidłowy format danych dla {symbol}: {data}")
            return None
            
        df = pd.DataFrame({
            'timestamp': pd.to_datetime(data['t'], unit='s'),
            'open': data['o'],
            'high': data['h'],
            'low': data['l'],
            'close': data['c'],
            'volume': data['v']
        })
        
        df.set_index('timestamp', inplace=True)
        logging.info(f"Pobrano {len(df)} świeczek dla {symbol} {resolution}")
        return df
        
    except requests.exceptions.HTTPError as e:
        logging.error(f"HTTP Error dla {symbol} {resolution}: {str(e)}")
        return None
    except Exception as e:
        logging.error(f"Błąd podczas pobierania {symbol} {resolution}: {str(e)}")
        return None

def save_data(df, symbol, timeframe):
    """Zapisywanie danych do plików"""
    if df is not None and not df.empty:
        try:
            # Zapis do CSV
            filename = f"{DATA_DIR}/{symbol}_{timeframe}.csv"
            df.to_csv(filename)
            
            # Zapis ostatniej ceny i timestamp do JSON
            last_price = {
                'symbol': symbol,
                'timeframe': timeframe,
                'last_close': float(df['close'].iloc[-1]),
                'last_update': df.index[-1].isoformat(),
                'data_points': len(df)
            }
            
            with open(f"{DATA_DIR}/{symbol}_{timeframe}_info.json", 'w') as f:
                json.dump(last_price, f, indent=2)
                
            logging.info(f"Zapisano dane {symbol} {timeframe}: {len(df)} świeczek")
            
        except Exception as e:
            logging.error(f"Błąd podczas zapisu {symbol} {timeframe}: {str(e)}")

def main():
    logging.info("Rozpoczęcie pobierania danych")
    
    # Test API przed głównym pobieraniem
    test_api_connection()
    
    for symbol_name, symbol_code in INSTRUMENTS.items():
        for timeframe, config in TIMEFRAMES.items():
            logging.info(f"Pobieranie {symbol_name} {timeframe}")
            time.sleep(1.5)  # Delay między zapytaniami
            
            from_time, to_time = get_unix_time(config['days_back'])
            df = fetch_data(symbol_code, config['resolution'], from_time, to_time)
            save_data(df, symbol_name, timeframe)
    
    logging.info("Zakończenie pobierania danych")

if __name__ == "__main__":
    main()