<?php

namespace App\Services;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Exception;

class QuotationAttachmentService
{
    private const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB per file
    private const MAX_TOTAL_SIZE = 20 * 1024 * 1024; // 20MB total
    private const ALLOWED_EXTENSIONS = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'jpg', 'jpeg', 'png', 'gif'];
    private const ALLOWED_MIME_TYPES = [
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/vnd.ms-powerpoint',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'image/jpeg',
        'image/png',
        'image/gif',
    ];

    /**
     * Validate and store attachment files
     *
     * @param array $files Array of UploadedFile instances
     * @param string $subdirectory Optional subdirectory under attachments
     * @return array Array of stored file paths
     * @throws Exception
     */
    public function storeAttachments(array $files, string $subdirectory = 'quotations'): array
    {
        try {
            $storedPaths = [];
            $totalSize = 0;

            // Validate file count
            if (count($files) > 5) {
                throw new Exception("Maximum 5 attachments allowed");
            }

            foreach ($files as $file) {
                // Validate file size
                $fileSize = $file->getSize();
                if ($fileSize > self::MAX_FILE_SIZE) {
                    throw new Exception("File {$file->getClientOriginalName()} exceeds maximum size of 5MB");
                }

                $totalSize += $fileSize;
                if ($totalSize > self::MAX_TOTAL_SIZE) {
                    throw new Exception("Total attachment size exceeds 20MB limit");
                }

                // Validate file type
                $this->validateFileType($file);

                // Store file
                $path = $this->storeFile($file, $subdirectory);
                $storedPaths[] = $path;
            }

            return $storedPaths;
        } catch (Exception $e) {
            throw new Exception("Attachment validation failed: {$e->getMessage()}");
        }
    }

    /**
     * Validate uploaded file
     *
     * @param UploadedFile $file
     * @throws Exception
     */
    private function validateFileType(UploadedFile $file): void
    {
        $extension = strtolower($file->getClientOriginalExtension());
        $mimeType = $file->getMimeType();

        if (!in_array($extension, self::ALLOWED_EXTENSIONS)) {
            throw new Exception("File type .{$extension} is not allowed");
        }

        if (!in_array($mimeType, self::ALLOWED_MIME_TYPES)) {
            throw new Exception("MIME type {$mimeType} is not allowed");
        }
    }

    /**
     * Store single file
     *
     * @param UploadedFile $file
     * @param string $subdirectory
     * @return string File path
     */
    private function storeFile(UploadedFile $file, string $subdirectory): string
    {
        $originalName = $file->getClientOriginalName();
        $timestamp = now()->timestamp;
        $filename = "{$timestamp}-{$originalName}";

        $path = "attachments/{$subdirectory}/{$filename}";
        Storage::disk('local')->putFileAs(
            "attachments/{$subdirectory}",
            $file,
            $filename
        );

        return $path;
    }

    /**
     * Delete attachment file
     *
     * @param string $filePath
     * @return bool
     */
    public function deleteAttachment(string $filePath): bool
    {
        try {
            if (Storage::disk('local')->exists($filePath)) {
                Storage::disk('local')->delete($filePath);
                return true;
            }
            return false;
        } catch (Exception $e) {
            \Log::warning("Failed to delete attachment {$filePath}: {$e->getMessage()}");
            return false;
        }
    }

    /**
     * Delete multiple attachments
     *
     * @param array $filePaths
     * @return int Number of successfully deleted files
     */
    public function deleteAttachments(array $filePaths): int
    {
        $deleted = 0;
        foreach ($filePaths as $path) {
            if ($this->deleteAttachment($path)) {
                $deleted++;
            }
        }
        return $deleted;
    }

    /**
     * Get allowed file extensions
     *
     * @return array
     */
    public static function getAllowedExtensions(): array
    {
        return self::ALLOWED_EXTENSIONS;
    }

    /**
     * Get max file size in bytes
     *
     * @return int
     */
    public static function getMaxFileSize(): int
    {
        return self::MAX_FILE_SIZE;
    }

    /**
     * Get max total size in bytes
     *
     * @return int
     */
    public static function getMaxTotalSize(): int
    {
        return self::MAX_TOTAL_SIZE;
    }
}
