<?php

namespace App\Http\Controllers;

use App\Models\Branch;
use App\Models\Business;
use App\Models\ManagementAlert;
use App\Services\AuditService;
use App\Services\BranchAccessService;
use App\Services\ManagementWorkSettings;
use App\Support\Authorization\PermissionName;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;

class ManagementAlertController extends Controller
{
    public function __construct(private BranchAccessService $branchAccess)
    {
    }

    public function index(Request $request, ManagementWorkSettings $settings): View
    {
        $business = Business::firstOrFail();
        $branchIds = $this->branchIds($request);
        $query = ManagementAlert::query()->with(['branch','acknowledger','resolver'])->where('business_id',$business->id);
        if (! $this->branchAccess->isSystemWide($request->user())) $query->whereIn('branch_id',$branchIds);

        if ($request->filled('status')) $query->where('status',(string)$request->string('status'));
        if ($request->filled('type')) $query->where('type',(string)$request->string('type'));
        if ($request->filled('branch_id')) {
            $branchId = (int)$request->integer('branch_id');
            abort_unless(in_array($branchId,$branchIds,true),403);
            $query->where('branch_id',$branchId);
        }

        $summaryQuery = ManagementAlert::query()->where('business_id',$business->id);
        if (! $this->branchAccess->isSystemWide($request->user())) $summaryQuery->whereIn('branch_id',$branchIds);

        return view('management-alerts.index',[
            'alerts'=>$query->orderByRaw("CASE severity WHEN 'critical' THEN 1 WHEN 'warning' THEN 2 ELSE 3 END")
                ->orderByRaw("CASE status WHEN 'open' THEN 1 WHEN 'acknowledged' THEN 2 ELSE 3 END")->orderByDesc('occurred_at')->paginate(30)->withQueryString(),
            'types'=>ManagementAlert::TYPES,'statuses'=>ManagementAlert::STATUSES,
            'branches'=>Branch::whereIn('id',$branchIds)->orderBy('name')->get(),
            'summary'=>[
                'open'=>(clone $summaryQuery)->where('status','open')->count(),
                'acknowledged'=>(clone $summaryQuery)->where('status','acknowledged')->count(),
                'critical'=>(clone $summaryQuery)->whereIn('status',['open','acknowledged'])->where('severity','critical')->count(),
            ],
            'managementSettings'=>$settings->values($business),'business'=>$business,
        ]);
    }

    public function acknowledge(Request $request, ManagementAlert $alert): RedirectResponse
    {
        Gate::forUser($request->user())->authorize('acknowledge', $alert);
        abort_if($alert->status === 'resolved',422,'Resolved alerts cannot be acknowledged.');
        if ($alert->status === 'acknowledged') return back()->with('success','Alert is already acknowledged.');
        $before = $alert->toArray();
        $alert->update(['status'=>'acknowledged','acknowledged_by'=>$request->user()->id,'acknowledged_at'=>now()]);
        AuditService::record('management_alert.acknowledged',$alert,$before,$alert->fresh()->toArray());
        return back()->with('success','Management alert acknowledged.');
    }

    public function resolve(Request $request, ManagementAlert $alert): RedirectResponse
    {
        Gate::forUser($request->user())->authorize('resolve', $alert);
        $data = $request->validate(['resolution_note'=>['required','string','max:5000']]);
        abort_if($alert->status === 'resolved',422,'Alert is already resolved.');
        $before = $alert->toArray();
        $alert->update([
            'status'=>'resolved','resolved_by'=>$request->user()->id,'resolved_at'=>now(),'resolution_note'=>$data['resolution_note'],
        ]);
        AuditService::record('management_alert.resolved',$alert,$before,$alert->fresh()->toArray());
        return back()->with('success','Management alert resolved.');
    }

    public function settings(Request $request, ManagementWorkSettings $settings): RedirectResponse
    {
        Gate::forUser($request->user())->authorize(PermissionName::MANAGEMENT_ALERTS_SETTINGS->value);
        $business = Business::firstOrFail();
        $data = $request->validate([
            'collection_task_overdue_days'=>['required','integer','min:1','max:3650'],
            'large_loan_threshold'=>['required','numeric','min:0'],'large_expense_threshold'=>['required','numeric','min:0'],
            'overdue_alert_days'=>['required','integer','min:1','max:3650'],'low_account_balance_threshold'=>['required','numeric','min:0'],
            'cash_shortage_threshold'=>['required','numeric','min:0'],'pending_approval_days'=>['required','integer','min:0','max:3650'],
            'document_expiry_days'=>['required','integer','min:0','max:3650'],
        ]);
        $data['collection_tasks_enabled'] = $request->boolean('collection_tasks_enabled');
        $before = $settings->values($business);
        $settings->store($business->id,$data);
        AuditService::record('management.settings_updated',$business,$before,$settings->values($business));
        return back()->with('success','Task automation and management alert settings updated.');
    }

    private function branchIds(Request $request): array
    {
        return $this->branchAccess->accessibleBranchIds($request->user());
    }
}
