<?php

namespace App\Http\Controllers\Api\V1;

use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\Item\ItemFileUploadRequest;
use App\Models\Commons\File;
use App\Models\Items\Item;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * 품목 파일 관리 컨트롤러
 *
 * group_id 기반 파일 관리, field_key 동적 지원
 * - document_type: group_id (품목 그룹)
 * - document_id: item_id (품목 ID)
 * - file_type: field_key (동적)
 */
class ItemsFileController extends Controller
{
    /**
     * 품목 그룹 ID (고정값, 추후 설정으로 변경 가능)
     */
    private const ITEM_GROUP_ID = '1';

    /**
     * 파일 목록 조회
     *
     * GET /api/v1/items/{id}/files
     */
    public function index(int $id, Request $request)
    {
        return ApiResponse::handle(function () use ($id, $request) {
            $tenantId = app('tenant_id');
            $fieldKey = $request->input('field_key');

            // 품목 존재 확인
            $this->getItemById($id, $tenantId);

            // 파일 조회
            $query = File::query()
                ->where('tenant_id', $tenantId)
                ->where('document_type', self::ITEM_GROUP_ID)
                ->where('document_id', $id);

            // 특정 field_key만 조회
            if ($fieldKey) {
                $query->where('field_key', $fieldKey);
            }

            $files = $query->orderBy('created_at', 'desc')->get();

            // field_key별 그룹핑
            $grouped = $files->groupBy('field_key')->map(function ($group) {
                return $group->map(fn ($file) => $this->formatFileResponse($file))->values();
            });

            return $grouped;
        }, __('message.fetched'));
    }

    /**
     * 파일 업로드
     *
     * POST /api/v1/items/{id}/files
     */
    public function upload(int $id, ItemFileUploadRequest $request)
    {
        return ApiResponse::handle(function () use ($id, $request) {
            $tenantId = app('tenant_id');
            $userId = auth()->id() ?? app('api_user');
            $validated = $request->validated();
            $fieldKey = $validated['field_key'];
            $uploadedFile = $validated['file'];
            $existingFileId = $validated['file_id'] ?? null;

            // 품목 존재 확인
            $this->getItemById($id, $tenantId);

            $replaced = false;

            // 기존 파일 교체 (file_id가 있는 경우) - 완전 삭제
            if ($existingFileId) {
                $existingFile = File::query()
                    ->where('tenant_id', $tenantId)
                    ->where('document_type', self::ITEM_GROUP_ID)
                    ->where('document_id', $id)
                    ->where('id', $existingFileId)
                    ->first();

                if ($existingFile) {
                    $existingFile->permanentDelete(); // 파일 교체 시 완전 삭제
                    $replaced = true;
                }
            }

            // 파일명 생성 (64bit 난수)
            $extension = $uploadedFile->getClientOriginalExtension();
            $storedName = bin2hex(random_bytes(8)).'.'.$extension;
            $displayName = $uploadedFile->getClientOriginalName();

            // 경로 생성: tenants/{tenant_id}/items/{year}/{month}/{stored_name}
            $year = date('Y');
            $month = date('m');
            $directory = sprintf('%d/items/%s/%s', $tenantId, $year, $month);
            $filePath = $directory.'/'.$storedName;

            // 파일 저장 (tenant 디스크)
            Storage::disk('tenant')->putFileAs($directory, $uploadedFile, $storedName);

            // file_type 자동 분류 (MIME 타입 기반)
            $mimeType = $uploadedFile->getMimeType();
            $fileType = $this->detectFileType($mimeType);

            // files 테이블에 저장
            $file = File::create([
                'tenant_id' => $tenantId,
                'display_name' => $displayName,
                'stored_name' => $storedName,
                'file_path' => $filePath,
                'file_size' => $uploadedFile->getSize(),
                'mime_type' => $mimeType,
                'file_type' => $fileType,       // 파일 형식 (image, document, excel, archive)
                'field_key' => $fieldKey,       // 비즈니스 용도 (drawing, certificate 등)
                'document_id' => $id,
                'document_type' => self::ITEM_GROUP_ID,  // group_id
                'is_temp' => false,
                'uploaded_by' => $userId,
                'created_by' => $userId,
            ]);

            return [
                'file_id' => $file->id,
                'field_key' => $fieldKey,
                'file_url' => $this->getFileUrl($file->id),
                'file_path' => $filePath,
                'file_name' => $displayName,
                'file_size' => $file->file_size,
                'mime_type' => $file->mime_type,
                'replaced' => $replaced,
            ];
        }, __('message.file.uploaded'));
    }

    /**
     * 파일 삭제
     *
     * DELETE /api/v1/items/{id}/files/{fileId}
     */
    public function delete(int $id, mixed $fileId, Request $request)
    {
        $fileId = (int) $fileId;

        return ApiResponse::handle(function () use ($id, $fileId) {
            $tenantId = app('tenant_id');

            // 품목 존재 확인
            $this->getItemById($id, $tenantId);

            // 파일 조회
            $file = File::query()
                ->where('tenant_id', $tenantId)
                ->where('document_type', self::ITEM_GROUP_ID)
                ->where('document_id', $id)
                ->where('id', $fileId)
                ->first();

            if (! $file) {
                throw new NotFoundHttpException(__('error.file.not_found'));
            }

            // Soft delete
            $this->deleteFile($file);

            return [
                'file_id' => $fileId,
                'deleted' => true,
            ];
        }, __('message.file.deleted'));
    }

    /**
     * ID로 품목 조회 (통합 items 테이블)
     */
    private function getItemById(int $id, int $tenantId): Item
    {
        $item = Item::query()
            ->where('tenant_id', $tenantId)
            ->find($id);

        if (! $item) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        return $item;
    }

    /**
     * 파일 삭제 (일원화된 삭제 로직)
     */
    private function deleteFile(File $file): void
    {
        $userId = (int) (auth()->id() ?? app('api_user'));
        $file->softDeleteFile($userId);
    }

    /**
     * 파일 응답 포맷
     */
    private function formatFileResponse(File $file): array
    {
        return [
            'id' => $file->id,
            'file_name' => $file->display_name,
            'file_path' => $file->file_path,
            'file_url' => $this->getFileUrl($file->id),
            'file_size' => $file->file_size,
            'mime_type' => $file->mime_type,
            'file_type' => $file->file_type,
            'field_key' => $file->field_key,
            'created_at' => $file->created_at?->format('Y-m-d H:i:s'),
        ];
    }

    /**
     * 파일 URL 생성
     */
    private function getFileUrl(int $fileId): string
    {
        return url("/api/v1/files/{$fileId}/download");
    }

    /**
     * MIME 타입 기반 파일 형식 분류
     */
    private function detectFileType(string $mimeType): string
    {
        if (str_starts_with($mimeType, 'image/')) {
            return 'image';
        }

        if (in_array($mimeType, [
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'text/csv',
        ])) {
            return 'excel';
        }

        if (in_array($mimeType, [
            'application/zip',
            'application/x-rar-compressed',
            'application/x-7z-compressed',
            'application/gzip',
        ])) {
            return 'archive';
        }

        // 기본값: document (pdf, doc, hwp 등)
        return 'document';
    }
}
