@page "/check"
@attribute [Authorize]
@rendermode InteractiveServer

@inject ICVCheckService CVCheckService
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject ILogger<Check> Logger

<PageTitle>Upload CVs - RealCV</PageTitle>

<div class="container py-5">
    <div class="row justify-content-center">
        <div class="col-lg-8">
            <div class="text-center mb-4">
                <h1 class="fw-bold">Upload CVs for Verification</h1>
                <p class="text-muted lead">Upload one or more CVs in PDF or DOCX format to begin the verification process</p>
                <div class="alert alert-info d-inline-flex align-items-center py-2 px-3 mb-0" style="font-size: 0.875rem;">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="me-2 flex-shrink-0" viewBox="0 0 16 16">
                        <path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
                    </svg>
                    <span>For UK employment history</span>
                </div>
            </div>

            @if (!string.IsNullOrEmpty(_errorMessage))
            {
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    @_errorMessage
                    <button type="button" class="btn-close" @onclick="() => _errorMessage = null" aria-label="Close"></button>
                </div>
            }

            <div class="card border-0 shadow">
                <div class="card-body p-4">
                    @if (_isUploading)
                    {
                        <div class="text-center py-5">
                            <div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
                                <span class="visually-hidden">Uploading...</span>
                            </div>
                            <h5 class="mb-2">Uploading CVs...</h5>
                            <p class="text-muted">Processing @_currentFileIndex of @_totalFiles files</p>
                            <div class="progress" style="height: 8px;">
                                <div class="progress-bar progress-bar-striped progress-bar-animated"
                                     role="progressbar"
                                     style="width: @(_uploadProgress)%"
                                     aria-valuenow="@_uploadProgress"
                                     aria-valuemin="0"
                                     aria-valuemax="100">
                                </div>
                            </div>
                            @if (!string.IsNullOrEmpty(_currentFileName))
                            {
                                <small class="text-muted mt-2 d-block">@_currentFileName</small>
                            }
                        </div>
                    }
                    else
                    {
                        <div class="upload-area @(_isDragging ? "dragging" : "")"
                             @ondragenter="HandleDragEnter"
                             @ondragleave="HandleDragLeave"
                             @ondragover:preventDefault
                             @ondrop="HandleDrop"
                             @ondrop:preventDefault>

                            <InputFile OnChange="HandleFileSelected"
                                       accept=".pdf,.docx,.json"
                                       multiple
                                       class="d-none"
                                       id="fileInput" />

                            <label for="fileInput" class="d-block text-center py-4 cursor-pointer">
                                <div class="upload-icon mb-2">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-cloud-arrow-up" viewBox="0 0 16 16">
                                        <path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708l2-2z"/>
                                        <path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383zm.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>
                                    </svg>
                                </div>
                                <h4 class="fw-bold mb-1">Drop your CVs here</h4>
                                <p class="text-muted mb-3 small">Drag and drop files, or click to browse</p>
                                <div class="d-flex justify-content-center gap-2 flex-wrap">
                                    <span class="badge bg-light text-dark border px-2 py-1">PDF</span>
                                    <span class="badge bg-light text-dark border px-2 py-1">DOCX</span>
                                    <span class="badge bg-light text-dark border px-2 py-1">Max 10MB</span>
                                </div>
                            </label>
                        </div>

                        @if (_isBuffering)
                        {
                            <div class="mt-4 text-center">
                                <div class="spinner-border text-primary" role="status">
                                    <span class="visually-hidden">Loading files...</span>
                                </div>
                                <p class="mt-2 text-muted">Reading files...</p>
                            </div>
                        }

                        @if (_selectedFiles.Count > 0 && !_isBuffering)
                        {
                            <div class="mt-4">
                                <div class="d-flex justify-content-between align-items-center mb-2">
                                    <h6 class="mb-0">Selected Files (@_selectedFiles.Count)</h6>
                                    <button class="btn btn-outline-secondary btn-sm" @onclick="ClearAllFiles">
                                        Clear All
                                    </button>
                                </div>
                                <div class="file-list">
                                    @foreach (var file in _selectedFiles)
                                    {
                                        <div class="file-list-item">
                                            <div class="d-flex align-items-center">
                                                <div class="file-type-icon me-3 @GetFileTypeClass(file.Name)">
                                                    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
                                                        <path d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z"/>
                                                    </svg>
                                                </div>
                                                <div class="flex-grow-1">
                                                    <p class="mb-0 fw-medium">@file.Name</p>
                                                    <small class="text-muted">@FormatFileSize(file.Size)</small>
                                                </div>
                                            </div>
                                            <button class="btn btn-sm btn-outline-danger" @onclick="() => RemoveFile(file)">
                                                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
                                                    <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z"/>
                                                </svg>
                                            </button>
                                        </div>
                                    }
                                </div>
                            </div>

                            <div class="mt-4 text-center">
                                <button class="btn btn-primary btn-lg px-5" @onclick="UploadFiles">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-upload me-2" viewBox="0 0 16 16">
                                        <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
                                        <path d="M7.646 1.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 2.707V11.5a.5.5 0 0 1-1 0V2.707L5.354 4.854a.5.5 0 1 1-.708-.708l3-3z"/>
                                    </svg>
                                    Start Verification (@_selectedFiles.Count @(_selectedFiles.Count == 1 ? "CV" : "CVs"))
                                </button>
                            </div>
                        }
                    }
                </div>
            </div>

            <!-- Security & Process Info -->
            <div class="security-info mt-4">
                <div class="d-flex justify-content-center flex-wrap gap-4">
                    <div class="security-badge">
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
                            <path d="M5.338 1.59a61.44 61.44 0 0 0-2.837.856.481.481 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.725 10.725 0 0 0 2.287 2.233c.346.244.652.42.893.533.12.057.218.095.293.118a.55.55 0 0 0 .101.025.615.615 0 0 0 .1-.025c.076-.023.174-.061.294-.118.24-.113.547-.29.893-.533a10.726 10.726 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.775 11.775 0 0 1-2.517 2.453 7.159 7.159 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7.158 7.158 0 0 1-1.048-.625 11.777 11.777 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 62.456 62.456 0 0 1 5.072.56z"/>
                            <path d="M10.854 5.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 7.793l2.646-2.647a.5.5 0 0 1 .708 0z"/>
                        </svg>
                        <span>256-bit Encryption</span>
                    </div>
                    <div class="security-badge">
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
                            <path d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z"/>
                        </svg>
                        <span>Secure Storage</span>
                    </div>
                    <div class="security-badge">
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 16 16">
                            <path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/>
                            <path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319z"/>
                        </svg>
                        <span>AI-Powered Analysis</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<style>
    .upload-area {
        border: 2px dashed var(--realcv-gray-300);
        border-radius: 16px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        background: linear-gradient(180deg, var(--realcv-bg-surface) 0%, var(--realcv-bg-muted) 100%);
    }

    .upload-area:hover {
        border-color: var(--realcv-primary);
        background: linear-gradient(180deg, #e8f1fa 0%, #d4e4f4 100%);
        transform: translateY(-2px);
        box-shadow: 0 10px 25px -5px rgba(59, 111, 212, 0.1);
    }

    .upload-area.dragging {
        border-color: var(--realcv-primary);
        background: linear-gradient(180deg, #d4e4f4 0%, #c5d9ef 100%);
        border-style: solid;
        transform: scale(1.02);
    }

    .upload-icon {
        width: 80px;
        height: 80px;
        background: linear-gradient(135deg, var(--realcv-primary) 0%, var(--realcv-primary-dark) 100%);
        border-radius: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0 auto 1.5rem;
        color: white;
        transition: transform 0.3s ease;
    }

    .upload-area:hover .upload-icon {
        transform: scale(1.1) rotate(-5deg);
    }

    .cursor-pointer {
        cursor: pointer;
        user-select: none;
    }

    .file-list-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        border: 1px solid var(--realcv-gray-200);
        border-radius: 12px;
        padding: 1rem;
        margin-bottom: 0.75rem;
        background: var(--realcv-bg-surface);
        transition: all 0.2s ease;
    }

    .file-list-item:hover {
        border-color: var(--realcv-primary);
        box-shadow: 0 4px 12px rgba(59, 111, 212, 0.08);
    }

    .file-type-icon {
        width: 40px;
        height: 40px;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .file-type-icon.pdf {
        background: linear-gradient(135deg, #fde8e8 0%, #fcd9d9 100%);
        color: #dc2626;
    }

    .file-type-icon.docx {
        background: linear-gradient(135deg, #e3ecf7 0%, #d4e4f4 100%);
        color: var(--realcv-primary);
    }

    .file-type-icon.json {
        background: linear-gradient(135deg, #fef9c3 0%, #fef08a 100%);
        color: #ca8a04;
    }

    .security-info {
        padding: 1rem 0;
    }

    .security-badge {
        display: inline-flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.625rem 1rem;
        background: var(--realcv-bg-muted);
        border-radius: var(--realcv-radius);
        font-size: 0.875rem;
        color: var(--realcv-gray-600);
    }

    .security-badge svg {
        color: var(--realcv-verified);
    }

    @@media (max-width: 576px) {
        .upload-icon {
            width: 64px;
            height: 64px;
        }

        .upload-icon svg {
            width: 32px;
            height: 32px;
        }

        .card-body.p-5 {
            padding: 1.5rem !important;
        }

        .d-flex.justify-content-center.gap-3 {
            flex-direction: column;
            gap: 0.5rem !important;
        }

        .security-info .d-flex {
            flex-direction: column;
            gap: 0.75rem !important;
        }
    }
</style>

@code {
    private List<BufferedFile> _selectedFiles = new();
    private bool _isUploading;
    private bool _isBuffering;
    private bool _isDragging;
    private int _uploadProgress;
    private string? _errorMessage;
    private int _currentFileIndex;
    private int _totalFiles;
    private string? _currentFileName;

    private const long MaxFileSize = 10 * 1024 * 1024; // 10MB
    private const int MaxFileCount = 50; // Maximum files per batch

    // Magic bytes for file type validation
    private static readonly byte[] PdfMagicBytes = [0x25, 0x50, 0x44, 0x46]; // %PDF
    private static readonly byte[] DocxMagicBytes = [0x50, 0x4B, 0x03, 0x04]; // PK.. (ZIP signature)

    // Buffered file to prevent stale IBrowserFile references
    private sealed record BufferedFile(string Name, long Size, byte[] Data);

    private void HandleDragEnter()
    {
        _isDragging = true;
    }

    private void HandleDragLeave()
    {
        _isDragging = false;
    }

    private void HandleDrop()
    {
        _isDragging = false;
    }

    private async Task HandleFileSelected(InputFileChangeEventArgs e)
    {
        _errorMessage = null;
        _isBuffering = true;
        StateHasChanged();

        var invalidFiles = new List<string>();
        var oversizedFiles = new List<string>();
        var failedFiles = new List<string>();

        try
        {
            foreach (var file in e.GetMultipleFiles(MaxFileCount))
            {
                if (!IsValidFileType(file.Name))
                {
                    invalidFiles.Add(file.Name);
                    continue;
                }

                if (file.Size > MaxFileSize)
                {
                    oversizedFiles.Add(file.Name);
                    continue;
                }

                // Avoid duplicates
                if (_selectedFiles.Any(f => f.Name == file.Name && f.Size == file.Size))
                {
                    continue;
                }

                // Read file data immediately to prevent stale reference issues
                try
                {
                    await using var stream = file.OpenReadStream(MaxFileSize);
                    using var memoryStream = new MemoryStream();
                    await stream.CopyToAsync(memoryStream);
                    _selectedFiles.Add(new BufferedFile(file.Name, file.Size, memoryStream.ToArray()));
                }
                catch (Exception ex)
                {
                    Logger.LogWarning(ex, "Failed to buffer file: {FileName}", file.Name);
                    failedFiles.Add(file.Name);
                }
            }
        }
        finally
        {
            _isBuffering = false;
        }

        // Build error message if any files were rejected
        var errors = new List<string>();
        if (invalidFiles.Count > 0)
            errors.Add($"Invalid file type(s): {string.Join(", ", invalidFiles.Take(3))}{(invalidFiles.Count > 3 ? $" and {invalidFiles.Count - 3} more" : "")}");
        if (oversizedFiles.Count > 0)
            errors.Add($"File(s) exceed 10MB limit: {string.Join(", ", oversizedFiles.Take(3))}{(oversizedFiles.Count > 3 ? $" and {oversizedFiles.Count - 3} more" : "")}");
        if (failedFiles.Count > 0)
            errors.Add($"Failed to read file(s): {string.Join(", ", failedFiles.Take(3))}{(failedFiles.Count > 3 ? $" and {failedFiles.Count - 3} more" : "")}");

        if (errors.Count > 0)
            _errorMessage = string.Join(". ", errors);
    }

    private void RemoveFile(BufferedFile file)
    {
        _selectedFiles.Remove(file);
    }

    private void ClearAllFiles()
    {
        _selectedFiles.Clear();
        _errorMessage = null;
    }

    private async Task UploadFiles()
    {
        if (_selectedFiles.Count == 0) return;

        try
        {
            _isUploading = true;
            _uploadProgress = 0;
            _errorMessage = null;
            _totalFiles = _selectedFiles.Count;
            _currentFileIndex = 0;

            var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            var userIdClaim = authState.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                _errorMessage = "Unable to identify user. Please log in again.";
                _isUploading = false;
                return;
            }

            var failedFiles = new List<string>();

            foreach (var file in _selectedFiles.ToList())
            {
                _currentFileIndex++;
                _currentFileName = file.Name;
                _uploadProgress = (int)((_currentFileIndex - 1) / (double)_totalFiles * 100);
                await InvokeAsync(StateHasChanged);

                try
                {
                    using var memoryStream = new MemoryStream(file.Data);

                    // Validate file content (magic bytes)
                    if (!await ValidateFileContentAsync(memoryStream, file.Name))
                    {
                        failedFiles.Add($"{file.Name} (invalid content)");
                        continue;
                    }

                    await CVCheckService.CreateCheckAsync(userId, memoryStream, file.Name);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Error uploading CV: {FileName}", file.Name);
                    failedFiles.Add($"{file.Name} (upload error)");
                }
            }

            _uploadProgress = 100;
            _currentFileName = null;
            await InvokeAsync(StateHasChanged);
            await Task.Delay(500); // Brief pause to show completion

            if (failedFiles.Count > 0 && failedFiles.Count < _totalFiles)
            {
                // Partial success - some files failed
                Logger.LogWarning("Some files failed to upload: {FailedFiles}", string.Join(", ", failedFiles));
            }

            // Navigate to dashboard to see all uploaded CVs
            NavigationManager.NavigateTo("/dashboard");
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "Error uploading CVs");
            _errorMessage = "An error occurred while uploading. Please try again.";
        }
        finally
        {
            _isUploading = false;
            _currentFileName = null;
        }
    }

    private async Task<bool> ValidateFileContentAsync(MemoryStream stream, string fileName)
    {
        var extension = Path.GetExtension(fileName).ToLowerInvariant();
        var header = new byte[4];

        stream.Position = 0;
        var bytesRead = await stream.ReadAsync(header.AsMemory(0, 4));
        stream.Position = 0;

        if (bytesRead < 4)
            return false;

        return extension switch
        {
            ".pdf" => header.AsSpan().StartsWith(PdfMagicBytes),
            ".docx" => header.AsSpan().StartsWith(DocxMagicBytes),
            ".json" => header[0] == '{' || header[0] == '[',
            _ => false
        };
    }

    private bool IsValidFileType(string fileName)
    {
        var extension = Path.GetExtension(fileName).ToLowerInvariant();
        return extension is ".pdf" or ".docx" or ".json";
    }

    private static string FormatFileSize(long bytes)
    {
        string[] sizes = ["B", "KB", "MB", "GB"];
        int order = 0;
        double size = bytes;

        while (size >= 1024 && order < sizes.Length - 1)
        {
            order++;
            size /= 1024;
        }

        return $"{size:0.##} {sizes[order]}";
    }

    private static string GetFileTypeClass(string fileName)
    {
        var ext = Path.GetExtension(fileName).ToLowerInvariant();
        return ext switch
        {
            ".pdf" => "pdf",
            ".docx" => "docx",
            ".json" => "json",
            _ => "docx"
        };
    }
}
