using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace LLM.Editor.Analysis
{
    /// <summary>
    /// Finds assets in the project. Supports both standard AssetDatabase queries
    /// and file path glob patterns.
    /// </summary>
    public class FindAssetsProvider : IContextProvider
    {
        public class AssetInfo
        {
            public string guid;
            public string path;
            public string name;
        }

        public object GetContext(Object target, string qualifier)
        {
            if (string.IsNullOrEmpty(qualifier))
            {
                return "Error: A query string (qualifier) is required for FindAssets.";
            }

            // If the query contains wildcards or path separators, use glob search.
            if (qualifier.Contains("*") || qualifier.Contains("/"))
            {
                return FindAssetsByGlob(qualifier);
            }
            
            // Otherwise, use the default AssetDatabase search.
            return FindAssetsByQuery(qualifier);
        }

        private static object FindAssetsByGlob(string pattern)
        {
            try
            {
                var assetsPath = Application.dataPath;
                var absolutePatternPath = Path.GetDirectoryName(Path.Combine(assetsPath, pattern));
                var searchPattern = Path.GetFileName(pattern);

                if (!Directory.Exists(absolutePatternPath))
                {
                    return $"Error: Directory does not exist for glob pattern: {absolutePatternPath}";
                }

                var files = Directory.GetFiles(absolutePatternPath, searchPattern, SearchOption.AllDirectories);
                
                return files.Select(fullPath =>
                {
                    // Make path relative to Assets folder
                    var relativePath = "Assets" + fullPath.Substring(assetsPath.Length);
                    var guid = AssetDatabase.AssetPathToGUID(relativePath);
                    return new AssetInfo
                    {
                        guid = guid,
                        path = relativePath,
                        name = Path.GetFileName(relativePath)
                    };
                }).Where(info => !string.IsNullOrEmpty(info.guid)).ToArray();
            }
            catch (Exception e)
            {
                return $"Error during glob search: {e.Message}";
            }
        }

        private static object FindAssetsByQuery(string query)
        {
            var guids = AssetDatabase.FindAssets(query);
            if (guids != null && guids.Length > 0)
            {
                return guids.Select(guid =>
                {
                    var path = AssetDatabase.GUIDToAssetPath(guid);
                    return new AssetInfo
                    {
                        guid = guid,
                        path = path,
                        name = Path.GetFileName(path)
                    };
                }).ToArray();
            }

            // Handle direct GUID lookup as a fallback
            if (query.Contains("guid:"))
            {
                var guid = query.Replace("guid:", "").Trim();
                var path = AssetDatabase.GUIDToAssetPath(guid);
                if (!string.IsNullOrEmpty(path))
                {
                    return new[] { new AssetInfo { guid = guid, path = path, name = Path.GetFileName(path) } };
                }
            }

            return Array.Empty<AssetInfo>();
        }
    }
}
