<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Department;
use App\Models\SlaBusinessHours;
use App\Models\SlaPolicy;
use App\Models\TicketCustomField;
use App\Models\TicketTag;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
use Inertia\Response;

class TicketSettingsController extends Controller
{
    public function index(): Response
    {
        $departments = Department::query()
            ->with(['slaPolicy', 'autoAssignee:id,name,email'])
            ->orderBy('sort_order')
            ->get();

        $slaPolicies = SlaPolicy::query()->orderBy('name')->get();

        $businessHours = SlaBusinessHours::query()
            ->orderBy('day_of_week')
            ->get();

        $tags = TicketTag::query()->orderBy('name')->get();

        $customFields = TicketCustomField::query()
            ->with('department:id,name')
            ->orderBy('sort_order')
            ->get();

        $staffUsers = User::role('admin')->select('id', 'name', 'email')->orderBy('name')->get();

        return Inertia::render('Admin/Tickets/Settings', [
            'departments' => $departments,
            'slaPolicies' => $slaPolicies,
            'businessHours' => $businessHours,
            'tags' => $tags,
            'customFields' => $customFields,
            'staffUsers' => $staffUsers,
        ]);
    }

    // --- Departments ---

    public function storeDepartment(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'slug' => ['required', 'string', 'max:255', 'unique:departments,slug'],
            'email' => ['nullable', 'email', 'max:255'],
            'auto_assign_to' => ['nullable', 'exists:users,id'],
            'sla_policy_id' => ['nullable', 'exists:sla_policies,id'],
            'sort_order' => ['integer'],
        ]);

        $validated['slug'] = Str::slug($validated['slug']);

        Department::query()->create($validated);

        return redirect()->back()->with('success', 'Department created successfully.');
    }

    public function updateDepartment(Request $request, Department $department): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'slug' => ['required', 'string', 'max:255', Rule::unique('departments', 'slug')->ignore($department->id)],
            'email' => ['nullable', 'email', 'max:255'],
            'auto_assign_to' => ['nullable', 'exists:users,id'],
            'sla_policy_id' => ['nullable', 'exists:sla_policies,id'],
            'sort_order' => ['integer'],
        ]);

        $validated['slug'] = Str::slug($validated['slug']);

        $department->update($validated);

        return redirect()->back()->with('success', 'Department updated successfully.');
    }

    public function destroyDepartment(Department $department): RedirectResponse
    {
        if ($department->tickets()->exists()) {
            return redirect()->back()->with('error', 'Cannot delete department with existing tickets.');
        }

        $department->delete();

        return redirect()->back()->with('success', 'Department deleted successfully.');
    }

    // --- SLA Policies ---

    public function storeSlaPolicy(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'priority' => ['required', 'string', 'in:low,medium,high,urgent'],
            'first_response_hours' => ['required', 'integer', 'min:1'],
            'resolution_hours' => ['required', 'integer', 'min:1'],
            'business_hours_only' => ['boolean'],
        ]);

        SlaPolicy::query()->create($validated);

        return redirect()->back()->with('success', 'SLA policy created successfully.');
    }

    public function updateSlaPolicy(Request $request, SlaPolicy $slaPolicy): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'priority' => ['required', 'string', 'in:low,medium,high,urgent'],
            'first_response_hours' => ['required', 'integer', 'min:1'],
            'resolution_hours' => ['required', 'integer', 'min:1'],
            'business_hours_only' => ['boolean'],
        ]);

        $slaPolicy->update($validated);

        return redirect()->back()->with('success', 'SLA policy updated successfully.');
    }

    public function destroySlaPolicy(SlaPolicy $slaPolicy): RedirectResponse
    {
        if ($slaPolicy->departments()->exists()) {
            return redirect()->back()->with('error', 'Cannot delete SLA policy assigned to departments.');
        }

        $slaPolicy->delete();

        return redirect()->back()->with('success', 'SLA policy deleted successfully.');
    }

    // --- Business Hours ---

    public function updateBusinessHours(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'hours' => ['required', 'array'],
            'hours.*.day_of_week' => ['required', 'integer', 'between:0,6'],
            'hours.*.start_time' => ['required', 'date_format:H:i'],
            'hours.*.end_time' => ['required', 'date_format:H:i', 'after:hours.*.start_time'],
            'hours.*.is_holiday' => ['boolean'],
        ]);

        // Replace all business hours with the new set
        SlaBusinessHours::query()->delete();

        foreach ($validated['hours'] as $hour) {
            SlaBusinessHours::query()->create($hour);
        }

        return redirect()->back()->with('success', 'Business hours updated successfully.');
    }

    // --- Tags ---

    public function storeTag(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'color' => ['required', 'string', 'size:7', 'regex:/^#[0-9A-Fa-f]{6}$/'],
        ]);

        TicketTag::query()->create($validated);

        return redirect()->back()->with('success', 'Tag created successfully.');
    }

    public function updateTag(Request $request, TicketTag $ticketTag): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'color' => ['required', 'string', 'size:7', 'regex:/^#[0-9A-Fa-f]{6}$/'],
        ]);

        $ticketTag->update($validated);

        return redirect()->back()->with('success', 'Tag updated successfully.');
    }

    public function destroyTag(TicketTag $ticketTag): RedirectResponse
    {
        $ticketTag->tickets()->detach();
        $ticketTag->delete();

        return redirect()->back()->with('success', 'Tag deleted successfully.');
    }

    // --- Custom Fields ---

    public function storeCustomField(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'type' => ['required', 'in:text,select,checkbox,number'],
            'options' => ['nullable', 'array'],
            'options.*' => ['string', 'max:255'],
            'is_required' => ['boolean'],
            'department_id' => ['nullable', 'exists:departments,id'],
            'sort_order' => ['integer'],
        ]);

        TicketCustomField::query()->create($validated);

        return redirect()->back()->with('success', 'Custom field created successfully.');
    }

    public function updateCustomField(Request $request, TicketCustomField $ticketCustomField): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'type' => ['required', 'in:text,select,checkbox,number'],
            'options' => ['nullable', 'array'],
            'options.*' => ['string', 'max:255'],
            'is_required' => ['boolean'],
            'department_id' => ['nullable', 'exists:departments,id'],
            'sort_order' => ['integer'],
        ]);

        $ticketCustomField->update($validated);

        return redirect()->back()->with('success', 'Custom field updated successfully.');
    }

    public function destroyCustomField(TicketCustomField $ticketCustomField): RedirectResponse
    {
        $ticketCustomField->values()->delete();
        $ticketCustomField->delete();

        return redirect()->back()->with('success', 'Custom field deleted successfully.');
    }
}
