<?php

namespace App\Http\Controllers\Api\Desktop;

use App\Http\Controllers\Controller;
use App\Models\ShopTransactionAttachment;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class AttachmentSyncController extends Controller
{
    /**
     * Receive & store an attachment (receipt image / PDF) pushed by the desktop POS.
     *
     * This endpoint is public (no Sanctum token). It authenticates the request by
     * matching license_key + shop_id to an active user's shop, exactly like the
     * check-license / app-launch flow.
     *
     * Contract (do not change): must return HTTP 200 JSON exactly {"success": true}.
     */
    public function upload(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'file' => 'required|file',
                'license_key' => 'required|string',
                'shop_id' => 'required',
                'code' => 'required|string',
                'transaction_code' => 'required|string',
                'mime_type' => 'nullable|string',
                'size' => 'nullable|integer',
            ]);

            // Authenticate via license_key + shop_id (reuse the check-license resolution).
            if (!$this->authorizeShop($request->input('license_key'), $request->input('shop_id'))) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid license key or shop',
                ], 403);
            }

            $shopId = (string) $request->input('shop_id');
            $code = (string) $request->input('code');

            // Idempotent: if this attachment code already exists, treat as success.
            if (ShopTransactionAttachment::where('code', $code)->exists()) {
                return response()->json(['success' => true]);
            }

            $file = $request->file('file');
            $fileName = $file->getClientOriginalName();

            // Store on the public disk under attachments/ (served via storage:link).
            $path = $file->store('attachments', 'public');

            try {
                ShopTransactionAttachment::create([
                    'shop_id' => $shopId,
                    'code' => $code,
                    'transaction_code' => (string) $request->input('transaction_code'),
                    'file_path' => $path,
                    'file_name' => $fileName,
                    'mime_type' => $request->input('mime_type') ?: $file->getClientMimeType(),
                    'size' => (int) ($request->input('size') ?: $file->getSize()),
                ]);
            } catch (\Illuminate\Database\QueryException $e) {
                // Race condition on the unique code: another request stored it first.
                if (ShopTransactionAttachment::where('code', $code)->exists()) {
                    return response()->json(['success' => true]);
                }
                throw $e;
            }

            return response()->json(['success' => true]);

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        } catch (\Exception $e) {
            Log::error('Attachment upload failed', [
                'error' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString(),
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * List attachments for a shop so the desktop can pull raw files.
     * This endpoint is public and authenticates the same way as upload().
     */
    public function download(Request $request): JsonResponse
    {
        $request->validate([
            'license_key' => 'required|string',
            'shop_id' => 'required',
        ]);

        if (!$this->authorizeShop($request->input('license_key'), $request->input('shop_id'))) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid license key or shop',
            ], 403);
        }

        $shopId = (string) $request->input('shop_id');

        $attachments = ShopTransactionAttachment::where('shop_id', $shopId)
            ->get()
            ->map(function (ShopTransactionAttachment $attachment) {
                return [
                    'code' => $attachment->code,
                    'transaction_code' => $attachment->transaction_code,
                    'download_url' => $attachment->url,
                    'file_name' => $attachment->file_name,
                    'mime_type' => $attachment->mime_type,
                    'size' => $attachment->size,
                ];
            });

        return response()->json([
            'attachments' => $attachments,
        ]);
    }

    /**
     * Validate the request by matching license_key + shop_id to an active user's shop.
     * Mirrors the resolution used by check-license / app-launch (User::license_key).
     */
    private function authorizeShop(?string $licenseKey, $shopId): bool
    {
        if (empty($licenseKey) || $shopId === null || $shopId === '') {
            return false;
        }

        return User::where('license_key', $licenseKey)
            ->where('is_active', true)
            ->where('shop_id', $shopId)
            ->exists();
    }
}
