using Meezi.Core.Entities;
using Meezi.Core.Interfaces;
using Meezi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace Meezi.Infrastructure.Services;

public class WebsiteService(AppDbContext db) : IWebsiteService
{
    public async Task<(IReadOnlyList<object> Posts, int Total)> GetPostsAsync(
        string locale, int page, int limit, CancellationToken ct = default)
    {
        var query = db.WebsiteBlogPosts.Where(p => p.IsPublished)
            .OrderByDescending(p => p.PublishedAt);

        var total = await query.CountAsync(ct);
        var posts = await query.Skip((page - 1) * limit).Take(limit).ToListAsync(ct);

        var dtos = posts.Select(p => (object)MapPostSummary(p, locale)).ToList();
        return (dtos, total);
    }

    public async Task<object?> GetPostAsync(string slug, string locale, CancellationToken ct = default)
    {
        var post = await db.WebsiteBlogPosts
            .Include(p => p.Comments.Where(c => c.IsApproved))
            .FirstOrDefaultAsync(p => p.Slug == slug && p.IsPublished, ct);
        if (post is null) return null;

        // Increment view count (fire and forget)
        post.ViewCount++;
        await db.SaveChangesAsync(ct);

        return MapPostDetail(post, locale);
    }

    public async Task<IReadOnlyList<object>> GetCommentsAsync(string slug, CancellationToken ct = default)
    {
        var comments = await db.WebsiteComments
            .Where(c => c.PostSlug == slug && c.IsApproved)
            .OrderBy(c => c.CreatedAt)
            .ToListAsync(ct);
        return comments.Select(c => (object)MapComment(c)).ToList();
    }

    public async Task<object> AddCommentAsync(string slug, string authorName, string? email,
        string content, string? ip, CancellationToken ct = default)
    {
        var postExists = await db.WebsiteBlogPosts
            .AnyAsync(p => p.Slug == slug && p.IsPublished, ct);
        if (!postExists) throw new InvalidOperationException("Post not found.");

        var comment = new WebsiteComment
        {
            PostSlug   = slug,
            AuthorName = authorName.Trim(),
            AuthorEmail = email?.Trim(),
            Content    = content.Trim(),
            IpAddress  = ip,
            IsApproved = false, // Requires moderation
        };
        db.WebsiteComments.Add(comment);
        await db.SaveChangesAsync(ct);
        return MapComment(comment);
    }

    public async Task<object> CreateDemoRequestAsync(string contactName, string businessName,
        string phone, string? email, string branchCount, string? notes, string source,
        CancellationToken ct = default)
    {
        var req = new DemoRequest
        {
            ContactName  = contactName.Trim(),
            BusinessName = businessName.Trim(),
            Phone        = phone.Trim(),
            Email        = email?.Trim(),
            BranchCount  = branchCount,
            Notes        = notes?.Trim(),
            Source       = source,
        };
        db.DemoRequests.Add(req);
        await db.SaveChangesAsync(ct);
        return new { req.Id, req.CreatedAt };
    }

    // ── Mappers ──────────────────────────────────────────────────────────────

    private static object MapPostSummary(WebsiteBlogPost p, string locale) => new
    {
        p.Id,
        p.Slug,
        Title     = locale == "en" && !string.IsNullOrWhiteSpace(p.TitleEn) ? p.TitleEn : p.TitleFa,
        Excerpt   = locale == "en" && !string.IsNullOrWhiteSpace(p.ExcerptEn) ? p.ExcerptEn : p.ExcerptFa,
        Category  = locale == "en" && !string.IsNullOrWhiteSpace(p.CategoryEn) ? p.CategoryEn : p.CategoryFa,
        p.Author,
        p.CoverImage,
        p.PublishedAt,
        p.ViewCount,
        p.TagsJson,
    };

    private static object MapPostDetail(WebsiteBlogPost p, string locale) => new
    {
        p.Id,
        p.Slug,
        Title     = locale == "en" && !string.IsNullOrWhiteSpace(p.TitleEn) ? p.TitleEn : p.TitleFa,
        Excerpt   = locale == "en" && !string.IsNullOrWhiteSpace(p.ExcerptEn) ? p.ExcerptEn : p.ExcerptFa,
        Content   = locale == "en" && !string.IsNullOrWhiteSpace(p.ContentEn) ? p.ContentEn : p.ContentFa,
        Category  = locale == "en" && !string.IsNullOrWhiteSpace(p.CategoryEn) ? p.CategoryEn : p.CategoryFa,
        p.Author,
        p.CoverImage,
        p.PublishedAt,
        p.ViewCount,
        p.TagsJson,
        Comments  = p.Comments.Select(c => MapComment(c)).ToList(),
    };

    private static object MapComment(WebsiteComment c) => new
    {
        c.Id,
        c.AuthorName,
        c.Content,
        c.CreatedAt,
        c.IsApproved,
    };
}
