using System;
using System.Diagnostics;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
//using UnityEditor.Experimental.TerrainAPI;
using Debug = UnityEngine.Debug;

#if UNITY_ANDROID && !UNITY_EDITOR
using Babybus.Uno;
#endif

#if UNITY_IOS
using UnityEngine.iOS;
#endif
namespace Stary.Evo.Editor
{
    public static class FileUtility
    {
        public static string GetStreamingAssetsPath(string fileName)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
        return System.IO.Path.Combine(Application.streamingAssetsPath+ "/Android",fileName);
#elif UNITY_EDITOR
            return System.IO.Path.Combine("file://" + Application.streamingAssetsPath + "/Android", fileName);
#elif UNITY_IOS
        return  "file://"+ System.IO.Path.Combine(Application.streamingAssetsPath + "/IOS", fileName);
#else
        return "";
#endif
        }

        /// <summary>
        /// 读取StreamingAssets目录文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static byte[] ReadStreamingAssets(string path)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            var bytes = AndroidStreamingAssetSyncLoader.LoadFile(path);
#else
            var bytes = File.ReadAllBytes(Application.streamingAssetsPath + "/" + path);
#endif
            return bytes;
        }

        public static void CreateDirectory(string path)
        {
            string directoryName = Path.GetDirectoryName(path);
            if (directoryName != "" && !Directory.Exists(directoryName))
                Directory.CreateDirectory(directoryName);
        }

        public static void WriteAllText(string path, string content)
        {
            if (string.IsNullOrEmpty(path)) return;
            CreateDirectory(path);
            File.WriteAllText(path, content);
        }

        public static void WriteAllBytes(string path, byte[] bytes)
        {
            if (string.IsNullOrEmpty(path)) return;
            CreateDirectory(path);
            File.WriteAllBytes(path, bytes);
        }

        public static void Move(string sourceFileName, string destFileName)
        {
            if (sourceFileName == destFileName)
                return;
            if (!File.Exists(sourceFileName))
                return;
            CreateDirectory(destFileName);
            DeleteFile(destFileName);
            File.Move(sourceFileName, destFileName);
        }

        public static void Copy(string sourceFileName, string destFileName, bool overwrite)
        {
            if (sourceFileName == destFileName)
                return;
            CreateDirectory(destFileName);
            File.Copy(sourceFileName, destFileName, overwrite);
        }

        public static void CopyDirectory(string srcPath, string dstPath, bool overwrite = true,
            string excludeExtension = ".meta")
        {
            DeleteFile(dstPath);
            if (!Directory.Exists(dstPath))
                Directory.CreateDirectory(dstPath);
            foreach (var file in Directory.GetFiles(srcPath, "*.*")
                         .Where(path => Path.GetExtension(path) != excludeExtension))
            {
                File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)), overwrite);
            }

            foreach (var dir in Directory.GetDirectories(srcPath)
                         .Where(path => Path.GetExtension(path) != excludeExtension))
                CopyDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)), overwrite);
        }

        public static void CopyDirectory(string srcPath, string dstPath, string[] excludeFileExtensions,
            string[] excludeDirectoryExtensions = null, bool overwrite = true)
        {
            if (!Directory.Exists(dstPath))
                Directory.CreateDirectory(dstPath);
            foreach (var file in Directory.GetFiles(srcPath, "*.*", SearchOption.TopDirectoryOnly).Where(path =>
                         excludeFileExtensions == null || !excludeFileExtensions.Contains(Path.GetExtension(path))))
            {
                File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)), overwrite);
            }

            foreach (var dir in Directory.GetDirectories(srcPath).Where(path =>
                         excludeDirectoryExtensions == null ||
                         !excludeDirectoryExtensions.Contains(Path.GetExtension(path))))
                CopyDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)), excludeFileExtensions,
                    excludeDirectoryExtensions, overwrite);
        }

        public static void DeleteFile(string path)
        {
            if (File.Exists(path))
                File.Delete(path);
        }

        /// <summary>
        /// 文件是否被占用
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static bool IsFileInUse(string fileName)
        {
            if (File.Exists(fileName) == false) return false;
            bool inUse = true;
            FileStream fs = null;
            try
            {
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
                inUse = false;
            }
            catch
            {
                // ignored
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }

            return inUse; //true表示正在使用,false没有使用
        }

        /// <summary>
        /// 是否只读文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static bool IsReadOnly(string path)
        {
            if (!File.Exists(path)) return false;
            FileInfo fi = new FileInfo(path);
            return fi.IsReadOnly;
        }

        public static void DeleteDirectory(string path)
        {
            if (Directory.Exists(path)) Directory.Delete(path, true);
        }

        public static string GetFullPathWithoutExtension(string path)
        {
            return Path.GetDirectoryName(path) + "/" + Path.GetFileNameWithoutExtension(path);
        }

        public static int GetFileSize(string path)
        {
            if (!File.Exists(path)) return 0;
            FileStream fs = new FileStream(path, FileMode.Open);
            long length = fs.Length;
            fs.Close();
            return (int)length;
        }

        /// <summary>
        /// 获取文件夹下所有文件路径
        /// </summary>
        /// <param name="path"></param>
        /// <param name="extension">"*.mp3"</param>
        /// <returns></returns>
        public static string[] GetFiles(string path, string extension = "*")
        {
            if (File.Exists(path))
            {
                return Directory.GetFiles(path, extension, SearchOption.AllDirectories);
            }
            else
            {
                return null;
            }
        }

        public static void TakePhoto(Camera camera, string path, int width, int height, bool hideCamera = true)
        {
            Rect rect = new Rect(0, 0, width, height);
            camera.gameObject.SetActive(true);
            //特别注意事项
            camera.clearFlags = CameraClearFlags.SolidColor;
            var color = Color.black;
            color.a = 0.00001f;
            camera.backgroundColor = color;
            RenderTexture rt = new RenderTexture(width, height, 24);
            camera.targetTexture = rt;
            camera.Render();
            //ps: --- 如果这样加上第二个相机，可以实现只截图某几个指定的相机一起看到的图像。  
            //ps: camera2.targetTexture = rt;  
            //ps: camera2.Render();  
            //ps: -------------------------------------------------------------------  
            // 激活这个rt, 并从中中读取像素
            RenderTexture.active = rt;
            Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, true);
            texture.ReadPixels(rect, 0, 0);
            texture.Apply();
            RenderTexture.active = null;
            camera.gameObject.SetActive(!hideCamera);
            byte[] bytes = texture.EncodeToPNG();
            WriteAllBytes(path, bytes);
#if UNITY_EDITOR
            Debug.Log("截屏了一张照片: " + path);
#endif
        }

        public static Texture2D LoadTextureByIO(string path, int width, int height)
        {
            //创建文件读取流
            FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            fileStream.Seek(0, SeekOrigin.Begin);
            //创建文件长度缓冲区
            byte[] bytes = new byte[fileStream.Length];
            //读取文件
            fileStream.Read(bytes, 0, (int)fileStream.Length);
            //释放文件读取流
            fileStream.Close();
            fileStream.Dispose();
            fileStream = null;
            //创建Texture
            Texture2D texture = new Texture2D(width, height);
            texture.LoadImage(bytes);
#if UNITY_EDITOR
            Debug.Log("跳场景或删除时要Destroy(texutre)掉，不然内存会增加");
#endif
            return texture;
        }

        public static Sprite LoadSpriteByIO(string fileName, int width, int height)
        {
            Texture2D texture2D = LoadTextureByIO(fileName, width, height);
            return Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), new Vector2(0.5f, 0.5f));
        }

        // 硬盘检测方法
        public static bool CheckDriveExists(string driveLetter)
        {
            try
            {
                // 确保输入格式正确（例如："D:"）
                if (!driveLetter.EndsWith(":\\"))
                    driveLetter += ":\\";

                foreach (DriveInfo drive in DriveInfo.GetDrives())
                {
                    if (drive.IsReady && drive.Name.Equals(driveLetter, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"检测硬盘时发生错误: {e.Message}");
            }

            return false;
        }


        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param name="path"></param>
        public static void OpenDirectory(string path)
        {
#if UNITY_EDITOR
            if (string.IsNullOrEmpty(path)) return;
            path = path.Replace("/", "\\");
            if (!Directory.Exists(path))
            {
                Debug.LogError("No Directory: " + path);
                return;
            }

            System.Diagnostics.Process.Start("explorer.exe", path);
#endif
        }
    }
}