<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\SlaPlan;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class SlaPlanController extends Controller
{
    use LogsAdminActivity;

    public function index()
    {
        return view('admin.sla-plans.index');
    }

    public function create()
    {
        return view('admin.sla-plans.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'first_response_time' => 'required|integer|min:1',
            'resolution_time' => 'required|integer|min:1',
            'business_hours_only' => 'nullable',
            'priority_low' => 'nullable|numeric|min:0.1',
            'priority_medium' => 'nullable|numeric|min:0.1',
            'priority_high' => 'nullable|numeric|min:0.1',
            'priority_urgent' => 'nullable|numeric|min:0.1',
            'is_active' => 'nullable',
            'is_global' => 'nullable',
        ]);

        try {
            DB::beginTransaction();

            $slaPlan = SlaPlan::create([
                'name' => $validated['name'],
                'description' => $validated['description'] ?? null,
                'first_response_time' => $validated['first_response_time'],
                'resolution_time' => $validated['resolution_time'],
                'business_hours_only' => $request->boolean('business_hours_only'),
                'is_active' => $request->boolean('is_active', true),
                'is_global' => $request->boolean('is_global'),
                'priority_multipliers' => [
                    'low' => (float) ($validated['priority_low'] ?? 2),
                    'medium' => (float) ($validated['priority_medium'] ?? 1),
                    'high' => (float) ($validated['priority_high'] ?? 0.5),
                    'urgent' => (float) ($validated['priority_urgent'] ?? 0.25),
                ],
            ]);

            // PRC-351 — exactly one global default plan.
            if ($slaPlan->is_global) {
                SlaPlan::where('id', '!=', $slaPlan->id)->where('is_global', true)->update(['is_global' => false]);
            }

            $this->logCreated($slaPlan, "Created SLA plan #{$slaPlan->id} - {$slaPlan->name}");

            DB::commit();

            return redirect()->route('admin.sla-plans.index')
                ->with('success', __('admin/sla.plan_created'));
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()->back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function edit(SlaPlan $slaPlan)
    {
        return view('admin.sla-plans.edit', compact('slaPlan'));
    }

    public function update(Request $request, SlaPlan $slaPlan)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'first_response_time' => 'required|integer|min:1',
            'resolution_time' => 'required|integer|min:1',
            'business_hours_only' => 'nullable',
            'priority_low' => 'nullable|numeric|min:0.1',
            'priority_medium' => 'nullable|numeric|min:0.1',
            'priority_high' => 'nullable|numeric|min:0.1',
            'priority_urgent' => 'nullable|numeric|min:0.1',
            'is_active' => 'nullable',
            'is_global' => 'nullable',
        ]);

        try {
            DB::beginTransaction();

            $slaPlan->update([
                'name' => $validated['name'],
                'description' => $validated['description'] ?? null,
                'first_response_time' => $validated['first_response_time'],
                'resolution_time' => $validated['resolution_time'],
                'business_hours_only' => $request->boolean('business_hours_only'),
                'is_active' => $request->boolean('is_active', true),
                'is_global' => $request->boolean('is_global'),
                'priority_multipliers' => [
                    'low' => (float) ($validated['priority_low'] ?? 2),
                    'medium' => (float) ($validated['priority_medium'] ?? 1),
                    'high' => (float) ($validated['priority_high'] ?? 0.5),
                    'urgent' => (float) ($validated['priority_urgent'] ?? 0.25),
                ],
            ]);

            // PRC-351 — exactly one global default plan.
            if ($slaPlan->is_global) {
                SlaPlan::where('id', '!=', $slaPlan->id)->where('is_global', true)->update(['is_global' => false]);
            }

            $this->logUpdated($slaPlan, "Updated SLA plan #{$slaPlan->id} - {$slaPlan->name}");

            DB::commit();

            return redirect()->route('admin.sla-plans.index')
                ->with('success', __('admin/sla.plan_updated'));
        } catch (\Exception $e) {
            DB::rollBack();

            return redirect()->back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function destroy(SlaPlan $slaPlan)
    {
        try {
            DB::beginTransaction();

            $this->logDeleted($slaPlan, "Deleted SLA plan #{$slaPlan->id} - {$slaPlan->name}");

            $slaPlan->delete();

            DB::commit();

            return response()->json(['success' => true, 'message' => __('admin/sla.plan_deleted')]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function records(Request $request): JsonResponse
    {
        $query = SlaPlan::query();

        if ($request->filled('status')) {
            $query->where('is_active', $request->input('status') === 'active');
        }

        $query->orderBy('name');

        $perPage = $request->input('length', -1);

        if ($perPage == -1) {
            $results = $query->get();
            $total = $results->count();
            $paginatedResults = new \stdClass;
            $paginatedResults->data = $results;
            $paginatedResults->total = $total;
            $results = $paginatedResults;
        } else {
            $page = ($request->input('start', 0) / $perPage) + 1;
            $results = $query->paginate($perPage, ['*'], 'page', $page);
        }

        $dataCollection = $perPage == -1 ? $results->data : $results;
        $data = $dataCollection->map(function (SlaPlan $plan) {
            return [
                'id' => $plan->id,
                'name' => $plan->name,
                'first_response_time' => $this->formatMinutes($plan->first_response_time),
                'resolution_time' => $this->formatMinutes($plan->resolution_time),
                'business_hours_only' => $plan->business_hours_only,
                'is_active' => $plan->is_active,
                'created_at' => $plan->created_at->format('d.m.Y H:i'),
            ];
        });

        $total = $perPage == -1 ? $results->total : $results->total();

        return response()->json([
            'draw' => (int) $request->input('draw'),
            'recordsTotal' => $total,
            'recordsFiltered' => $total,
            'data' => $data,
        ]);
    }

    private function formatMinutes(int $minutes): string
    {
        if ($minutes < 60) {
            return $minutes . 'm';
        }

        $hours = floor($minutes / 60);
        $remaining = $minutes % 60;

        return $remaining > 0 ? "{$hours}h {$remaining}m" : "{$hours}h";
    }
}
