import os
import json
from datetime import datetime, timedelta
import requests
from django.db import models
from asgiref.sync import sync_to_async


class APIDataLogger:
    """Класс для работы с API, сохранения и обработки данных."""

    def __init__(self, name, url, token=None, username=None, password=None):
        self.name = name
        self.url = url
        self.token = token
        self.username = username
        self.password = password
        self.output_dir = "modules"

    def ensure_directory_exists(self, path):
        """Создать директорию, если она не существует."""
        if not os.path.exists(path):
            os.makedirs(path)

    def fetch_data(self, additional_data=None):
        """Получить данные из API."""
        headers = {"Content-Type": "application/json"}
        data = additional_data or {}

        if self.token:
            data["token"] = self.token

        response = requests.post(self.url, headers=headers, json=data, auth=(self.username, self.password) if self.username and self.password else None)
        if response.status_code != 200:
            print(f'{self.name}: API запрос не удался. Код статуса: {response.status_code}')
            return []

        return response.json()

    def save_data(self, data, suffix):
        """Сохранить данные в файл JSON."""
        now = datetime.now()
        current_date = now.strftime('%Y-%m-%d')
        directory = os.path.join(self.output_dir, current_date, self.name)
        self.ensure_directory_exists(directory)

        filename = f"{self.name} {suffix}.json"
        filepath = os.path.join(directory, filename)
        with open(filepath, 'w') as file:
            json.dump(data, file)
        return filepath

    def load_previous_data(self, suffixes):
        """Загрузить данные из файлов за текущий и предыдущий интервалы."""
        now = datetime.now()
        current_date = now.strftime('%Y-%m-%d')
        yesterday_date = (now - timedelta(days=1)).strftime('%Y-%m-%d')

        directories = [(yesterday_date, "21"), (current_date, "9")] if 9 <= now.hour < 21 else [(current_date, "9"), (current_date, "21")]
        data_combined = []

        for date, suffix in directories:
            filepath = os.path.join(self.output_dir, date, self.name, f"{self.name} {suffix}.json")
            try:
                with open(filepath, 'r') as file:
                    data_combined.extend(json.load(file))
            except FileNotFoundError:
                pass

        return data_combined

    def filter_data(self, data, filter_function):
        """Фильтрация данных с использованием переданной функции."""
        return filter_function(data)

    def process_and_save(self, additional_data=None, filter_function=None):
        """Основной процесс: запрос, сохранение, чтение, фильтрация."""
        now = datetime.now()
        suffix = "9" if 9 <= now.hour < 21 else "21"

        # Шаг 1: Получить данные
        raw_data = self.fetch_data(additional_data)
        self.save_data(raw_data, suffix)

        # Шаг 2: Загрузить данные за текущий и предыдущий интервал
        combined_data = self.load_previous_data(["9", "21"])

        # Шаг 3: Фильтрация
        if filter_function:
            combined_data = self.filter_data(combined_data, filter_function)

        return combined_data