<?php

declare(strict_types=1);

namespace App\Http\Controllers\Barangay;

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

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

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

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

        $query = BarangayProject::orderByDesc('id');

        if ($status = $request->input('status')) $query->where('status', $status);
        if ($type = $request->input('type')) $query->where('type', $type);
        if ($year = $request->input('year')) {
            $query->whereYear('start_date', $year);
        }

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

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

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

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

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

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

        $validator = Validator::make($request->all(), [
            'project_name'        => 'required|string|max:500',
            'description'         => 'nullable|string',
            'type'                => 'required|in:INFRASTRUCTURE,LIVELIHOOD,HEALTH,EDUCATION,ENVIRONMENT,OTHERS',
            'budget'              => 'required|numeric|min:0',
            'fund_source'         => 'required|in:GENERAL_FUND,SK,PROVINCE,NATIONAL,OTHERS',
            'start_date'          => 'required|date',
            'end_date'            => 'nullable|date|after:start_date',
            'implementing_office' => 'nullable|string|max:255',
            'contractor'          => 'nullable|string|max:255',
            'location'            => 'nullable|string|max:500',
            'beneficiaries_count' => 'nullable|integer|min:0',
        ]);

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

        $data = $validator->validated();
        $data['hashkey']    = hash('sha256', uniqid((string) now(), true));
        $data['status']     = 'PLANNED';
        $data['created_by'] = Auth::id();
        $data['updated_by'] = Auth::id();

        $project = BarangayProject::create($data);

        return response()->json(['success' => true, 'data' => $project, 'message' => 'Project created']);
    }

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

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

        $data = $request->except(['target', 'hashkey', 'created_by']);
        $data['updated_by'] = Auth::id();
        $project->update($data);

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

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

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

        $validStatuses = ['PLANNED', 'ONGOING', 'COMPLETED', 'SUSPENDED', 'CANCELLED'];
        $status = $request->input('status');
        if (!in_array($status, $validStatuses)) {
            return ResponseHelper::returnError('Invalid status', 422);
        }

        $project->update(['status' => $status, 'updated_by' => Auth::id()]);

        return response()->json(['success' => true, 'data' => $project, 'message' => "Project status set to {$status}"]);
    }

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

        $summary = [
            'total'       => BarangayProject::count(),
            'planned'     => BarangayProject::where('status', 'PLANNED')->count(),
            'ongoing'     => BarangayProject::where('status', 'ONGOING')->count(),
            'completed'   => BarangayProject::where('status', 'COMPLETED')->count(),
            'total_budget' => BarangayProject::sum('budget'),
            'by_type'     => BarangayProject::selectRaw('type, count(*) as count, sum(budget) as budget')
                ->groupBy('type')->get(),
        ];

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