@page "/"
@using Microsoft.EntityFrameworkCore
@using Microsoft.Extensions.Options
@using Wave.Data
@using Wave.Utilities
@using System.Globalization

@inject IOptions<Customization> Customizations
@inject IOptions<Features> Features
@inject NavigationManager Navigation
@inject IDbContextFactory<ApplicationDbContext> ContextFactory;
@inject IStringLocalizer<Home> Localizer
@inject IMessageDisplay Message

<HeadContent>
	<meta property="og:type" content="website">
	<meta property="og:title" content="@Customizations.Value.AppName">
	<meta property="og:site_name" content="@Customizations.Value.AppName">
	<meta property="og:url" content="@Navigation.BaseUri">
	@if (!string.IsNullOrWhiteSpace(Customizations.Value.LogoLink)) {
		<meta property="og:image" content="@Customizations.Value.LogoLink">
	} else {
		<meta property="og:image" content="@Navigation.ToAbsoluteUri("/img/logo.png")">
	}
	@if (!string.IsNullOrWhiteSpace(Customizations.Value.AppDescription)) {
		<meta name="description" content="@Customizations.Value.AppDescription">
		<meta property="og:description" content="@Customizations.Value.AppDescription">
	}
	@if (Features.Value.Rss) { 
		<link rel="alternate" type="application/rss+xml" title="RSS Feed on @Customizations.Value.AppName" href="/rss/rss.xml">
		<link rel="alternate" type="application/atom+xml" title="Atom RSS Feed on @Customizations.Value.AppName" href="/rss/atom.xml">
	}
	
	@if (Page >= TotalPages) {
		<meta name="robots" content="noindex">
	} else if (Page > 0) {
		<link rel="canonical" href="@(new UriBuilder(Navigation.BaseUri) { Scheme = "https", Query = "?page=" + Page, Port = -1 }.Uri.AbsoluteUri)" />
	} else {
		<link rel="canonical" href="@(new UriBuilder(Navigation.BaseUri) { Scheme = "https", Port = -1 }.Uri.AbsoluteUri)" />
	}
</HeadContent>

<PageTitle>@(Customizations.Value.AppName ?? "Wave")</PageTitle>

<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 xl:grid-rows-4 gap-4">
	<div class="sm:col-span-2 flex flex-col">
		<h1 class="text-3xl lg:text-5xl font-light mb-3 text-primary">@Customizations.Value.AppName</h1>
		<p class="flex-1 my-3">@Customizations.Value.AppDescription</p>
		<section class="flex gap-2 justify-between sm:justify-start flex-wrap mb-3">
			@if (Features.Value.Rss) {
				<a class="btn btn-sm bg-orange-500 text-slate-50" title="RSS Feed on @Customizations.Value.AppName" href="/rss/rss.xml">
					RSS
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
						<path fill-rule="evenodd" d="M3.75 4.5a.75.75 0 0 1 .75-.75h.75c8.284 0 15 6.716 15 15v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75C18 11.708 12.292 6 5.25 6H4.5a.75.75 0 0 1-.75-.75V4.5Zm0 6.75a.75.75 0 0 1 .75-.75h.75a8.25 8.25 0 0 1 8.25 8.25v.75a.75.75 0 0 1-.75.75H12a.75.75 0 0 1-.75-.75v-.75a6 6 0 0 0-6-6H4.5a.75.75 0 0 1-.75-.75v-.75Zm0 7.5a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0Z" clip-rule="evenodd" />
					</svg>
				</a>
				<a class="btn btn-sm bg-orange-500 text-slate-50" title="Atom RSS Feed on @Customizations.Value.AppName" href="/rss/atom.xml">
					Atom RSS
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
						<path fill-rule="evenodd" d="M3.75 4.5a.75.75 0 0 1 .75-.75h.75c8.284 0 15 6.716 15 15v.75a.75.75 0 0 1-.75.75h-.75a.75.75 0 0 1-.75-.75v-.75C18 11.708 12.292 6 5.25 6H4.5a.75.75 0 0 1-.75-.75V4.5Zm0 6.75a.75.75 0 0 1 .75-.75h.75a8.25 8.25 0 0 1 8.25 8.25v.75a.75.75 0 0 1-.75.75H12a.75.75 0 0 1-.75-.75v-.75a6 6 0 0 0-6-6H4.5a.75.75 0 0 1-.75-.75v-.75Zm0 7.5a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0Z" clip-rule="evenodd" />
					</svg>
				</a>
			}
			@if (Features.Value.EmailSubscriptions) {
				<a class="btn btn-sm btn-primary" title="E-Mail Newsletter" href="/Email/Subscribe">
					E-Mail
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
						<path d="M1.5 8.67v8.58a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V8.67l-8.928 5.493a3 3 0 0 1-3.144 0L1.5 8.67Z" />
						<path d="M22.5 6.908V6.75a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v.158l9.714 5.978a1.5 1.5 0 0 0 1.572 0L22.5 6.908Z" />
					</svg>
				</a>
			}
		</section>
	</div>
	@if (Featured is {} featured) {
		<div class="sm:col-span-2 row-span-2 aspect-square xl:order-first" style="padding: 0 4px 4px 0">
			<ArticleLink Article="featured">
				<article class="relative h-full bg-secondary text-secondary-content border-2 border-current shadow-[4px_4px_0_0_currentColor]">
					<div class="absolute inset-8 overflow-hidden fade-away">
						<div class="mb-3">
							<h2 class="text-2xl lg:text-4xl line-clamp-2 hyphens-auto">
								@featured.Title
							</h2>
							<p class="flex flex-wrap gap-2">
								@foreach (var category in featured.Categories.OrderBy(c => c.Color)) {
									<span class="badge badge-@CategoryUtilities.GetCssClassPostfixForColor(category.Color)">
										@category.Name
									</span>
								}
							</p>
						</div>
						<div class="hidden sm:block w-1/3 float-left mr-2">
							<ProfilePictureComponent ProfileId="@featured.Author.Id" LoadAsync="false" Size="400" />
						</div>
						<p class="font-bold">@featured.Author.FullName</p>
						<small class="text-sm">@featured.PublishDate.ToString("g")</small>
						<p class="hyphens-auto text-justify" lang="@CultureInfo.CurrentCulture">
							@((MarkupString) featured.BodyPlain[..Math.Min(1500, featured.BodyPlain.Length)]) ...
						</p>
					</div>
				</article>
			</ArticleLink>
		</div>
	} else {
		<div class="sm:col-span-4">
			<h2 class="text-2xl lg:text-4xl mb-6">@Localizer["NoArticles_Title"]</h2>
			<p>@Localizer["NoArticles_Message"]</p>
		</div>
	}

	<PageComponent LoadCallback="LoadArticles" Page="@Page">
		<div class="aspect-square">
			<ArticleTile Article="context" />
		</div>
	</PageComponent>
</div>

<div class="grid place-content-center my-3">
	<div class="join">
		@if (Page < 1) {
			<button class="join-item btn" disabled title="@Localizer["Paging_Previous"]">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
					<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clip-rule="evenodd" />
				</svg>
			</button>
		} else {
			<a class="join-item btn" target="_top" href="@(Page < 2 ? "/" : $"/?page={Page - 1}")" title="@Localizer["Paging_Previous"]">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
					<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clip-rule="evenodd"/>
				</svg>
			</a>
		}
		<button class="join-item btn md:btn-wide no-animation">@Localizer["Paging_Page"] @(Page + 1)</button>
		@if (Page >= TotalPages - 1) {
			<button class="join-item btn" disabled title="@Localizer["Paging_Next"]">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
					<path fill-rule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clip-rule="evenodd"/>
				</svg>
			</button>
		} else {
			<a class="join-item btn" target="_top" href="/?page=@(Page + 1)" title="@Localizer["Paging_Next"]">
				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
					<path fill-rule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clip-rule="evenodd"/>
				</svg>
			</a>
		}
	</div>
</div>

@code {
	[CascadingParameter(Name = "TitlePrefix")]
	private string TitlePrefix { get; set; } = default!;
	[SupplyParameterFromQuery]
	public int Page { get; set; } = 0;

	private int TotalPages { get; set; } = 1;

	private Article? Featured { get; set; }

	protected override async Task OnInitializedAsync() {
		try {
			await using var context = await ContextFactory.CreateDbContextAsync();

			var query = context.Set<Article>()
				.Include(a => a.Author).Include(a => a.Categories)
				.OrderByDescending(a => a.PublishDate).ThenBy(a => a.Id);

			Featured = await query.FirstOrDefaultAsync();
			TotalPages = (int) Math.Max(Math.Ceiling((await query.CountAsync() - 1) / 10.0), 1);
		} catch {
			Message.ShowError(Localizer["Articles_Load_Error"]);
		}
	}

	private async ValueTask<IEnumerable<Article>> LoadArticles(int page, int count) {
		try {
			await using var context = await ContextFactory.CreateDbContextAsync();
			return await context.Set<Article>()
				.Include(a => a.Author).Include(a => a.Categories)
				.OrderByDescending(a => a.PublishDate).ThenBy(a => a.Id)
				.Skip(page + 1).Take(count).ToListAsync();
		} catch {
			Message.ShowError(Localizer["Articles_Load_Error"]);
			return [];
		}
	}
}