using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Reader
{
    public partial class MainForm : Form
    {
        private static readonly HttpClient http = new HttpClient();
        private static readonly string ServerUrl;
        private static readonly HashSet<string> DocumentExtensions = new(StringComparer.OrdinalIgnoreCase)
        {
            ".doc", ".docx", ".pdf", ".ppt", ".pptx"
        };
        private MouseButtons lastGridMouseButton = MouseButtons.Left;

        static MainForm()
        {
            var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json");
            var jsonContent = System.IO.File.ReadAllText(configPath);
            var start = jsonContent.IndexOf('"', jsonContent.IndexOf("ServerUrl") + 10);
            var end = jsonContent.IndexOf('"', start + 1);
            ServerUrl = jsonContent.Substring(start + 1, end - start - 1).Trim();
        }

        public MainForm()
        {
            InitializeComponent();
            dgv.CellMouseDown += dgv_CellMouseDown;
            dgv.CellMouseClick += dgv_CellMouseClick;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using var fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                txtFolder.Text = fbd.SelectedPath;
            }
        }

        private async void btnRead_Click(object sender, EventArgs e)
        {
            var folder = txtFolder.Text;
            if (string.IsNullOrWhiteSpace(folder) || !Directory.Exists(folder))
            {
                MessageBox.Show("请选择有效的文件夹。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            dgv.Rows.Clear();
            var files = Directory
                .GetFiles(folder, "*", SearchOption.AllDirectories)
                .Where(IsSupportedDocument)
                .OrderBy(Path.GetFileName, StringComparer.CurrentCultureIgnoreCase)
                .ToList();
            var fileEntries = new List<(string FilePath, string Sha)>();
            var shaList = new List<string>();
            foreach (var f in files)
            {
                try
                {
                    var sha = await Task.Run(() => ComputeSha256(f));
                    fileEntries.Add((f, sha));
                    shaList.Add(sha);
                }
                catch { }
            }
            if (fileEntries.Count == 0)
            {
                MessageBox.Show("没有找到支持的文档文件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            var payload = new { shas = shaList.Distinct().ToList() };
            var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
            var resp = await http.PostAsync(ServerUrl + "/read", content);
            if (!resp.IsSuccessStatusCode)
            {
                MessageBox.Show("读取失败: " + await resp.Content.ReadAsStringAsync(), "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            var text = await resp.Content.ReadAsStringAsync();
            using var doc = JsonDocument.Parse(text);
            var root = doc.RootElement;
            var data = root.GetProperty("data");
            foreach (var entry in fileEntries)
            {
                var fileName = Path.GetFileName(entry.FilePath);
                string up = "无";
                string down = "无";
                if (data.TryGetProperty(entry.Sha, out var item) && item.ValueKind != JsonValueKind.Null)
                {
                    up = item.GetProperty("upload_code").GetString() ?? "";
                    down = item.GetProperty("download_code").GetString() ?? "";
                }
                var rowIndex = dgv.Rows.Add(fileName, up, down);
                dgv.Rows[rowIndex].Tag = entry.FilePath;
                dgv.Rows[rowIndex].Cells["Filename"].ToolTipText = entry.FilePath;
            }
        }

        private static bool IsSupportedDocument(string filePath)
        {
            return DocumentExtensions.Contains(Path.GetExtension(filePath));
        }

        private static string ComputeSha256(string filePath)
        {
            using var sha = SHA256.Create();
            using var stream = File.OpenRead(filePath);
            var hash = sha.ComputeHash(stream);
            var sb = new StringBuilder();
            foreach (var b in hash) sb.Append(b.ToString("x2"));
            return sb.ToString();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.ShowCellToolTips = true;
            dgv.Columns["Filename"].Width = 500;
            dgv.Columns["eryi_ID"].Width = 100;
            dgv.Columns["下载者用户名"].Width = 100;
        }

        private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (lastGridMouseButton == MouseButtons.Right)
            {
                return;
            }
            HandleGridClick(e);
        }

        private void dgv_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            lastGridMouseButton = e.Button;
        }

        private void dgv_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0 || e.Button != MouseButtons.Right)
            {
                return;
            }

            var columnName = dgv.Columns[e.ColumnIndex].Name;
            if (columnName != "Filename")
            {
                return;
            }

            var row = dgv.Rows[e.RowIndex];
            var filePath = row.Tag as string;
            if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
            {
                OpenFolderAndSelectFile(filePath);
            }
        }

        private void HandleGridClick(DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0)
            {
                return;
            }

            var row = dgv.Rows[e.RowIndex];
            var columnName = dgv.Columns[e.ColumnIndex].Name;
            if (columnName == "Filename")
            {
                var filePath = row.Tag as string;
                if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
                {
                    OpenWithShell(filePath);
                }
                return;
            }

            if (columnName == "eryi_ID")
            {
                var code = row.Cells["eryi_ID"].Value?.ToString()?.Trim() ?? "";
                if (!string.IsNullOrWhiteSpace(code) && code != "无")
                {
                    OpenWithShell($"https://www.21cnjy.com/H/3/309824/{code}.shtml?token=mK2x9Pq7Rf4Tz8Wv1Lc3Yh5Nj6Bs0Ad9Eg2Hj3Kl4Mp5Qr6St7Uv8Wx9Yz0Ab1Cd");
                }
            }
        }

        private static void OpenFolderAndSelectFile(string filePath)
        {
            try
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = "explorer.exe",
                    Arguments = $"/select,\"{filePath}\"",
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("打开文件所在位置失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private static void OpenWithShell(string target)
        {
            try
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = target,
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("打开失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
