<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ImportMapping;
use App\Models\ImportLog;
use App\Services\Import\ImportService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class ImportController extends Controller
{
    protected ImportService $importService;

    public function __construct(ImportService $importService)
    {
        $this->importService = $importService;
    }

    /**
     * Upload file and get preview
     */
    public function upload(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'file' => 'required|file|max:10240', // 10MB max
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        $file = $request->file('file');
        $extension = strtolower($file->getClientOriginalExtension());

        // Verificar extensão permitida
        if (!in_array($extension, ImportMapping::FILE_TYPES)) {
            return response()->json([
                'success' => false,
                'message' => "Unsupported file type: $extension. Allowed: " . implode(', ', ImportMapping::FILE_TYPES),
            ], 422);
        }

        // Salvar arquivo temporariamente
        $filename = Str::uuid() . '.' . $extension;
        $path = $file->storeAs('imports/temp', $filename);
        $fullPath = Storage::path($path);

        try {
            // Obter preview
            $preview = $this->importService->getPreview($fullPath, 15);

            return response()->json([
                'success' => true,
                'data' => [
                    'temp_file' => $filename,
                    'original_name' => $file->getClientOriginalName(),
                    'file_type' => $extension,
                    'size' => $file->getSize(),
                    'preview' => $preview,
                ],
            ]);

        } catch (\Exception $e) {
            // Limpar arquivo em caso de erro
            Storage::delete($path);

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

    /**
     * Get headers from file with specific row
     */
    public function getHeaders(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'temp_file' => 'required|string',
            'header_row' => 'required|integer|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
            ], 422);
        }

        $fullPath = Storage::path('imports/temp/' . $request->temp_file);

        if (!file_exists($fullPath)) {
            return response()->json([
                'success' => false,
                'message' => 'Temporary file not found. Please upload again.',
            ], 404);
        }

        try {
            $headers = $this->importService->getHeaders($fullPath, [
                'header_row' => $request->header_row,
            ]);

            // Sugerir mapeamentos
            $suggestions = $this->importService->suggestMapping($headers);

            return response()->json([
                'success' => true,
                'data' => [
                    'headers' => $headers,
                    'suggestions' => $suggestions,
                ],
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error reading headers: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Process import with mapping
     */
    public function import(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'temp_file' => 'required|string',
            'mapping_id' => 'nullable|exists:import_mappings,id',
            'column_mappings' => 'required_without:mapping_id|array',
            'header_row' => 'required_without:mapping_id|integer|min:0',
            'data_start_row' => 'required_without:mapping_id|integer|min:0',
            'date_format' => 'nullable|string',
            'decimal_separator' => 'nullable|string|max:1',
            'thousands_separator' => 'nullable|string|max:1',
            'account_id' => 'nullable|exists:accounts,id',
            'category_id' => 'nullable|exists:categories,id',
            'cost_center_id' => 'nullable|exists:cost_centers,id',
            'save_mapping' => 'nullable|boolean',
            'mapping_name' => 'required_if:save_mapping,true|nullable|string|max:255',
            'bank_name' => 'nullable|string|max:100',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
            ], 422);
        }

        $fullPath = Storage::path('imports/temp/' . $request->temp_file);

        if (!file_exists($fullPath)) {
            return response()->json([
                'success' => false,
                'message' => 'Temporary file not found. Please upload again.',
            ], 404);
        }

        $userId = auth()->id();

        try {
            // Usar mapeamento existente ou criar novo
            if ($request->mapping_id) {
                $mapping = ImportMapping::where('user_id', $userId)
                    ->findOrFail($request->mapping_id);
            } else {
                $extension = pathinfo($request->temp_file, PATHINFO_EXTENSION);
                
                $mappingData = [
                    'user_id' => $userId,
                    'name' => $request->mapping_name ?? 'Importação ' . now()->format('d/m/Y H:i'),
                    'bank_name' => $request->bank_name,
                    'file_type' => $extension,
                    'header_row' => $request->header_row,
                    'data_start_row' => $request->data_start_row,
                    'date_format' => $request->date_format ?? 'd/m/Y',
                    'decimal_separator' => $request->decimal_separator ?? ',',
                    'thousands_separator' => $request->thousands_separator ?? '.',
                    'column_mappings' => $request->column_mappings,
                    'default_account_id' => $request->account_id,
                    'default_category_id' => $request->category_id,
                    'default_cost_center_id' => $request->cost_center_id,
                    'is_active' => $request->save_mapping ?? false,
                ];

                if ($request->save_mapping) {
                    $mapping = ImportMapping::create($mappingData);
                } else {
                    $mapping = new ImportMapping($mappingData);
                    // Não definir ID para mapeamento temporário - será tratado no ImportService
                }
            }

            // Executar importação
            $importLog = $this->importService->importTransactions(
                $fullPath,
                $mapping,
                $userId,
                $request->account_id,
                $request->category_id,
                $request->cost_center_id
            );

            // Limpar arquivo temporário
            Storage::delete('imports/temp/' . $request->temp_file);

            return response()->json([
                'success' => true,
                'message' => "Importação concluída: {$importLog->imported_rows} transações importadas",
                'data' => [
                    'import_log' => $importLog,
                    'mapping_saved' => $request->save_mapping && isset($mapping->id) && $mapping->id > 0,
                ],
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Import failed: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * List saved mappings
     */
    public function mappings(Request $request): JsonResponse
    {
        $mappings = ImportMapping::where('user_id', auth()->id())
            ->where('is_active', true)
            ->with(['defaultAccount', 'defaultCategory', 'defaultCostCenter'])
            ->orderBy('name')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $mappings,
        ]);
    }

    /**
     * Get single mapping
     */
    public function getMapping(int $id): JsonResponse
    {
        $mapping = ImportMapping::where('user_id', auth()->id())
            ->with(['defaultAccount', 'defaultCategory', 'defaultCostCenter'])
            ->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $mapping,
        ]);
    }

    /**
     * Update mapping
     */
    public function updateMapping(Request $request, int $id): JsonResponse
    {
        $mapping = ImportMapping::where('user_id', auth()->id())
            ->findOrFail($id);

        $validator = Validator::make($request->all(), [
            'name' => 'sometimes|string|max:255',
            'bank_name' => 'nullable|string|max:100',
            'header_row' => 'sometimes|integer|min:0',
            'data_start_row' => 'sometimes|integer|min:0',
            'date_format' => 'sometimes|string',
            'decimal_separator' => 'sometimes|string|max:1',
            'thousands_separator' => 'sometimes|string|max:1',
            'column_mappings' => 'sometimes|array',
            'default_account_id' => 'nullable|exists:accounts,id',
            'default_category_id' => 'nullable|exists:categories,id',
            'default_cost_center_id' => 'nullable|exists:cost_centers,id',
            'is_active' => 'sometimes|boolean',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
            ], 422);
        }

        $mapping->update($request->all());

        return response()->json([
            'success' => true,
            'data' => $mapping->fresh(),
        ]);
    }

    /**
     * Delete mapping
     */
    public function deleteMapping(int $id): JsonResponse
    {
        $mapping = ImportMapping::where('user_id', auth()->id())
            ->findOrFail($id);

        $mapping->delete();

        return response()->json([
            'success' => true,
            'message' => 'Mapping deleted successfully',
        ]);
    }

    /**
     * Get available bank presets
     */
    public function presets(): JsonResponse
    {
        $presets = $this->importService->getAvailablePresets();

        return response()->json([
            'success' => true,
            'data' => $presets,
        ]);
    }

    /**
     * Create mapping from preset
     */
    public function createFromPreset(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'preset' => 'required|string',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors(),
            ], 422);
        }

        try {
            $mapping = $this->importService->createBankPreset(
                $request->preset,
                auth()->id()
            );

            return response()->json([
                'success' => true,
                'data' => $mapping,
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * Get import history
     */
    public function history(Request $request): JsonResponse
    {
        $logs = ImportLog::where('user_id', auth()->id())
            ->with('importMapping')
            ->orderBy('created_at', 'desc')
            ->limit(50)
            ->get();

        return response()->json([
            'success' => true,
            'data' => $logs,
        ]);
    }

    /**
     * Get mappable fields info
     */
    public function fields(): JsonResponse
    {
        return response()->json([
            'success' => true,
            'data' => [
                'fields' => ImportMapping::MAPPABLE_FIELDS,
                'date_formats' => ImportMapping::DATE_FORMATS,
                'file_types' => ImportMapping::FILE_TYPES,
            ],
        ]);
    }
}
