<?php

namespace App\Http\Controllers;

use App\Models\Complaint;
use App\Models\Location;
use App\Services\LocationTrackingService;
use App\Services\ComplaintClassificationService;
use App\Services\DispatchService;
use App\Services\CctvService;
use App\Services\RulesEngineService;
use App\Services\WorkflowEngineService;
use App\Services\IncidentTimelineService;
use App\Services\HierarchicalAccessService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class ComplaintController extends Controller
{
    public function __construct(
        private LocationTrackingService $locationTrackingService,
        private ComplaintClassificationService $classificationService,
        private DispatchService $dispatchService,
        private CctvService $cctvService,
        private RulesEngineService $rulesEngine,
        private WorkflowEngineService $workflowEngine,
        private IncidentTimelineService $timelineService,
        private HierarchicalAccessService $accessService
    ) {}

    /**
     * Display a listing of complaints
     */
    public function index(Request $request)
    {
        if (!Schema::hasTable('complaints')) {
            $complaints = $this->emptyPaginator();
            return view('complaints.index', compact('complaints'));
        }

        $query = Complaint::with(['location', 'polsek', 'operator', 'dispatches'])
            ->orderBy('created_at', 'desc');

        // Apply hierarchical access control
        $this->accessService->applyScope($query, $request->user());

        // Apply filters
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        if ($request->has('category')) {
            $query->where('category', $request->category);
        }

        $complaints = $query->paginate(20);

        return view('complaints.index', compact('complaints'));
    }

    /**
     * Store a newly created complaint
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'source' => 'required|in:phone,mobile_app,panic_button,whatsapp,sms',
            'caller_phone' => 'nullable|string',
            'caller_name' => 'nullable|string',
            'description' => 'required|string',
            'latitude' => 'nullable|numeric',
            'longitude' => 'nullable|numeric',
            'cell_id' => 'nullable|string',
            'phone_number' => 'nullable|string',
        ]);

        // Auto-track location
        $location = $this->locationTrackingService->autoTrack(
            $validated['latitude'] ?? null,
            $validated['longitude'] ?? null,
            $validated['cell_id'] ?? null,
            $validated['phone_number'] ?? $validated['caller_phone'] ?? null
        );

        // Classify complaint
        $classification = $this->classificationService->classify(
            $validated['description'],
            $validated['caller_phone'] ?? null
        );

        // Find responsible Polsek
        $polsek = null;
        if ($location) {
            $polsek = $this->locationTrackingService->findResponsiblePolsek($location);
        }

        // Create complaint
        $complaint = Complaint::create([
            'ticket_number' => $this->generateTicketNumber(),
            'source' => $validated['source'],
            'caller_phone' => $validated['caller_phone'] ?? null,
            'caller_name' => $validated['caller_name'] ?? null,
            'description' => $validated['description'],
            'category' => $classification['category'],
            'priority' => $classification['priority'],
            'status' => 'pending',
            'location_id' => $location?->id,
            'polda_id' => $polsek?->polres?->polda_id,
            'polres_id' => $polsek?->polres_id,
            'polsek_id' => $polsek?->id,
            'operator_id' => $request->user()->id,
            'ai_classification' => $classification['ai_classification'],
            'keywords' => $classification['keywords'],
            'received_at' => now(),
        ]);

        // Log complaint received
        $this->timelineService->logComplaintReceived($complaint, $request->user());

        // Auto-detect and save reporter location
        $reporterLocation = $this->locationTrackingService->autoDetectReporterLocation(
            $complaint,
            $validated['latitude'] ?? null,
            $validated['longitude'] ?? null,
            $validated['cell_id'] ?? null,
            $validated['tower_id'] ?? null,
            $validated['phone_number'] ?? $validated['caller_phone'] ?? null,
            $validated['accuracy'] ?? null
        );

        // Log location detected if found
        if ($reporterLocation) {
            $this->timelineService->logLocationDetected($complaint, $reporterLocation->tracking_method);
        }

        // Log to heatmap
        if (\Illuminate\Support\Facades\Schema::hasTable('crime_heatmap_data')) {
            $heatmapService = app(\App\Services\HeatmapService::class);
            $heatmapService->logComplaint($complaint);
        }

        // Execute workflow
        $this->workflowEngine->executeComplaintWorkflow($complaint);

        // Execute automation rules
        $this->rulesEngine->executeRules('complaint.created', [
            'complaint_id' => $complaint->id,
            'category' => $complaint->category,
            'priority' => $complaint->priority,
            'has_location' => $location !== null,
        ]);

        return response()->json([
            'success' => true,
            'complaint' => $complaint->load(['location', 'polsek', 'dispatches']),
        ], 201);
    }

    /**
     * Display the specified complaint
     */
    public function show(Request $request, Complaint $complaint)
    {
        // Check access control
        $user = $request->user();
        if (!$this->accessService->canAccess($user, $complaint->polda_id, $complaint->polres_id, $complaint->polsek_id)) {
            abort(403, 'Unauthorized access to this complaint');
        }

        $complaint->load([
            'location',
            'polda',
            'polres',
            'polsek',
            'operator',
            'recordings',
            'dispatches.dispatchUnits.officer',
            'cctvSnapshots.cctv',
            'coordinations',
            'timeline.user',
            'timeline.officer',
            'evidence.collector',
            'evidence.officer',
        ]);

        return view('complaints.show', compact('complaint'));
    }

    /**
     * Classify complaint
     */
    public function classify(Request $request, Complaint $complaint)
    {
        $classification = $this->classificationService->classify(
            $complaint->description,
            $complaint->caller_phone
        );

        $complaint->update([
            'category' => $classification['category'],
            'priority' => $classification['priority'],
            'ai_classification' => $classification['ai_classification'],
            'keywords' => $classification['keywords'],
        ]);

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

    /**
     * Generate unique ticket number
     */
    private function generateTicketNumber(): string
    {
        $date = now()->format('Ymd');
        $random = Str::upper(Str::random(6));
        return "ADU-{$date}-{$random}";
    }
}
