#!/usr/bin/env python3
"""
IMPORT Executor
Company: eXonware.com
Author: eXonware Backend Team
Email: connect@exonware.com
Version: 0.9.0.6
"""

from typing import Any, Optional
from ..base import AUniversalOperationExecutor
from ....contracts import QueryAction, ExecutionContext, ExecutionResult
from ....defs import OperationType
from ..utils import extract_items, extract_field_value


class ImportExecutor(AUniversalOperationExecutor):
    """IMPORT - Load data from external path/url."""
    OPERATION_NAME = "IMPORT"
    OPERATION_TYPE = OperationType.DATA_OPS
    SUPPORTED_NODE_TYPES = []

    def _do_execute(self, action: QueryAction, context: ExecutionContext) -> ExecutionResult:
        params = action.params
        result_data = self._execute_import(context.node, params, context)
        return ExecutionResult(
            success=True,
            data=result_data,
            action_type=self.OPERATION_NAME,
            metadata={"operation": self.OPERATION_NAME},
        )

    def _execute_import(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        import csv
        import xml.etree.ElementTree as ET

        from exonware.xwsystem.io.serialization.formats.text import json as xw_json

        source = params.get("source")
        format_name = str(params.get("format", "json")).lower()
        options = params.get("options", {})

        if not source:
            return {"items": [], "count": 0, "error": "source is required"}

        try:
            if format_name == "json":
                with open(source, "r", encoding=options.get("encoding", "utf-8")) as handle:
                    loaded = xw_json.load(handle)
                items = loaded if isinstance(loaded, list) else [loaded]
            elif format_name == "csv":
                with open(source, "r", encoding=options.get("encoding", "utf-8"), newline="") as handle:
                    reader = csv.DictReader(handle)
                    items = list(reader)
            elif format_name == "xml":
                tree = ET.parse(source)
                root = tree.getroot()
                row_tag = options.get("row_tag")
                rows = root.findall(f".//{row_tag}") if row_tag else list(root)
                items = [{child.tag: child.text for child in row} for row in rows]
            else:
                return {"items": [], "count": 0, "error": f"Unsupported format: {format_name}"}
        except Exception as exc:
            return {"items": [], "count": 0, "error": str(exc), "source": source, "format": format_name}

        return {
            "items": items,
            "count": len(items),
            "source": source,
            "format": format_name,
        }
