@page "/admin/areas"
@using ScadaLink.Security
@using ScadaLink.Commons.Entities.Instances
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)]
@inject ISiteRepository SiteRepository
@inject ITemplateEngineRepository TemplateEngineRepository

<div class="container-fluid mt-3">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">Area Management</h4>
    </div>

    <ToastNotification @ref="_toast" />
    <ConfirmDialog @ref="_confirmDialog" />

    @if (_loading)
    {
        <LoadingSpinner IsLoading="true" />
    }
    else if (_errorMessage != null)
    {
        <div class="alert alert-danger">@_errorMessage</div>
    }
    else
    {
        <div class="row">
            <div class="col-md-3">
                <div class="card">
                    <div class="card-header">
                        <h6 class="mb-0">Sites</h6>
                    </div>
                    <div class="list-group list-group-flush">
                        @if (_sites.Count == 0)
                        {
                            <div class="list-group-item text-muted small">No sites configured.</div>
                        }
                        @foreach (var site in _sites)
                        {
                            <button type="button"
                                    class="list-group-item list-group-item-action @(site.Id == _selectedSiteId ? "active" : "")"
                                    @onclick="() => SelectSite(site.Id)">
                                @site.Name
                            </button>
                        }
                    </div>
                </div>
            </div>

            <div class="col-md-9">
                @if (_selectedSiteId == 0)
                {
                    <div class="text-muted">Select a site to manage its areas.</div>
                }
                else
                {
                    <div class="d-flex justify-content-between align-items-center mb-2">
                        <h5 class="mb-0">Areas for @(_sites.FirstOrDefault(s => s.Id == _selectedSiteId)?.Name)</h5>
                        <button class="btn btn-primary btn-sm" @onclick="ShowAddForm">Add Area</button>
                    </div>

                    @if (_showForm)
                    {
                        <div class="card mb-3">
                            <div class="card-body">
                                <h6 class="card-title">@(_editingArea == null ? "Add New Area" : "Edit Area")</h6>
                                <div class="row g-2 align-items-end">
                                    <div class="col-md-4">
                                        <label class="form-label small">Name</label>
                                        <input type="text" class="form-control form-control-sm" @bind="_formName" />
                                    </div>
                                    @if (_editingArea == null)
                                    {
                                        <div class="col-md-4">
                                            <label class="form-label small">Parent Area</label>
                                            <select class="form-select form-select-sm" @bind="_formParentAreaId">
                                                <option value="0">(Root level)</option>
                                                @foreach (var area in _areas)
                                                {
                                                    <option value="@area.Id">@GetAreaPath(area)</option>
                                                }
                                            </select>
                                        </div>
                                    }
                                    <div class="col-md-4">
                                        <button class="btn btn-success btn-sm me-1" @onclick="SaveArea">Save</button>
                                        <button class="btn btn-outline-secondary btn-sm" @onclick="CancelForm">Cancel</button>
                                    </div>
                                </div>
                                @if (_formError != null)
                                {
                                    <div class="text-danger small mt-1">@_formError</div>
                                }
                            </div>
                        </div>
                    }

                    @if (_areas.Count == 0)
                    {
                        <div class="text-muted">No areas configured for this site.</div>
                    }
                    else
                    {
                        <div class="card">
                            <div class="card-body p-2">
                                @foreach (var node in BuildFlatTree())
                                {
                                    <div class="d-flex align-items-center py-1 border-bottom"
                                         style="padding-left: @(node.Depth * 24 + 8)px;">
                                        <span class="me-2 text-muted small">
                                            @(node.HasChildren ? "[+]" : "  -")
                                        </span>
                                        <span class="flex-grow-1">@node.Area.Name</span>
                                        <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1"
                                                @onclick="() => EditArea(node.Area)">Edit</button>
                                        <button class="btn btn-outline-danger btn-sm py-0 px-1"
                                                @onclick="() => DeleteArea(node.Area)">Delete</button>
                                    </div>
                                }
                            </div>
                        </div>
                    }
                }
            </div>
        </div>
    }
</div>

@code {
    private List<Site> _sites = new();
    private List<Area> _areas = new();
    private int _selectedSiteId;
    private bool _loading = true;
    private string? _errorMessage;

    private bool _showForm;
    private Area? _editingArea;
    private string _formName = string.Empty;
    private int _formParentAreaId;
    private string? _formError;

    private ToastNotification _toast = default!;
    private ConfirmDialog _confirmDialog = default!;

    protected override async Task OnInitializedAsync()
    {
        _loading = true;
        try
        {
            _sites = (await SiteRepository.GetAllSitesAsync()).ToList();
        }
        catch (Exception ex)
        {
            _errorMessage = $"Failed to load sites: {ex.Message}";
        }
        _loading = false;
    }

    private async Task SelectSite(int siteId)
    {
        _selectedSiteId = siteId;
        _showForm = false;
        await LoadAreasAsync();
    }

    private async Task LoadAreasAsync()
    {
        try
        {
            _areas = (await TemplateEngineRepository.GetAreasBySiteIdAsync(_selectedSiteId)).ToList();
        }
        catch (Exception ex)
        {
            _errorMessage = $"Failed to load areas: {ex.Message}";
        }
    }

    private record AreaTreeNode(Area Area, int Depth, bool HasChildren);

    private List<AreaTreeNode> BuildFlatTree()
    {
        var result = new List<AreaTreeNode>();
        AddChildren(null, 0, result);
        return result;
    }

    private void AddChildren(int? parentId, int depth, List<AreaTreeNode> result)
    {
        var children = _areas.Where(a => a.ParentAreaId == parentId).OrderBy(a => a.Name);
        foreach (var child in children)
        {
            var hasChildren = _areas.Any(a => a.ParentAreaId == child.Id);
            result.Add(new AreaTreeNode(child, depth, hasChildren));
            AddChildren(child.Id, depth + 1, result);
        }
    }

    private string GetAreaPath(Area area)
    {
        var parts = new List<string>();
        var current = area;
        while (current != null)
        {
            parts.Insert(0, current.Name);
            current = current.ParentAreaId.HasValue
                ? _areas.FirstOrDefault(a => a.Id == current.ParentAreaId.Value)
                : null;
        }
        return string.Join(" / ", parts);
    }

    private void ShowAddForm()
    {
        _editingArea = null;
        _formName = string.Empty;
        _formParentAreaId = 0;
        _formError = null;
        _showForm = true;
    }

    private void EditArea(Area area)
    {
        _editingArea = area;
        _formName = area.Name;
        _formError = null;
        _showForm = true;
    }

    private void CancelForm()
    {
        _showForm = false;
        _editingArea = null;
        _formError = null;
    }

    private async Task SaveArea()
    {
        _formError = null;
        if (string.IsNullOrWhiteSpace(_formName)) { _formError = "Name is required."; return; }

        try
        {
            if (_editingArea != null)
            {
                _editingArea.Name = _formName.Trim();
                await TemplateEngineRepository.UpdateAreaAsync(_editingArea);
            }
            else
            {
                var area = new Area(_formName.Trim())
                {
                    SiteId = _selectedSiteId,
                    ParentAreaId = _formParentAreaId == 0 ? null : _formParentAreaId
                };
                await TemplateEngineRepository.AddAreaAsync(area);
            }
            await TemplateEngineRepository.SaveChangesAsync();
            _showForm = false;
            _editingArea = null;
            _toast.ShowSuccess("Area saved.");
            await LoadAreasAsync();
        }
        catch (Exception ex)
        {
            _formError = $"Save failed: {ex.Message}";
        }
    }

    private async Task DeleteArea(Area area)
    {
        var hasChildren = _areas.Any(a => a.ParentAreaId == area.Id);
        var message = hasChildren
            ? $"Area '{area.Name}' has child areas. Delete child areas first."
            : $"Delete area '{area.Name}'?";

        var confirmed = await _confirmDialog.ShowAsync(message, "Delete Area");
        if (!confirmed) return;

        try
        {
            await TemplateEngineRepository.DeleteAreaAsync(area.Id);
            await TemplateEngineRepository.SaveChangesAsync();
            _toast.ShowSuccess($"Area '{area.Name}' deleted.");
            await LoadAreasAsync();
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Delete failed: {ex.Message}");
        }
    }
}
