using System.Text.Json;
using PlotLine.Data;
using PlotLine.Models;

namespace PlotLine.Services;

public interface IProjectExportService
{
    Task<ProjectBackupResult?> ExportAsync(int projectId);
}

public sealed class ProjectExportService(
    IProjectBackupRepository backups,
    IProjectActivityService activity,
    ICurrentUserService currentUser,
    ILogger<ProjectExportService> logger) : IProjectExportService
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = true
    };

    public async Task<ProjectBackupResult?> ExportAsync(int projectId)
    {
        if (!currentUser.UserId.HasValue)
        {
            return null;
        }

        var backup = await backups.GetProjectBackupAsync(projectId, currentUser.UserId.Value);
        if (backup?.Project is null)
        {
            logger.LogWarning("Project backup export requested for missing project {ProjectID}.", projectId);
            return null;
        }

        var json = JsonSerializer.Serialize(backup, JsonOptions);
        var fileName = BuildFileName(backup.Project.ProjectName, backup.ExportedAtUtc);

        logger.LogInformation("Project backup export generated for project {ProjectID} with {ByteCount} JSON bytes.", projectId, json.Length);
        await activity.RecordAsync(projectId, "Exported", "Project", projectId, backup.Project.ProjectName, "Project backup exported.");

        return new ProjectBackupResult
        {
            FileName = fileName,
            ContentType = "application/json",
            Json = json
        };
    }

    private static string BuildFileName(string projectName, DateTime exportedAtUtc)
    {
        var safeTitle = new string(projectName
            .Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c)
            .ToArray())
            .Trim();

        safeTitle = string.Join("_", safeTitle.Split(' ', StringSplitOptions.RemoveEmptyEntries));

        if (string.IsNullOrWhiteSpace(safeTitle))
        {
            safeTitle = "PlotDirector_Project";
        }

        return $"{safeTitle}_{exportedAtUtc:yyyy-MM-dd_HHmm}.plotdirector";
    }
}
