using System.IO; // Explicitly included for Path
using FrymasterBadgeApp.Services;
using Microsoft.Data.SqlClient;
using Microsoft.Maui.Controls.Shapes; // For RoundRectangle
using Microsoft.Maui.Graphics;

namespace FrymasterBadgeApp;

public partial class EmployeePage : ContentPage
{
    private readonly SqlService _db;
    private readonly PrinterService _printerService;
    private Dictionary<string, object>? _selectedEmployee;
    private readonly Dictionary<string, object> _currentCompany;

    private string _tempCapturePath = "";
    private double _editX = 0;
    private double _editY = 0;

    private string _currentBadgeType = "Office";
    private string _currentGuestImage = "Guest1.png";

    public EmployeePage(
        SqlService db,
        PrinterService printerService,
        Dictionary<string, object> company
    )
    {
        InitializeComponent();
        _db = db;
        _printerService = printerService;
        _currentCompany = company;

        EditorPhotoPreview.SetBinding(
            Image.ScaleProperty,
            new Binding("Value", source: ZoomSlider)
        );

        GuestImagePicker.Items.Add("Guest1.png");
        GuestImagePicker.Items.Add("Guest2.png");
        GuestImagePicker.Items.Add("Guest3.png");
        GuestImagePicker.SelectedIndex = 0;
        GuestImagePicker.SelectedIndexChanged += OnGuestImageChanged;

        BadgeTypePicker.SelectedIndexChanged += OnBadgeTypeChanged;

        LoadCompanyLogo();
        LoadEmployees();
    }

    private string GetPhotoDir()
    {
        string path = @"C:\FrymasterData\photos";
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);
        return path;
    }

    private void LoadCompanyLogo()
    {
        string logoPath = _currentCompany.GetValueOrDefault("logo")?.ToString() ?? "";
        if (!string.IsNullOrEmpty(logoPath) && File.Exists(logoPath))
        {
            PreviewLogoFront.Source = ImageSource.FromFile(logoPath);
        }
    }

    private void LoadEmployees()
    {
        string sql =
            "SELECT *, ISNULL(BadgeType, 'Office') AS BadgeType FROM dbo.tblData ORDER BY Data2";
        var results = _db.Query(sql, null);
        MainThread.BeginInvokeOnMainThread(() => EmployeeList.ItemsSource = results);
    }

    private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
    {
        string search = $"%{e.NewTextValue}%";
        string sql =
            @"SELECT *, ISNULL(BadgeType, 'Office') AS BadgeType 
                       FROM dbo.tblData 
                       WHERE Data2 LIKE @s OR Data1 LIKE @s 
                       ORDER BY Data2";
        var results = _db.Query(sql, new[] { new SqlParameter("@s", search) });
        MainThread.BeginInvokeOnMainThread(() =>
        {
            EmployeeList.SelectedItem = null;
            EmployeeList.ItemsSource = results;
        });
    }

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        _selectedEmployee = e.CurrentSelection.FirstOrDefault() as Dictionary<string, object>;
        if (_selectedEmployee == null)
        {
            ClearBadgePreview();
            return;
        }

        _currentBadgeType =
            _selectedEmployee.GetValueOrDefault("BadgeType")?.ToString() ?? "Office";
        BadgeTypePicker.SelectedItem = _currentBadgeType;
        GuestImageSelector.IsVisible = _currentBadgeType == "Guest";

        RenderBadgePreview(_selectedEmployee);
    }

    private void OnBadgeTypeChanged(object sender, EventArgs e)
    {
        if (_selectedEmployee == null)
            return;

        _currentBadgeType = BadgeTypePicker.SelectedItem?.ToString() ?? "Office";
        GuestImageSelector.IsVisible = _currentBadgeType == "Guest";

        string sql = "UPDATE dbo.tblData SET BadgeType = @type WHERE Data1 = @id";
        _db.Execute(
            sql,
            new[]
            {
                new SqlParameter("@type", _currentBadgeType),
                new SqlParameter("@id", _selectedEmployee["Data1"]),
            }
        );

        _selectedEmployee["BadgeType"] = _currentBadgeType;
        RenderBadgePreview(_selectedEmployee);
    }

    private void OnGuestImageChanged(object sender, EventArgs e)
    {
        _currentGuestImage = GuestImagePicker.SelectedItem?.ToString() ?? "Guest1.png";
        if (_selectedEmployee != null && _currentBadgeType == "Guest")
            RenderBadgePreview(_selectedEmployee);
    }

    private void ClearBadgePreview()
    {
        PreviewFrame.Content = null;
    }

    private void RenderBadgePreview(Dictionary<string, object> emp)
    {
        string firstName = (emp.GetValueOrDefault("Data8")?.ToString() ?? "").Trim();
        string lastName = (emp.GetValueOrDefault("Data7")?.ToString() ?? "").Trim();
        string recordNum = (emp.GetValueOrDefault("Data1")?.ToString() ?? "").Trim();
        string department = (emp.GetValueOrDefault("Data9")?.ToString() ?? "").Trim();
        string title = (emp.GetValueOrDefault("Data10")?.ToString() ?? "").Trim();
        string data5 = (emp.GetValueOrDefault("Data5")?.ToString() ?? "").Trim();

        string fullName = $"{firstName} {lastName}".Trim();
        string barcode = $"*{recordNum}*";

        string picCode = emp.GetValueOrDefault("picCode")?.ToString() ?? "";
        string photoPath = string.IsNullOrEmpty(picCode)
            ? ""
            : System.IO.Path.Combine(GetPhotoDir(), $"{picCode}.jpg"); // Fully qualified

        double scale = SafeToDouble(emp.GetValueOrDefault("cropScale"), 1.0);
        double tx = SafeToDouble(emp.GetValueOrDefault("cropX"), 0.0);
        double ty = SafeToDouble(emp.GetValueOrDefault("cropY"), 0.0);

        bool medicalBlue = false;
        bool medicalRed = false;

        var mainLayout = new HorizontalStackLayout
        {
            Spacing = 60,
            Padding = 20,
            HorizontalOptions = LayoutOptions.Center,
        };

        // FRONT BADGE
        var frontLayout = new VerticalStackLayout { Spacing = 15 };

        Color frontBg = Colors.White;
        Color frontBorderColor = Colors.Gray;

        switch (_currentBadgeType)
        {
            case "Plant":
                frontBg = Color.FromArgb("#e8f5e8");
                frontBorderColor = Colors.Green;
                break;
            case "Maintenance":
                frontBg = Color.FromArgb("#fff3e0");
                frontBorderColor = Colors.Orange;
                break;
            case "Guest":
                frontBg = Color.FromArgb("#f3e8ff");
                frontBorderColor = Colors.Purple;
                break;
            case "Visitor":
            case "Vendor":
                frontBg = Color.FromArgb("#ffebee");
                frontBorderColor = Colors.Red;
                break;
        }

        var frontBorder = new Border
        {
            Stroke = frontBorderColor,
            StrokeThickness = 4,
            BackgroundColor = frontBg,
            Padding = 25,
            WidthRequest = 380,
            StrokeShape = new RoundRectangle { CornerRadius = 20 },
            Shadow = new Shadow
            {
                Brush = SolidColorBrush.Black,
                Offset = new Point(0, 4),
                Radius = 10f,
                Opacity = 0.3f,
            },
            Content = frontLayout,
        };

        frontLayout.Children.Add(
            new Image
            {
                Source = PreviewLogoFront.Source,
                HeightRequest = 70,
                HorizontalOptions = LayoutOptions.Center,
                Aspect = Aspect.AspectFit,
            }
        );

        if (_currentBadgeType == "Guest")
        {
            frontLayout.Children.Add(
                new Image
                {
                    Source = ImageSource.FromResource(
                        $"FrymasterBadgeApp.Resources.Images.{_currentGuestImage}"
                    ),
                    HeightRequest = 200,
                    WidthRequest = 200,
                    Aspect = Aspect.AspectFit,
                }
            );
        }
        else if (File.Exists(photoPath))
        {
            var photoImg = new Image
            {
                Source = ImageSource.FromFile(photoPath),
                HeightRequest = 200,
                WidthRequest = 200,
                Aspect = Aspect.AspectFill,
                Scale = scale,
                TranslationX = tx,
                TranslationY = ty,
            };
            frontLayout.Children.Add(photoImg);
        }
        else
        {
            frontLayout.Children.Add(
                new Label
                {
                    Text = "No Photo",
                    FontSize = 18,
                    TextColor = Colors.Gray,
                    HorizontalTextAlignment = TextAlignment.Center,
                }
            );
        }

        frontLayout.Children.Add(
            new Label
            {
                Text = fullName,
                FontSize = 24,
                FontAttributes = FontAttributes.Bold,
                HorizontalTextAlignment = TextAlignment.Center,
                TextColor = Colors.Black,
            }
        );

        if (!string.IsNullOrEmpty(title))
            frontLayout.Children.Add(
                new Label
                {
                    Text = title,
                    FontSize = 18,
                    HorizontalTextAlignment = TextAlignment.Center,
                    TextColor = Colors.Black,
                }
            );

        if (!string.IsNullOrEmpty(department))
            frontLayout.Children.Add(
                new Label
                {
                    Text = department,
                    FontSize = 16,
                    HorizontalTextAlignment = TextAlignment.Center,
                    TextColor = Colors.Gray,
                }
            );

        mainLayout.Children.Add(frontBorder);

        // BACK BADGE
        var backLayout = new VerticalStackLayout { Spacing = 12 };

        var backBorder = new Border
        {
            Stroke = Colors.Gray,
            StrokeThickness = 4,
            BackgroundColor = Colors.White,
            Padding = 25,
            WidthRequest = 380,
            StrokeShape = new RoundRectangle { CornerRadius = 20 },
            Shadow = new Shadow
            {
                Brush = SolidColorBrush.Black,
                Offset = new Point(0, 4),
                Radius = 10f,
                Opacity = 0.3f,
            },
            Content = backLayout,
        };

        backLayout.Children.Add(
            new Image
            {
                Source = PreviewLogoFront.Source,
                HeightRequest = 50,
                HorizontalOptions = LayoutOptions.Center,
                Aspect = Aspect.AspectFit,
            }
        );

        backLayout.Children.Add(
            new Label
            {
                Text =
                    $"This badge is the property of {_currentCompany.GetValueOrDefault("Name")} L.L.C.",
                FontSize = 14,
                FontAttributes = FontAttributes.Bold,
                HorizontalTextAlignment = TextAlignment.Center,
                TextColor = Colors.Black,
            }
        );

        backLayout.Children.Add(
            new Label
            {
                Text = $"ID: {recordNum}",
                FontSize = 16,
                TextColor = Colors.Black,
            }
        );
        backLayout.Children.Add(
            new Label
            {
                Text = title,
                FontSize = 16,
                TextColor = Colors.Black,
            }
        );
        backLayout.Children.Add(
            new Label
            {
                Text = data5,
                FontSize = 16,
                TextColor = Colors.Black,
            }
        );

        string address = _currentCompany.GetValueOrDefault("Address")?.ToString() ?? "";
        if (!string.IsNullOrEmpty(address))
            backLayout.Children.Add(
                new Label
                {
                    Text = address,
                    FontSize = 14,
                    TextColor = Colors.Black,
                }
            );

        var locationParts = new[]
        {
            _currentCompany.GetValueOrDefault("City")?.ToString(),
            _currentCompany.GetValueOrDefault("State")?.ToString(),
            _currentCompany.GetValueOrDefault("Zip")?.ToString(),
        }
            .Where(p => !string.IsNullOrEmpty(p))
            .ToArray();

        if (locationParts.Length > 0)
            backLayout.Children.Add(
                new Label
                {
                    Text = string.Join(", ", locationParts),
                    FontSize = 14,
                    TextColor = Colors.Black,
                }
            );

        string phone = _currentCompany.GetValueOrDefault("Phone")?.ToString() ?? "";
        if (!string.IsNullOrEmpty(phone))
            backLayout.Children.Add(
                new Label
                {
                    Text = phone,
                    FontSize = 14,
                    TextColor = Colors.Black,
                }
            );

        if (medicalBlue || medicalRed)
        {
            var medStack = new HorizontalStackLayout
            {
                HorizontalOptions = LayoutOptions.Center,
                Spacing = 10,
            };
            if (medicalBlue)
                medStack.Children.Add(
                    new Label
                    {
                        Text = "🩺",
                        FontSize = 36,
                        TextColor = Colors.Blue,
                    }
                );
            if (medicalRed)
                medStack.Children.Add(
                    new Label
                    {
                        Text = "🩺",
                        FontSize = 36,
                        TextColor = Colors.Red,
                    }
                );
            backLayout.Children.Add(medStack);
        }

        if (_currentBadgeType == "Office" || _currentBadgeType == "Plant")
        {
            backLayout.Children.Add(
                new Label
                {
                    Text = barcode,
                    FontFamily = "BarcodeFont",
                    FontSize = 50,
                    HorizontalTextAlignment = TextAlignment.Center,
                    TextColor = Colors.Black,
                }
            );
        }

        mainLayout.Children.Add(backBorder);

        PreviewFrame.Content = mainLayout;
    }

    private async void OnTakePhotoClicked(object sender, EventArgs e)
    {
        if (_selectedEmployee == null)
            return;

        try
        {
            var photo = await MediaPicker.Default.CapturePhotoAsync();
            if (photo != null)
            {
                _tempCapturePath = System.IO.Path.Combine(
                    FileSystem.CacheDirectory,
                    "temp_editor.jpg"
                ); // Fully qualified
                using var source = await photo.OpenReadAsync();
                using var dest = File.OpenWrite(_tempCapturePath);
                await source.CopyToAsync(dest);

                EditorPhotoPreview.Source = ImageSource.FromFile(_tempCapturePath);
                _editX = _editY = 0;
                EditorPhotoPreview.TranslationX = EditorPhotoPreview.TranslationY = 0;
                ZoomSlider.Value = 1;
                PhotoEditorOverlay.IsVisible = true;
            }
        }
        catch (Exception ex)
        {
            await DisplayAlert("Camera Error", ex.Message, "OK");
        }
    }

    private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        if (e.StatusType == GestureStatus.Running)
        {
            EditorPhotoPreview.TranslationX = _editX + e.TotalX;
            EditorPhotoPreview.TranslationY = _editY + e.TotalY;
        }
        else if (e.StatusType == GestureStatus.Completed)
        {
            _editX = EditorPhotoPreview.TranslationX;
            _editY = EditorPhotoPreview.TranslationY;
        }
    }

    private async void OnApplyPhoto(object sender, EventArgs e)
    {
        if (_selectedEmployee == null)
            return;

        try
        {
            string firstName = (
                _selectedEmployee.GetValueOrDefault("Data8")?.ToString() ?? ""
            ).Trim();
            string lastName = (
                _selectedEmployee.GetValueOrDefault("Data7")?.ToString() ?? ""
            ).Trim();
            string recordNum = (
                _selectedEmployee.GetValueOrDefault("Data1")?.ToString() ?? ""
            ).Trim();

            string picCode = $"{lastName}{recordNum}{firstName}{lastName}";
            string finalPath = System.IO.Path.Combine(GetPhotoDir(), $"{picCode}.jpg"); // Fully qualified

            File.Copy(_tempCapturePath, finalPath, true);

            string sql =
                @"UPDATE dbo.tblData SET picCode = @pic, cropScale = @s, cropX = @x, cropY = @y WHERE Data1 = @id";

            _db.Execute(
                sql,
                new[]
                {
                    new SqlParameter("@pic", picCode),
                    new SqlParameter("@s", ZoomSlider.Value),
                    new SqlParameter("@x", EditorPhotoPreview.TranslationX),
                    new SqlParameter("@y", EditorPhotoPreview.TranslationY),
                    new SqlParameter("@id", recordNum),
                }
            );

            _selectedEmployee["picCode"] = picCode;
            _selectedEmployee["cropScale"] = ZoomSlider.Value;
            _selectedEmployee["cropX"] = EditorPhotoPreview.TranslationX;
            _selectedEmployee["cropY"] = EditorPhotoPreview.TranslationY;

            RenderBadgePreview(_selectedEmployee);
            PhotoEditorOverlay.IsVisible = false;
        }
        catch (Exception ex)
        {
            await DisplayAlert("Save Error", ex.Message, "OK");
        }
    }

    private void OnCancelPhoto(object sender, EventArgs e) => PhotoEditorOverlay.IsVisible = false;

    private double SafeToDouble(object? value, double defaultValue)
    {
        if (value == null || value == DBNull.Value)
            return defaultValue;
        return double.TryParse(value.ToString(), out double d) ? d : defaultValue;
    }

    private void OnPrintClicked(object sender, EventArgs e)
    {
        if (_selectedEmployee != null)
            _printerService.PrintBadge(_selectedEmployee, _currentCompany, _currentBadgeType);
    }
}
