DataGridView Sütun başlıklarına özellik ekle, veriler zamana göre artan veya azalan sıralanabilsin, ad'a göre de sıralama özelliği ekle -> using System;
using System.Windows.Forms;
using Firebase.Database;
using Firebase.Database.Query;
using FirebaseAdmin;
using Google.Apis.Auth.OAuth2;
using System.Threading.Tasks;
using System.Linq;
using System.Drawing;
using System.Collections.Generic;

namespace Flashcard
{
    public partial class MainForm : Form
    {
        private FirebaseClient firebaseClient;
        private DataGridView dataGridView;
        private TextBox txtTitle, txtCategory, txtContent, txtBackgroundColor, txtSearch;
        private CheckBox chkFavorite, chkPinned;
        private Button btnAdd, btnUpdate, btnDelete, btnSearch, btnClear;
        private StatusStrip statusStrip;
        private ToolStripStatusLabel statusLabel;

        public MainForm()
        {
            InitializeComponent();
            InitializeFirebase();
            InitializeUI();
        }

        private void InitializeFirebase()
        {
            var path = "flashcard-e7f47-firebase-adminsdk-om656-e70a5506c2.json";
            var credential = GoogleCredential.FromFile(path);

            FirebaseApp.Create(new AppOptions
            {
                Credential = credential
            });

            firebaseClient = new FirebaseClient("https://flashcard-e7f47-default-rtdb.europe-west1.firebasedatabase.app/");
        }

        private void InitializeUI()
        {
            this.Size = new Size(800, 600);
            this.Text = "Flashcard Application";

            dataGridView = new DataGridView
            {
                Dock = DockStyle.Top,
                Height = 300,
                AllowUserToAddRows = false,
                AllowUserToDeleteRows = false,
                ReadOnly = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                MultiSelect = true,
                AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill // Sütunların genişliğini otomatik olarak ayarla
            };
            dataGridView.SelectionChanged += DataGridView_SelectionChanged;
            dataGridView.CellContentClick += DataGridView_CellContentClick;
            dataGridView.CellFormatting += DataGridView_CellFormatting;
            Controls.Add(dataGridView);

            txtCategory = CreateTextBox("Category", 10, 320, 180); // Category metin kutusu önce
            txtTitle = CreateTextBox("Title", 200, 320, 180); // Title metin kutusu sonra
            txtContent = CreateTextBox("Content", 10, 350, 370); // Content metin kutusu
            txtBackgroundColor = CreateTextBox("Background Color", 390, 320, 180);
            txtSearch = CreateTextBox("Search...", 580, 320, 200);

            chkFavorite = new CheckBox { Text = "Favorite", Top = 320, Left = 390, Width = 80 };
            chkPinned = new CheckBox { Text = "Pinned", Top = 320, Left = 480, Width = 80 };
            Controls.Add(chkFavorite);
            Controls.Add(chkPinned);

            btnAdd = CreateButton("Add", 10, 380, 100);
            btnUpdate = CreateButton("Update", 120, 380, 100);
            btnDelete = CreateButton("Delete", 230, 380, 100);
            btnSearch = CreateButton("Search", 580, 350, 100);
            btnClear = CreateButton("Clear", 690, 350, 90);

            statusStrip = new StatusStrip();
            statusLabel = new ToolStripStatusLabel();
            statusStrip.Items.Add(statusLabel);
            Controls.Add(statusStrip);

            this.Load += MainForm_Load;
        }

        private async void MainForm_Load(object sender, EventArgs e)
        {
            await LoadDataAsync();
            RealTimeListener();
        }

        private TextBox CreateTextBox(string placeholder, int left, int top, int width)
        {
            TextBox textBox = new TextBox { Left = left, Top = top, Width = width, Text = placeholder };
            textBox.GotFocus += (sender, e) => { if (textBox.Text == placeholder) textBox.Text = ""; };
            textBox.LostFocus += (sender, e) => { if (string.IsNullOrWhiteSpace(textBox.Text)) textBox.Text = placeholder; };
            Controls.Add(textBox);
            return textBox;
        }

        private Button CreateButton(string text, int left, int top, int width)
        {
            Button button = new Button { Text = text, Left = left, Top = top, Width = width };
            button.Click += (sender, e) => ButtonClick(text);
            Controls.Add(button);
            return button;
        }

        private void ButtonClick(string buttonText)
        {
            switch (buttonText)
            {
                case "Add":
                    AddData();
                    break;
                case "Update":
                    UpdateData();
                    break;
                case "Delete":
                    DeleteData();
                    break;
                case "Search":
                    SearchData();
                    break;
                case "Clear":
                    ClearSearch();
                    break;
            }
        }

        private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && (e.ColumnIndex == dataGridView.Columns["favorite"].Index || e.ColumnIndex == dataGridView.Columns["pinned"].Index))
            {
                var flashcard = (Flashcard)dataGridView.Rows[e.RowIndex].DataBoundItem;
                bool newValue = !(bool)dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;

                if (e.ColumnIndex == dataGridView.Columns["favorite"].Index)
                {
                    flashcard.favorite = newValue;
                }
                else
                {
                    flashcard.pinned = newValue;
                }

                _ = UpdateFlashcardInDatabase(flashcard);
            }
        }

        private async Task UpdateFlashcardInDatabase(Flashcard flashcard)
        {
            try
            {
                await firebaseClient
                    .Child("flashcards")
                    .Child(flashcard.id)
                    .PutAsync(flashcard);

                await LoadDataAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error updating flashcard: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async Task LoadDataAsync()
        {
            try
            {
                var data = await firebaseClient
                    .Child("flashcards")
                    .OnceAsync<Flashcard>();

                var flashcards = data.Select(d => new Flashcard
                {
                    id = d.Key,
                    title = d.Object.title,
                    category = string.IsNullOrWhiteSpace(d.Object.category) ? "Uncategorized" : d.Object.category,
                    content = d.Object.content,
                    favorite = d.Object.favorite,
                    pinned = d.Object.pinned,
                    timestamp = d.Object.timestamp,
                    backgroundColor = d.Object.backgroundColor
                }).ToList();

                UpdateDataGridView(flashcards);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error loading data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void UpdateDataGridView(List<Flashcard> flashcards)
        {
            dataGridView.DataSource = null;
            dataGridView.Columns.Clear();

            if (flashcards.Any())
            {
                dataGridView.DataSource = flashcards;

            }
            else
            {
                dataGridView.Columns.Add("Message", "Message");
                dataGridView.Rows.Add("No flashcards found.");
            }

            statusLabel.Text = $"Total Items: {flashcards.Count}";
        }

        private async void AddData()
        {
            var newFlashcard = CreateFlashcardFromInputs();
            if (newFlashcard != null)
            {
                try
                {
                    var response = await firebaseClient
                        .Child("flashcards")
                        .PostAsync(newFlashcard);

                    newFlashcard.id = response.Key;
                    await LoadDataAsync();
                    ClearInputs();
                    MessageBox.Show("Flashcard added successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Error adding flashcard: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private async void UpdateData()
        {
            if (dataGridView.SelectedRows.Count > 0)
            {
                var selectedFlashcard = (Flashcard)dataGridView.SelectedRows[0].DataBoundItem;
                var updatedFlashcard = CreateFlashcardFromInputs();
                if (updatedFlashcard != null)
                {
                    updatedFlashcard.id = selectedFlashcard.id;
                    try
                    {
                        await firebaseClient
                            .Child("flashcards")
                            .Child(selectedFlashcard.id)
                            .PutAsync(updatedFlashcard);

                        await LoadDataAsync();
                        ClearInputs();
                        MessageBox.Show("Flashcard updated successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Error updating flashcard: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select a flashcard to update.", "No Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // Updated DeleteData method to handle multiple selections
        private async void DeleteData()
        {
            if (dataGridView.SelectedRows.Count > 0)
            {
                int selectedCount = dataGridView.SelectedRows.Count;
                var confirmResult = MessageBox.Show($"Are you sure you want to delete {selectedCount} flashcard(s)?",
                                                    "Confirm Delete",
                                                    MessageBoxButtons.YesNo,
                                                    MessageBoxIcon.Question);
                if (confirmResult == DialogResult.Yes)
                {
                    try
                    {
                        // Create a list of delete tasks
                        var deleteTasks = dataGridView.SelectedRows
                            .Cast<DataGridViewRow>()
                            .Select(row =>
                            {
                                var flashcard = (Flashcard)row.DataBoundItem;
                                return firebaseClient.Child("flashcards").Child(flashcard.id).DeleteAsync();
                            })
                            .ToList();

                        // Execute all delete tasks in parallel
                        await Task.WhenAll(deleteTasks);

                        // Clear inputs and reload data
                        ClearInputs();
                        await LoadDataAsync();

                        MessageBox.Show($"{selectedCount} flashcard(s) deleted successfully!",
                                        "Success",
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Error deleting flashcards: {ex.Message}",
                                        "Error",
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select one or more flashcards to delete.",
                                "No Selection",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
            }
        }

        private Flashcard CreateFlashcardFromInputs()
        {
            string title = txtTitle.Text == "Title" ? "" : txtTitle.Text;

            return new Flashcard
            {
                title = title,
                category = txtCategory.Text == "Category" ? "Uncategorized" : txtCategory.Text,
                content = txtContent.Text == "Content" ? "" : txtContent.Text,
                favorite = chkFavorite.Checked,
                pinned = chkPinned.Checked,
                timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                backgroundColor = txtBackgroundColor.Text == "Background Color" ? "" : txtBackgroundColor.Text
            };
        }

        private void ClearInputs()
        {
            txtTitle.Text = "Title";
            txtCategory.Text = "Category";
            txtContent.Text = "Content";
            txtBackgroundColor.Text = "Background Color";
            chkFavorite.Checked = false;
            chkPinned.Checked = false;
        }

        private void DataGridView_SelectionChanged(object sender, EventArgs e)
        {
            if (dataGridView.SelectedRows.Count > 0)
            {
                var selectedFlashcard = (Flashcard)dataGridView.SelectedRows[0].DataBoundItem;
                txtTitle.Text = selectedFlashcard.title;
                txtCategory.Text = selectedFlashcard.category;
                txtContent.Text = selectedFlashcard.content;
                txtBackgroundColor.Text = selectedFlashcard.backgroundColor;
                chkFavorite.Checked = selectedFlashcard.favorite;
                chkPinned.Checked = selectedFlashcard.pinned;
            }
        }

        private void RealTimeListener()
        {
            firebaseClient
                .Child("flashcards")
                .AsObservable<Flashcard>()
                .Subscribe(d =>
                {
                    Invoke((Action)(() => LoadDataAsync().ConfigureAwait(false)));
                });
        }

        private void SearchData()
        {
            string searchTerm = txtSearch.Text.ToLower();
            if (string.IsNullOrWhiteSpace(searchTerm) || searchTerm == "Search...")
            {
                _ = LoadDataAsync();
                return;
            }

            var allData = (List<Flashcard>)dataGridView.DataSource;
            if (allData != null)
            {
                var filteredData = allData
                    .Where(f => f.title.ToLower().Contains(searchTerm) ||
                                f.category.ToLower().Contains(searchTerm) ||
                                f.content.ToLower().Contains(searchTerm))
                    .ToList();

                UpdateDataGridView(filteredData);
            }
        }

        private void ClearSearch()
        {
            txtSearch.Text = "Search...";
            _ = LoadDataAsync();
        }
        private void DataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (dataGridView.Columns[e.ColumnIndex].Name == "timestamp")
            {
                if (e.Value != null)
                {
                    long timestamp = Convert.ToInt64(e.Value);
                    DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(timestamp);
                    DateTime dateTime = dateTimeOffset.ToOffset(TimeSpan.FromHours(3)).DateTime; // Türkiye saati için UTC+3
                    e.Value = dateTime.ToString("yyyy-MM-dd HH:mm:ss");
                    e.FormattingApplied = true;
                }
            }
        }
    }

        public class Flashcard
    {
        public string id { get; set; }

        public string category { get; set; }

        public string title { get; set; }

        public string content { get; set; }
        public bool favorite { get; set; }
        public bool pinned { get; set; }
        public long timestamp { get; set; }
        public string backgroundColor { get; set; }
    }
}