# Copyright (c) 2025 Patrick Motsch
# All rights reserved.

import logging
from datetime import datetime, UTC
from modules.workflows.methods.methodBase import MethodBase
from modules.datamodels.datamodelWorkflowActions import WorkflowActionDefinition, WorkflowActionParameter
from modules.shared.frontendTypes import FrontendType

# Import helpers
from .helpers.csvProcessing import CsvProcessingHelper

# Import actions
from .actions.process import process
from .actions.webResearch import webResearch
from .actions.summarizeDocument import summarizeDocument
from .actions.translateDocument import translateDocument
from .actions.convertDocument import convertDocument
from .actions.generateDocument import generateDocument
from .actions.generateCode import generateCode

logger = logging.getLogger(__name__)

class MethodAi(MethodBase):
    """AI processing methods."""
    
    def __init__(self, services):
        super().__init__(services)
        self.name = "ai"
        self.description = "AI processing methods"
        
        # Initialize helper modules
        self.csvProcessing = CsvProcessingHelper(self)
        
        # RBAC-Integration: Action-Definitionen mit actionId
        self._actions = {
            "process": WorkflowActionDefinition(
                actionId="ai.process",
                description="Universal AI document processing action - accepts multiple input documents in any format and processes them together with a prompt. If the prompt specifies document formats to deliver, include them in the prompt",
                dynamicMode=True,
                parameters={
                    "aiPrompt": WorkflowActionParameter(
                        name="aiPrompt",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=True,
                        description="Instruction for the AI describing what processing to perform"
                    ),
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=False,
                        description="Document reference(s) in any format to use as input/context"
                    ),
                    "resultType": WorkflowActionParameter(
                        name="resultType",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["txt", "json", "md", "csv", "xml", "html", "pdf", "docx", "xlsx", "pptx", "png", "jpg"],
                        required=False,
                        default="txt",
                        description="Output file extension. Optional: if omitted, formats are determined from prompt by AI. Default \"txt\" is validation fallback only. With per-document format determination, AI can determine different formats for different documents based on prompt."
                    ),
                    "generationIntent": WorkflowActionParameter(
                        name="generationIntent",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["document", "code", "image"],
                        required=False,
                        default="document",
                        description="Explicit generation intent (\"document\" | \"code\" | \"image\"). Required for DATA_GENERATE operations. Defaults to \"document\" if not provided. For code generation, use ai.generateCode action or explicitly pass generationIntent=\"code\". For IMAGE_GENERATE operations, this parameter is ignored."
                    ),
                    "simpleMode": WorkflowActionParameter(
                        name="simpleMode",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=False,
                        description="If true, uses fast simple AI call without document generation pipeline. Use for chatbot responses and simple text generation."
                    ),
                    "contentParts": WorkflowActionParameter(
                        name="contentParts",
                        type="List[ContentPart]",
                        frontendType=FrontendType.HIDDEN,
                        required=False,
                        description="Pre-extracted content parts (internal parameter, typically passed between actions). If provided, these will be used instead of extracting from documentList. Can be a list of ContentPart objects or an object with a 'parts' attribute."
                    ),
                },
                execute=process.__get__(self, self.__class__)
            ),
            "webResearch": WorkflowActionDefinition(
                actionId="ai.webResearch",
                description="Web research with two-step process: search for URLs, then crawl content",
                dynamicMode=True,
                parameters={
                    "prompt": WorkflowActionParameter(
                        name="prompt",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=True,
                        description="Natural language research instruction"
                    ),
                    "urlList": WorkflowActionParameter(
                        name="urlList",
                        type="List[str]",
                        frontendType=FrontendType.MULTISELECT,
                        required=False,
                        description="Specific URLs to crawl, if needed"
                    ),
                    "country": WorkflowActionParameter(
                        name="country",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Two-digit country code (lowercase, e.g., ch, us, de)"
                    ),
                    "language": WorkflowActionParameter(
                        name="language",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["de", "en", "fr", "it", "es"],
                        required=False,
                        description="Language code (lowercase, e.g., de, en, fr)"
                    ),
                    "researchDepth": WorkflowActionParameter(
                        name="researchDepth",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["fast", "general", "deep"],
                        required=False,
                        default="general",
                        description="Research depth"
                    )
                },
                execute=webResearch.__get__(self, self.__class__)
            ),
            "summarizeDocument": WorkflowActionDefinition(
                actionId="ai.summarizeDocument",
                description="Summarize one or more documents, extracting key points and main ideas. If the prompt specifies document formats to deliver, include them in the prompt",
                dynamicMode=True,
                parameters={
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=True,
                        description="Document reference(s) to summarize"
                    ),
                    "summaryLength": WorkflowActionParameter(
                        name="summaryLength",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["brief", "medium", "detailed"],
                        required=False,
                        default="medium",
                        description="Desired summary length"
                    ),
                    "focus": WorkflowActionParameter(
                        name="focus",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Specific aspect to focus on in the summary (e.g., financial data, key decisions)"
                    ),
                    "resultType": WorkflowActionParameter(
                        name="resultType",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["txt", "md", "docx"],
                        required=False,
                        default="txt",
                        description="Output file extension"
                    )
                },
                execute=summarizeDocument.__get__(self, self.__class__)
            ),
            "translateDocument": WorkflowActionDefinition(
                actionId="ai.translateDocument",
                description="Translate documents to a target language while preserving formatting and structure",
                dynamicMode=True,
                parameters={
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=True,
                        description="Document reference(s) to translate"
                    ),
                    "targetLanguage": WorkflowActionParameter(
                        name="targetLanguage",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=True,
                        description="Target language code or name (e.g., de, German, French, es)"
                    ),
                    "sourceLanguage": WorkflowActionParameter(
                        name="sourceLanguage",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Source language if known (e.g., en, English). If not provided, AI will detect"
                    ),
                    "preserveFormatting": WorkflowActionParameter(
                        name="preserveFormatting",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=True,
                        description="Whether to preserve original formatting"
                    ),
                    "resultType": WorkflowActionParameter(
                        name="resultType",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        description="Output file extension. If not specified, uses same format as input"
                    )
                },
                execute=translateDocument.__get__(self, self.__class__)
            ),
            "convertDocument": WorkflowActionDefinition(
                actionId="ai.convertDocument",
                description="Convert documents between different formats (PDF→Word, Excel→CSV, etc.)",
                dynamicMode=True,
                parameters={
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=True,
                        description="Document reference(s) to convert"
                    ),
                    "targetFormat": WorkflowActionParameter(
                        name="targetFormat",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["docx", "pdf", "xlsx", "csv", "txt", "html", "json", "md"],
                        required=True,
                        description="Target format extension"
                    ),
                    "preserveStructure": WorkflowActionParameter(
                        name="preserveStructure",
                        type="bool",
                        frontendType=FrontendType.CHECKBOX,
                        required=False,
                        default=True,
                        description="Whether to preserve document structure (headings, tables, etc.)"
                    )
                },
                execute=convertDocument.__get__(self, self.__class__)
            ),
            "generateDocument": WorkflowActionDefinition(
                actionId="ai.generateDocument",
                description="Generate documents from scratch or based on templates/inputs. If the prompt specifies document formats to deliver, include them in the prompt",
                dynamicMode=True,
                parameters={
                    "prompt": WorkflowActionParameter(
                        name="prompt",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=True,
                        description="Description of the document to generate"
                    ),
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=False,
                        description="Template documents or reference documents to use as a guide"
                    ),
                    "documentType": WorkflowActionParameter(
                        name="documentType",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["letter", "memo", "proposal", "contract", "report", "email"],
                        required=False,
                        description="Type of document"
                    ),
                    "resultType": WorkflowActionParameter(
                        name="resultType",
                        type="str",
                        frontendType=FrontendType.TEXT,
                        required=False,
                        default="txt",
                        description="Output format (e.g., txt, html, pdf, docx, md, json, csv, xlsx, pptx, png, jpg). Optional: if omitted, formats are determined from prompt by AI. Default \"txt\" is validation fallback only. With per-document format determination, AI can determine different formats for different documents based on prompt."
                    )
                },
                execute=generateDocument.__get__(self, self.__class__)
            ),
            "generateCode": WorkflowActionDefinition(
                actionId="ai.generateCode",
                description="Generate one or multiple code files in a single action - explicitly sets intent to 'code'. This action can generate multiple files (e.g., config.json, customers.json, settings.json) when the prompt requests multiple files. If the prompt specifies file formats to deliver, include them in the prompt. IMPORTANT: When the user requests multiple files (e.g., 'generate 3 JSON files'), use a SINGLE ai.generateCode action with a prompt that describes ALL requested files, rather than splitting into multiple actions.",
                dynamicMode=True,
                parameters={
                    "prompt": WorkflowActionParameter(
                        name="prompt",
                        type="str",
                        frontendType=FrontendType.TEXTAREA,
                        required=True,
                        description="Description of code to generate. If multiple files are requested, describe ALL files in this single prompt (e.g., 'Generate 3 JSON files: 1) config.json with..., 2) customers.json with..., 3) settings.json with...')."
                    ),
                    "documentList": WorkflowActionParameter(
                        name="documentList",
                        type="List[str]",
                        frontendType=FrontendType.DOCUMENT_REFERENCE,
                        required=False,
                        description="Reference documents"
                    ),
                    "resultType": WorkflowActionParameter(
                        name="resultType",
                        type="str",
                        frontendType=FrontendType.SELECT,
                        frontendOptions=["py", "js", "ts", "html", "java", "cpp", "txt", "json", "csv", "xml"],
                        required=False,
                        description="Output format (html, js, py, json, csv, xml, etc.). Optional: if omitted, formats are determined from prompt by AI. This action can return MULTIPLE files in a single call when the prompt requests multiple files. With per-document format determination, AI can determine different formats for different files based on prompt. When multiple files are requested, the action will return multiple documents (one per file)."
                    )
                },
                execute=generateCode.__get__(self, self.__class__)
            )
        }
        
        # Validate actions after definition
        self._validateActions()
        
        # Register actions as methods (optional, für direkten Zugriff)
        self.process = process.__get__(self, self.__class__)
        self.webResearch = webResearch.__get__(self, self.__class__)
        self.summarizeDocument = summarizeDocument.__get__(self, self.__class__)
        self.translateDocument = translateDocument.__get__(self, self.__class__)
        self.convertDocument = convertDocument.__get__(self, self.__class__)
        self.generateDocument = generateDocument.__get__(self, self.__class__)
        self.generateCode = generateCode.__get__(self, self.__class__)
    
    def _format_timestamp_for_filename(self) -> str:
        """Format current timestamp as YYYYMMDD-hhmmss for filenames."""
        return datetime.now(UTC).strftime("%Y%m%d-%H%M%S")

