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

import logging
import json
from typing import Dict, Any
from modules.datamodels.datamodelChat import ActionResult, ActionDocument

logger = logging.getLogger(__name__)

async def copyFile(self, parameters: Dict[str, Any]) -> ActionResult:
    try:
        connectionReference = parameters.get("connectionReference")
        if not connectionReference:
            return ActionResult.isFailure(error="connectionReference parameter is required")
        
        # Set SharePoint access token first – required before siteDiscovery/sharepoint calls
        connection = self.connection.getMicrosoftConnection(connectionReference)
        if not connection:
            return ActionResult.isFailure(error="No valid Microsoft connection found for the provided connection reference")
        
        sourcePath = (parameters.get("sourcePath") or parameters.get("sourcePathQuery") or "").strip()
        destPath = (parameters.get("destPath") or parameters.get("destPathQuery") or "").strip()
        
        siteId = None
        sourceFolder = None
        sourceFile = None
        destFolder = None
        destFile = None
        
        if sourcePath and destPath and sourcePath.startswith("/sites/") and destPath.startswith("/sites/"):
            parsedSource = self.services.sharepoint.extractSiteFromStandardPath(sourcePath)
            parsedDest = self.services.sharepoint.extractSiteFromStandardPath(destPath)
            if parsedSource and parsedDest:
                innerSrc = (parsedSource.get("innerPath") or "").strip().rstrip("/")
                innerDest = (parsedDest.get("innerPath") or "").strip().rstrip("/")
                if innerSrc:
                    if "/" in innerSrc:
                        sourceFolder = innerSrc.rsplit("/", 1)[0]
                        sourceFile = innerSrc.rsplit("/", 1)[-1]
                    else:
                        sourceFolder = ""
                        sourceFile = innerSrc
                    destFolder = innerDest
                    destFile = sourceFile
                    sites, _ = await self.siteDiscovery.resolveSitesFromPathQuery(sourcePath)
                    if sites:
                        siteId = sites[0].get("id")
        
        if not siteId or not sourceFolder or not sourceFile or not destFolder:
            siteIdParam = parameters.get("siteId")
            sourceFolder = parameters.get("sourceFolder")
            sourceFile = parameters.get("sourceFile")
            destFolder = parameters.get("destFolder")
            destFile = parameters.get("destFile")
            if not siteIdParam:
                return ActionResult.isFailure(error="Either sourcePath+destPath or siteId, sourceFolder, sourceFile, destFolder, destFile are required")
            if not sourceFolder or not sourceFile or not destFolder or not destFile:
                return ActionResult.isFailure(error="sourceFolder, sourceFile, destFolder, and destFile are required")
            if not destFile:
                destFile = sourceFile
            if isinstance(siteIdParam, str):
                from modules.datamodels.datamodelDocref import DocumentReferenceList
                try:
                    docList = DocumentReferenceList.from_string_list([siteIdParam])
                    chatDocuments = self.services.chat.getChatDocumentsFromDocumentList(docList)
                    if chatDocuments and len(chatDocuments) > 0:
                        siteInfoJson = json.loads(chatDocuments[0].documentData)
                        siteId = siteInfoJson.get("id")
                except Exception:
                    pass
                if not siteId:
                    siteId = siteIdParam
            else:
                siteId = siteIdParam
        
        if not siteId:
            return ActionResult.isFailure(error="Could not resolve siteId")
        
        # Copy file
        await self.services.sharepoint.copyFileAsync(
            siteId=siteId,
            sourceFolder=sourceFolder,
            sourceFile=sourceFile,
            destFolder=destFolder,
            destFile=destFile
        )
        
        logger.info(f"Copied file in SharePoint: {sourceFolder}/{sourceFile} -> {destFolder}/{destFile}")
        
        # Generate filename
        workflowContext = self.services.chat.getWorkflowContext() if hasattr(self.services, 'chat') else None
        filename = self._generateMeaningfulFileName(
            "file_copy_result",
            "json",
            workflowContext,
            "copyFile"
        )
        
        result = {
            "success": True,
            "siteId": siteId,
            "sourcePath": f"{sourceFolder}/{sourceFile}",
            "destPath": f"{destFolder}/{destFile}"
        }
        
        validationMetadata = self._createValidationMetadata(
            "copyFile",
            siteId=siteId,
            sourcePath=f"{sourceFolder}/{sourceFile}",
            destPath=f"{destFolder}/{destFile}"
        )
        
        document = ActionDocument(
            documentName=filename,
            documentData=json.dumps(result, indent=2),
            mimeType="application/json",
            validationMetadata=validationMetadata
        )
        
        return ActionResult.isSuccess(documents=[document])
        
    except Exception as e:
        # Handle file not found gracefully
        if "itemNotFound" in str(e) or "404" in str(e):
            logger.warning(f"File not found for copy: {parameters.get('sourceFolder')}/{parameters.get('sourceFile')}")
            # Return success with skipped status
            workflowContext = self.services.chat.getWorkflowContext() if hasattr(self.services, 'chat') else None
            filename = self._generateMeaningfulFileName(
                "file_copy_result",
                "json",
                workflowContext,
                "copyFile"
            )
            
            result = {
                "success": True,
                "skipped": True,
                "reason": "File not found (may not exist yet)"
            }
            
            validationMetadata = self._createValidationMetadata(
                "copyFile",
                skipped=True
            )
            
            document = ActionDocument(
                documentName=filename,
                documentData=json.dumps(result, indent=2),
                mimeType="application/json",
                validationMetadata=validationMetadata
            )
            
            return ActionResult.isSuccess(documents=[document])
        
        errorMsg = f"Error copying file in SharePoint: {str(e)}"
        logger.error(errorMsg)
        return ActionResult.isFailure(error=errorMsg)

