import requests
import time
import re
import csv
import os # Import the os module to access environment variables
from dotenv import load_dotenv # Import load_dotenv

# Load environment variables from .env file
load_dotenv()

# --- Configuration for Discogs API ---
BASE_URL = os.getenv("BASE_URL", "https://api.discogs.com") # Get from .env, default if not found
DISCOGS_CONSUMER_KEY = os.getenv("DISCOGS_CONSUMER_KEY") # Get from .env
DISCOGS_CONSUMER_SECRET = os.getenv("DISCOGS_CONSUMER_SECRET") # Get from .env

USER_AGENT = "SoFreshCollectionFetcher/1.0 +https://github.com/yourusername/sofresh" # Replace with your app name and contact info
# Note: Discogs API has rate limits (60 requests per minute for authenticated, 25 for unauthenticated).
# A small delay is added between requests to avoid hitting limits.

# --- Helper Function to make Discogs API requests ---
def get_discogs_data(url, params=None):
    """
    Fetches data from the Discogs API with appropriate headers,
    including authentication, and handles rate limiting.
    """
    # Check if credentials are loaded
    if not DISCOGS_CONSUMER_KEY or not DISCOGS_CONSUMER_SECRET:
        print("Error: Discogs API key or secret not found in environment variables. Please check your .env file.")
        return None

    headers = {
        "User-Agent": USER_AGENT,
        # Authenticate with Discogs using your consumer key and secret
        "Authorization": f"Discogs key={DISCOGS_CONSUMER_KEY}, secret={DISCOGS_CONSUMER_SECRET}"
    }
    try:
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
        time.sleep(1) # Be kind to the API and wait a bit between requests
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error fetching data from {url}: {e}")
        # Print response content for debugging if it's an HTTP error
        if hasattr(e, 'response') and e.response is not None:
            print(f"Response content: {e.response.text}")
        return None

# --- Function to parse "So Fresh" compilation titles ---
def parse_so_fresh_title(title):
    """
    Parses a 'So Fresh' compilation title to extract the season and year.
    Handles various naming conventions and attempts to identify release types.
    Returns (release_type, year) or (None, None) if not found.
    """
    original_title_lower = title.lower()
    release_type = None
    year = None

    # 1. Try to find the year (4 digits, possibly after a season or "hits of")
    year_match = re.search(r'\b(19|20)\d{2}\b', original_title_lower)
    if year_match:
        year = int(year_match.group(0))

    # 2. Common season patterns (highest priority)
    if "summer" in original_title_lower:
        release_type = "Summer"
    elif "autumn" in original_title_lower or "fall" in original_title_lower:
        release_type = "Autumn"
    elif "winter" in original_title_lower:
        release_type = "Winter"
    elif "spring" in original_title_lower:
        release_type = "Spring"

    # 3. Specific compilation types if no season found yet
    if not release_type:
        if "christmas" in original_title_lower or "xmas" in original_title_lower or "holiday" in original_title_lower:
            release_type = "Christmas Release"
        elif "top" in original_title_lower and "hits" in original_title_lower:
            release_type = "Top Hits"
        elif "greatest hits" in original_title_lower or "best of" in original_title_lower or "years of" in original_title_lower:
            release_type = "Greatest Hits"
        elif "ultimate" in original_title_lower or "platinum" in original_title_lower or "classic" in original_title_lower:
            release_type = "Special Compilation"
        elif "the hits" in original_title_lower:
            release_type = "The Hits" # Added for titles like "So Fresh: The Hits of 200X"
        elif "random" in original_title_lower:
            release_type = "Random" # Added for specific "So Fresh: Random" releases

    # The "Summer + previous year hits" case is handled during display,
    # as inferring it perfectly from just the title and API data is challenging.
    # We will rely on the main loop to decide how to display the season.
    return release_type, year

# --- Script: Fetch Songs from a Specific Discogs Label and Save to CSV ---
def fetch_so_fresh_tracks_from_label(label_url, output_csv_file="so_fresh_tracks.csv"):
    """
    Fetches all track information from releases associated with a given Discogs label URL
    and saves the data to a CSV file.
    Handles compilations that might not fit the 'Season, Year' format,
    attempting to classify them more specifically.
    Includes main genre and Discogs release URL.
    """
    print("\n--- Script: Fetching Songs from Discogs Label Releases ---")
    all_tracks_data = []

    # Extract label ID from the URL
    label_match = re.search(r'/label/(\d+)', label_url)
    if not label_match:
        print(f"Error: Invalid Discogs label URL provided: {label_url}. Expected format: .../label/LABEL_ID")
        return []
    label_id = label_match.group(1)

    page = 1
    total_pages = 1 # Initialize to enter the loop

    while page <= total_pages:
        label_releases_url = f"{BASE_URL}/labels/{label_id}/releases"
        params = {"page": page, "per_page": 50} # Max items per page
        print(f"Fetching releases for label ID {label_id}, page {page}...")
        releases_data = get_discogs_data(label_releases_url, params)

        if releases_data and releases_data.get("releases"):
            for release_summary in releases_data["releases"]:
                release_id = release_summary.get("id")
                release_title = release_summary.get("title", "")
                release_year = release_summary.get("year") # This is often more accurate for year than parsing

                # Filter for "So Fresh" in the title to ensure we only process relevant releases
                if "so fresh" not in release_title.lower():
                    print(f"Skipping non-'So Fresh' release: '{release_title}'.")
                    continue

                if not release_id:
                    print(f"Skipping release with no ID: '{release_title}'.")
                    continue

                print(f"Processing release: '{release_title}' (ID: {release_id})...")

                # Parse release type and year from title. Prioritize direct release_year for the year field.
                detected_release_type, parsed_year = parse_so_fresh_title(release_title)
                final_year = release_year if release_year else parsed_year # Use API year if available

                # Determine display release type and year
                display_release_type = detected_release_type
                display_year = final_year

                # Special handling for "Summer + previous year hits" if detected as Summer
                if display_release_type == "Summer" and display_year:
                    prev_year_for_summer = display_year - 1
                    # Check if the previous year is explicitly mentioned in the title alongside "hits"
                    if re.search(r'hits of \b' + str(prev_year_for_summer) + r'\b', release_title.lower()):
                        display_release_type = f"Summer + {prev_year_for_summer} Hits"

                # If no specific type was determined, mark as "General Compilation"
                if not display_release_type:
                    display_release_type = "General Compilation"


                # Fetch full release details for tracklist
                release_detail_data = get_discogs_data(f"{BASE_URL}/releases/{release_id}")

                if release_detail_data:
                    # Extract main genre
                    main_genre = "N/A"
                    if release_detail_data.get("genres") and len(release_detail_data["genres"]) > 0:
                        main_genre = release_detail_data["genres"][0]

                    # Construct Discogs release URL
                    discogs_release_url = f"https://www.discogs.com/release/{release_id}"

                    if release_detail_data.get("tracklist"):
                        for track in release_detail_data["tracklist"]:
                            track_number = track.get("position", "")
                            track_name = track.get("title", "")
                            track_duration = track.get("duration", "")

                            # Get artists. If track has specific artists, use them. Otherwise, use album artists.
                            track_artists = []
                            if track.get("artists"):
                                track_artists = [a.get("name") for a in track["artists"] if a.get("name")]
                            elif release_detail_data.get("artists"): # Fallback to release artists
                                track_artists = [a.get("name") for a in release_detail_data["artists"] if a.get("name")]
                            
                            artist_name = ", ".join(track_artists) if track_artists else "Various"

                            all_tracks_data.append({
                                "track_number": track_number,
                                "track_name": track_name,
                                "artist": artist_name,
                                "track_length": track_duration,
                                "season": display_release_type, # Use the more specific release type here
                                "year": display_year if display_year else "N/A", # Ensure year is N/A if not found
                                "main_genre": main_genre,
                                "discogs_release_url": discogs_release_url
                            })
                    else:
                        print(f"No tracklist found for release '{release_title}' (ID: {release_id}).")
                else:
                    print(f"Failed to fetch detailed data for release '{release_title}' (ID: {release_id}).")
            
            # Update total_pages for the next iteration
            pagination = releases_data.get("pagination", {})
            total_pages = pagination.get("pages", 1)
            page += 1
        else:
            break # No more results or error

    print("\n--- All Tracks Found (Script Output) ---")
    # Define CSV header
    csv_headers = ["Track Number", "Track Name", "Artist", "Track Length (Min:Sec)", "Season", "Year", "Main Genre", "Discogs Release URL"]

    try:
        with open(output_csv_file, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(csv_headers) # Write the header row
            for track in all_tracks_data:
                writer.writerow([
                    track['track_number'],
                    track['track_name'],
                    track['artist'],
                    track['track_length'],
                    track['season'],
                    track['year'],
                    track['main_genre'],
                    track['discogs_release_url']
                ])
        print(f"Successfully saved {len(all_tracks_data)} tracks to '{output_csv_file}'")
    except IOError as e:
        print(f"Error saving data to CSV file: {e}")

    print("-" * 50)
    return all_tracks_data


# --- Main Execution ---
if __name__ == "__main__":
    so_fresh_label_url = "https://www.discogs.com/label/334733-So-Fresh"
    # Call the function to fetch tracks and save to CSV
    fetch_so_fresh_tracks_from_label(so_fresh_label_url, output_csv_file="so_fresh_compilation_tracks.csv")
