<?php

declare(strict_types=1);

namespace App\Http\Controllers\Barangay;

use App\Enums\UserActions;
use App\Enums\Barangay\BlotterStatus;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Http\Controllers\Helpers\ResponseHelper;
use App\Models\Barangay\Blotter;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
use Hypervel\Support\Facades\Validator;

class BlotterController
{
    private function checkRead(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ViewBlotters);
    }

    private function checkWrite(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ProcessBlotter);
    }

    public function index(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $query = Blotter::with(['assignedOfficer'])->orderByDesc('id');

        if ($status = $request->input('status')) $query->where('status', $status);
        if ($type = $request->input('incident_type')) $query->where('incident_type', $type);
        if ($search = $request->input('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('complainant_name', 'like', "%{$search}%")
                  ->orWhere('respondent_name', 'like', "%{$search}%")
                  ->orWhere('blotter_no', 'like', "%{$search}%");
            });
        }

        $blotters = $query->paginate((int) $request->input('per_page', 20));

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

    public function show(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $blotter = Blotter::with(['assignedOfficer', 'hearings.officer'])
            ->where('hashkey', $request->input('target'))
            ->first();

        if (!$blotter) return ResponseHelper::returnError('Blotter not found', 404);

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

    public function store(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'complainant_name'    => 'required|string|max:255',
            'complainant_contact' => 'nullable|string|max:30',
            'complainant_address' => 'nullable|string|max:500',
            'respondent_name'     => 'required|string|max:255',
            'respondent_contact'  => 'nullable|string|max:30',
            'respondent_address'  => 'nullable|string|max:500',
            'incident_type'       => 'required|in:AMICABLE,UNLAWFUL,MINOR,OTHER',
            'incident_date'       => 'required|date',
            'incident_location'   => 'nullable|string|max:500',
            'narrative'           => 'required|string',
            'complainant_user_id' => 'nullable|integer|exists:users,id',
            'respondent_user_id'  => 'nullable|integer|exists:users,id',
        ]);

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

        $data = $validator->validated();
        $data['hashkey']        = hash('sha256', uniqid((string) now(), true));
        $data['blotter_no']     = Blotter::generateBlotterNo();
        $data['status']         = BlotterStatus::FILED;
        $data['complaint_date'] = now()->toDateString();
        $data['filed_by']       = Auth::id();
        $data['is_active']      = true;
        $data['created_by']     = Auth::id();
        $data['updated_by']     = Auth::id();

        $blotter = Blotter::create($data);

        return response()->json(['success' => true, 'data' => $blotter, 'message' => 'Blotter filed successfully']);
    }

    public function updateStatus(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $blotter = Blotter::where('hashkey', $request->input('target'))->first();
        if (!$blotter) return ResponseHelper::returnError('Blotter not found', 404);

        $newStatus = BlotterStatus::tryFrom($request->input('status'));
        if (!$newStatus) return ResponseHelper::returnError('Invalid status', 422);

        $data = ['status' => $newStatus, 'updated_by' => Auth::id()];
        if ($request->input('resolution')) $data['resolution'] = $request->input('resolution');
        if ($request->input('endorsed_to')) $data['endorsed_to'] = $request->input('endorsed_to');
        if ($request->input('settlement_type')) $data['settlement_type'] = $request->input('settlement_type');

        $blotter->update($data);

        return response()->json(['success' => true, 'data' => $blotter, 'message' => 'Status updated']);
    }

    public function assignOfficer(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $blotter = Blotter::where('hashkey', $request->input('target'))->first();
        if (!$blotter) return ResponseHelper::returnError('Blotter not found', 404);

        $blotter->update([
            'assigned_officer_id' => $request->input('officer_id'),
            'updated_by'          => Auth::id(),
        ]);

        return response()->json(['success' => true, 'data' => $blotter, 'message' => 'Officer assigned']);
    }

    public function statusOptions()
    {
        $options = collect(BlotterStatus::cases())->map(fn ($s) => ['value' => $s->value, 'label' => $s->label()]);
        return response()->json(['success' => true, 'data' => $options]);
    }
}
