@page "/templates"
@using GmRelay.Web.Services
@using GmRelay.Shared.Domain
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@attribute [Authorize]
@inject AuthorizedSessionService SessionService
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager Navigation

<PageTitle>Шаблоны кампаний — GM-Relay</PageTitle>

<div class="page-container">
    <ul class="gm-breadcrumb animate-fade-in">
        <li><a href="/">Главная</a></li>
        <li class="active">Шаблоны кампаний</li>
    </ul>

    <div class="page-header animate-fade-in">
        <h2>📋 Шаблоны кампаний</h2>
        <p>Сохраняйте типовые кампании один раз и применяйте их на странице нужной группы.</p>
    </div>

    @if (!string.IsNullOrEmpty(errorMessage))
    {
        <div class="gm-alert gm-alert-danger" style="margin-bottom: 1rem;">
            ⚠️ @errorMessage
        </div>
    }

    @if (!string.IsNullOrEmpty(successMessage))
    {
        <div class="gm-alert gm-alert-success" style="margin-bottom: 1rem;">
            ✅ @successMessage
        </div>
    }

    @if (groups is null)
    {
        <div class="glass-card" style="padding: 2rem;">
            <div class="skeleton skeleton-text" style="width: 80%; margin-bottom: 1rem;"></div>
            <div class="skeleton skeleton-text" style="width: 60%; margin-bottom: 0.75rem;"></div>
            <div class="skeleton skeleton-text" style="width: 70%;"></div>
        </div>
    }
    else if (groups.Count == 0)
    {
        <div class="glass-card">
            <div class="empty-state">
                <div class="empty-state-icon">🤖</div>
                <div class="empty-state-title">Нет доступных групп</div>
                <p class="empty-state-text">Добавьте бота GM-Relay в группу Telegram, чтобы создать первый шаблон кампании.</p>
            </div>
        </div>
    }
    else
    {
        <div class="glass-card campaign-template-panel animate-slide-up">
            <div class="batch-bulk-header">
                <div>
                    <h3>Группа для шаблонов</h3>
                    <p>@(SelectedGroup?.Name ?? "Выберите группу")</p>
                </div>
                @if (SelectedGroup is not null)
                {
                    <span class="status-badge @(SelectedGroup.ManagerRole == GroupManagerRoleExtensions.OwnerValue ? "status-success" : "status-info")">
                        @FormatRole(SelectedGroup.ManagerRole)
                    </span>
                }
            </div>

            <div class="template-group-selector">
                <select value="@selectedGroupId" @onchange="OnSelectedGroupChanged" class="gm-form-control">
                    @foreach (var group in groups)
                    {
                        <option value="@group.Id">@group.Name</option>
                    }
                </select>
                @if (SelectedGroup is not null)
                {
                    <a href="/group/@SelectedGroup.Id" class="btn-gm btn-gm-outline">Открыть группу →</a>
                }
            </div>
        </div>

        <div class="glass-card campaign-template-panel animate-slide-up">
            <div class="batch-bulk-header">
                <div>
                    <h3>Новый шаблон</h3>
                    <p>Эти параметры будут использоваться при запуске batch из группы.</p>
                </div>
                <span class="status-badge status-info">Template</span>
            </div>

            <EditForm Model="@templateModel" OnValidSubmit="CreateCampaignTemplate">
                <div class="campaign-template-fields">
                    <div class="gm-form-group">
                        <label class="gm-form-label">Название шаблона</label>
                        <InputText @bind-Value="templateModel.Name" class="gm-form-control" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Название кампании</label>
                        <InputText @bind-Value="templateModel.Title" class="gm-form-control" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Ссылка</label>
                        <InputText @bind-Value="templateModel.JoinLink" class="gm-form-control" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Игр</label>
                        <InputNumber @bind-Value="templateModel.SessionCount" class="gm-form-control" min="1" max="52" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Интервал, дней</label>
                        <InputNumber @bind-Value="templateModel.IntervalDays" class="gm-form-control" min="1" max="365" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Мест</label>
                        <InputNumber @bind-Value="templateModel.MaxPlayers" class="gm-form-control" min="1" />
                    </div>
                    <div class="gm-form-group">
                        <label class="gm-form-label">Уведомления</label>
                        <select @bind="templateModel.NotificationMode" class="gm-form-control">
                            <option value="@SessionNotificationModeExtensions.GroupAndDirectValue">В группе и в личку</option>
                            <option value="@SessionNotificationModeExtensions.GroupOnlyValue">Только в группе</option>
                        </select>
                    </div>
                </div>

                <button type="submit" class="btn-gm btn-gm-primary" disabled="@isCreatingTemplate">
                    @(isCreatingTemplate ? "⏳ Сохраняем..." : "💾 Сохранить шаблон")
                </button>
            </EditForm>
        </div>

        <div class="glass-card campaign-template-panel animate-slide-up">
            <div class="batch-bulk-header">
                <div>
                    <h3>Сохранённые шаблоны</h3>
                    <p>@campaignTemplateModels.Count для выбранной группы</p>
                </div>
                <span class="status-badge status-info">@campaignTemplateModels.Count</span>
            </div>

            @if (campaignTemplates is null)
            {
                <div class="skeleton skeleton-text" style="width: 70%; margin-bottom: 0.75rem;"></div>
                <div class="skeleton skeleton-text" style="width: 55%;"></div>
            }
            else if (campaignTemplateModels.Count == 0)
            {
                <div class="empty-state empty-state-compact">
                    <div class="empty-state-title">Шаблонов пока нет</div>
                    <p class="empty-state-text">Создайте первый шаблон для выбранной группы.</p>
                </div>
            }
            else
            {
                <div class="campaign-template-list">
                    @foreach (var template in campaignTemplateModels)
                    {
                        <div class="campaign-template-row template-management-row">
                            <div class="campaign-template-info">
                                <h3>@template.Name</h3>
                                <p>@FormatTemplateSummary(template)</p>
                            </div>
                            <div class="template-management-actions">
                                <span class="status-badge status-neutral">@FormatLocalMoscow(template.UpdatedAt.ToMoscow())</span>
                                <button type="button" class="btn-gm btn-gm-danger" disabled="@(deletingTemplateId == template.Id)" @onclick="() => DeleteCampaignTemplate(template)">
                                    @(deletingTemplateId == template.Id ? "⏳ Удаляем..." : "Удалить")
                                </button>
                            </div>
                        </div>
                    }
                </div>
            }
        </div>
    }
</div>

@code {
    private List<WebGameGroup>? groups;
    private List<WebCampaignTemplate>? campaignTemplates;
    private List<CampaignTemplateManagementModel> campaignTemplateModels = [];
    private Guid selectedGroupId;
    private Guid? deletingTemplateId;
    private bool isCreatingTemplate;
    private long telegramId;
    private string? errorMessage;
    private string? successMessage;
    private CampaignTemplateEditModel templateModel = new();

    private WebGameGroup? SelectedGroup => groups?.FirstOrDefault(group => group.Id == selectedGroupId);

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthStateProvider.GetAuthenticationStateAsync();
        if (!authState.User.TryGetTelegramId(out telegramId))
        {
            Navigation.NavigateTo("/access-denied");
            return;
        }

        groups = await SessionService.GetGroupsForGmAsync(telegramId);
        selectedGroupId = groups.FirstOrDefault()?.Id ?? Guid.Empty;

        if (selectedGroupId != Guid.Empty)
        {
            await LoadTemplates();
        }
    }

    private async Task OnSelectedGroupChanged(ChangeEventArgs args)
    {
        if (!Guid.TryParse(args.Value?.ToString(), out var groupId))
        {
            return;
        }

        selectedGroupId = groupId;
        errorMessage = null;
        successMessage = null;
        await LoadTemplates();
    }

    private async Task LoadTemplates()
    {
        campaignTemplates = null;
        campaignTemplateModels = [];

        var templates = await SessionService.GetCampaignTemplatesForGmAsync(selectedGroupId, telegramId);
        if (templates is null)
        {
            Navigation.NavigateTo("/access-denied");
            return;
        }

        campaignTemplates = templates;
        RebuildCampaignTemplateModels();
    }

    private async Task CreateCampaignTemplate()
    {
        errorMessage = null;
        successMessage = null;

        if (selectedGroupId == Guid.Empty)
        {
            errorMessage = "Выберите группу для шаблона.";
            return;
        }

        if (!ValidateCampaignTemplate(templateModel))
        {
            errorMessage = "Шаблон должен иметь название, ссылку, 1-52 игр, шаг 1-365 дней и положительный лимит мест, если он указан.";
            return;
        }

        isCreatingTemplate = true;

        try
        {
            await SessionService.CreateCampaignTemplateForGmAsync(
                selectedGroupId,
                telegramId,
                new CreateCampaignTemplateRequest(
                    templateModel.Name,
                    templateModel.Title,
                    templateModel.JoinLink,
                    templateModel.SessionCount,
                    templateModel.IntervalDays,
                    templateModel.MaxPlayers,
                    SessionNotificationModeExtensions.FromDatabaseValue(templateModel.NotificationMode)));

            templateModel = new();
            successMessage = "Шаблон кампании сохранён.";
            await LoadTemplates();
        }
        catch (SessionAccessDeniedException)
        {
            Navigation.NavigateTo("/access-denied");
        }
        catch (Exception ex)
        {
            errorMessage = "Не удалось сохранить шаблон: " + ex.Message;
        }
        finally
        {
            isCreatingTemplate = false;
        }
    }

    private async Task DeleteCampaignTemplate(CampaignTemplateManagementModel template)
    {
        errorMessage = null;
        successMessage = null;
        deletingTemplateId = template.Id;

        try
        {
            await SessionService.DeleteCampaignTemplateForGmAsync(template.Id, telegramId);
            successMessage = "Шаблон кампании удалён.";
            await LoadTemplates();
        }
        catch (SessionAccessDeniedException)
        {
            Navigation.NavigateTo("/access-denied");
        }
        catch (Exception ex)
        {
            errorMessage = "Не удалось удалить шаблон: " + ex.Message;
        }
        finally
        {
            deletingTemplateId = null;
        }
    }

    private void RebuildCampaignTemplateModels()
    {
        campaignTemplateModels = campaignTemplates?
            .OrderByDescending(template => template.UpdatedAt)
            .ThenBy(template => template.Name)
            .Select(template => new CampaignTemplateManagementModel
            {
                Id = template.Id,
                Name = template.Name,
                Title = template.Title,
                JoinLink = template.JoinLink,
                SessionCount = template.SessionCount,
                IntervalDays = template.IntervalDays,
                MaxPlayers = template.MaxPlayers,
                NotificationMode = template.NotificationMode,
                UpdatedAt = template.UpdatedAt
            })
            .ToList() ?? [];
    }

    private static bool ValidateCampaignTemplate(CampaignTemplateEditModel template)
    {
        template.Name = template.Name.Trim();
        template.Title = template.Title.Trim();
        template.JoinLink = template.JoinLink.Trim();

        if (template.MaxPlayers.HasValue && template.MaxPlayers.Value <= 0)
        {
            return false;
        }

        return template.Name.Length > 0 &&
               template.Title.Length > 0 &&
               template.JoinLink.Length > 0 &&
               template.SessionCount is >= 1 and <= 52 &&
               template.IntervalDays is >= 1 and <= 365;
    }

    private static string FormatTemplateSummary(CampaignTemplateManagementModel template)
    {
        var seats = template.MaxPlayers.HasValue
            ? $"{template.MaxPlayers.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)} мест"
            : "без лимита";

        return $"{template.Title} · {template.SessionCount} игр · каждые {template.IntervalDays} дн. · {seats} · {FormatNotificationMode(template.NotificationMode)}";
    }

    private static string FormatNotificationMode(string notificationMode) =>
        SessionNotificationModeExtensions.FromDatabaseValue(notificationMode) switch
        {
            SessionNotificationMode.GroupOnly => "только группа",
            _ => "группа и личка"
        };

    private static string FormatRole(string role) =>
        GroupManagerRoleExtensions.FromDatabaseValue(role).ToDisplayName();

    private static string FormatLocalMoscow(DateTime localMoscow) =>
        localMoscow.ToString("d MMMM yyyy, HH:mm", System.Globalization.CultureInfo.GetCultureInfo("ru-RU"));

    private sealed class CampaignTemplateEditModel
    {
        public string Name { get; set; } = "";
        public string Title { get; set; } = "";
        public string JoinLink { get; set; } = "";
        public int SessionCount { get; set; } = 6;
        public int IntervalDays { get; set; } = 7;
        public int? MaxPlayers { get; set; }
        public string NotificationMode { get; set; } = SessionNotificationModeExtensions.GroupAndDirectValue;
    }

    private sealed class CampaignTemplateManagementModel
    {
        public Guid Id { get; init; }
        public string Name { get; init; } = "";
        public string Title { get; init; } = "";
        public string JoinLink { get; init; } = "";
        public int SessionCount { get; init; }
        public int IntervalDays { get; init; }
        public int? MaxPlayers { get; init; }
        public string NotificationMode { get; init; } = SessionNotificationModeExtensions.GroupAndDirectValue;
        public DateTime UpdatedAt { get; init; }
    }
}
