"""File parser service for card import."""
import csv
import json
from typing import List, Union
from pathlib import Path
import openpyxl
import pandas as pd


class FileParser:
    """Parse various file formats for card import."""

    SUPPORTED_FORMATS = ['xlsx', 'csv', 'json', 'ods']

    @staticmethod
    async def parse_file(file_path: Path) -> List[str]:
        """
        Parse a file and extract card names.
        
        Args:
            file_path: Path to the file to parse
            
        Returns:
            List of card names extracted from the file
            
        Raises:
            ValueError: If file format is not supported
            FileNotFoundError: If file does not exist
            Exception: If file cannot be parsed
        """
        file_type = file_path.suffix.lower().lstrip('.')

        if file_type not in FileParser.SUPPORTED_FORMATS:
            raise ValueError(f"Unsupported file format: {file_type}. Supported formats: {FileParser.SUPPORTED_FORMATS}")

        if not file_path.exists():
            raise FileNotFoundError(f"File not found: {file_path}")

        if file_type == 'csv':
            return FileParser._parse_csv(file_path)
        elif file_type == 'json':
            return FileParser._parse_json(file_path)
        elif file_type == 'xlsx':
            return FileParser._parse_xlsx(file_path)
        elif file_type == 'ods':
            return FileParser._parse_ods(file_path)

    @staticmethod
    def _parse_csv(file_path: Path) -> List[str]:
        """Parse CSV file and extract card names."""
        card_names = []
        with open(file_path, 'r', encoding='utf-8') as f:
            reader = csv.reader(f)
            for row in reader:
                # Take first non-empty column as card name
                for cell in row:
                    cell = cell.strip()
                    if cell:
                        card_names.append(cell)
                        break
        return card_names

    @staticmethod
    def _parse_json(file_path: Path) -> List[str]:
        """Parse JSON file and extract card names."""
        with open(file_path, 'r', encoding='utf-8') as f:
            data = json.load(f)

        if isinstance(data, list):
            return [str(item).strip() for item in data if str(item).strip()]
        elif isinstance(data, dict):
            # Try common keys
            for key in ['cards', 'card_names', 'cards_list', 'list']:
                if key in data and isinstance(data[key], list):
                    return [str(item).strip() for item in data[key] if str(item).strip()]
            # If no common key found, try first list value
            for value in data.values():
                if isinstance(value, list):
                    return [str(item).strip() for item in value if str(item).strip()]
        raise ValueError("Invalid JSON format: expected list or dict with card names")

    @staticmethod
    def _parse_xlsx(file_path: Path) -> List[str]:
        """Parse XLSX file and extract card names from first column."""
        card_names = []
        try:
            workbook = openpyxl.load_workbook(file_path, read_only=True)
            worksheet = workbook.active

            for row in worksheet.iter_rows(values_only=True):
                if row and row[0]:
                    cell_value = str(row[0]).strip()
                    if cell_value:
                        card_names.append(cell_value)
        finally:
            if 'workbook' in locals():
                workbook.close()
        return card_names

    @staticmethod
    def _parse_ods(file_path: Path) -> List[str]:
        """Parse ODS file and extract card names from first column."""
        try:
            df = pd.read_excel(file_path, engine='odf')
            card_names = df.iloc[:, 0].dropna().astype(str).str.strip().tolist()
            return [name for name in card_names if name]
        except ImportError:
            raise ImportError("pandas with odf engine required for ODS parsing. Install with: pip install pandas odfpy")
