<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\ResolveUnknownStatusesRequest;
use App\Http\Requests\StoreImportRequest;
use App\Jobs\ImportLeadsJob;
use App\Models\ImportLog;
use App\Models\ImportUnknownStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

/**
 * CSV-импорт исторических лидов из crm.bp-gr.ru (ТЗ §6).
 *
 * Все маршруты — под auth:sanctum + tenant (RLS-контекст задан middleware).
 * tenant_id берётся из авторизованного пользователя, не из запроса.
 */
class ImportController extends Controller
{
    /**
     * POST /api/imports — загрузка CSV, создание import_log, dispatch job'а.
     */
    public function store(StoreImportRequest $request): JsonResponse
    {
        $tenantId = (int) $request->user()->tenant_id;
        $file = $request->file('file');
        $storedName = Str::uuid()->toString().'.csv';
        $path = $file->storeAs("imports/{$tenantId}", $storedName, 'local');

        $log = ImportLog::create([
            'tenant_id' => $tenantId,
            'user_id' => $request->user()->id,
            'filename' => $file->getClientOriginalName(),
            'file_path' => $path,
            'status' => 'pending',
            'entity_type' => 'leads',
            'source_system' => 'crm.bp-gr.ru',
            'dry_run' => $request->boolean('dry_run'),
        ]);

        ImportLeadsJob::dispatch($log->id, $tenantId);

        return response()->json(['data' => $this->toResource($log)], 201);
    }

    /**
     * GET /api/imports — история импортов тенанта (RLS отфильтрует по tenant).
     *
     * Defense-in-depth: явный where(tenant_id) поверх RLS — на dev через
     * `postgres` superuser RLS обходится BYPASSRLS, app-фильтр гарантирует
     * изоляцию (паттерн из DealController).
     */
    public function index(Request $request): JsonResponse
    {
        $tenantId = (int) $request->user()->tenant_id;

        $logs = ImportLog::query()
            ->where('tenant_id', $tenantId)
            ->orderByDesc('id')
            ->limit(50)
            ->get()
            ->map(fn (ImportLog $log) => $this->toResource($log));

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

    /**
     * GET /api/imports/{importLog} — прогресс одного импорта (для polling'а).
     *
     * Defense-in-depth: явная проверка tenant_id на принадлежность поверх RLS.
     */
    public function show(Request $request, ImportLog $importLog): JsonResponse
    {
        $tenantId = (int) $request->user()->tenant_id;

        abort_if($importLog->tenant_id !== $tenantId, 403, 'Доступ к импорту другого тенанта запрещён.');

        return response()->json(['data' => $this->toResource($importLog)]);
    }

    /**
     * GET /api/imports/unknown-statuses — незамапленные статусы (вход wizard'а §6.6).
     *
     * Defense-in-depth: явный where(tenant_id) поверх RLS.
     */
    public function unknownStatuses(Request $request): JsonResponse
    {
        $tenantId = (int) $request->user()->tenant_id;

        $rows = ImportUnknownStatus::query()
            ->where('tenant_id', $tenantId)
            ->unresolved()
            ->orderByDesc('occurrences')
            ->get()
            ->map(fn (ImportUnknownStatus $s) => [
                'id' => $s->id,
                'status_ru' => $s->status_ru,
                'occurrences' => $s->occurrences,
            ]);

        return response()->json(['data' => $rows]);
    }

    /**
     * POST /api/imports/unknown-statuses/resolve — ручной маппинг статусов.
     *
     * Defense-in-depth: явный where(tenant_id) поверх RLS.
     */
    public function resolveUnknownStatuses(ResolveUnknownStatusesRequest $request): JsonResponse
    {
        $tenantId = (int) $request->user()->tenant_id;
        $userId = (int) $request->user()->id;

        DB::transaction(function () use ($request, $tenantId, $userId): void {
            DB::statement('SET LOCAL app.current_tenant_id = '.$tenantId);

            foreach ($request->validated()['mappings'] as $mapping) {
                ImportUnknownStatus::query()
                    ->where('tenant_id', $tenantId)
                    ->where('status_ru', $mapping['status_ru'])
                    ->update([
                        'mapped_to_slug' => $mapping['slug'],
                        'resolved_at' => now(),
                        'resolved_by' => $userId,
                    ]);
            }
        });

        return response()->json(['data' => ['resolved' => count($request->validated()['mappings'])]]);
    }

    /**
     * @return array<string, mixed>
     */
    private function toResource(ImportLog $log): array
    {
        return [
            'id' => $log->id,
            'filename' => $log->filename,
            'status' => $log->status,
            'rows_total' => $log->rows_total,
            'rows_added' => $log->rows_added,
            'rows_updated' => $log->rows_updated,
            'rows_skipped' => $log->rows_skipped,
            'unknown_statuses_count' => $log->unknown_statuses_count,
            'dry_run' => $log->dry_run,
            'error_message' => $log->error_message,
            'started_at' => $log->started_at?->toIso8601String(),
            'finished_at' => $log->finished_at?->toIso8601String(),
        ];
    }
}
