<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\GarmentType;
use App\Models\MeasurementField;
use App\Models\ShopGarmentField;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class ShopGarmentFieldController extends Controller
{
    public function index(GarmentType $garmentType)
    {
        $shopId = $this->shopId();

        $configured = ShopGarmentField::where('shop_id', $shopId)
            ->where('garment_type_id', $garmentType->id)
            ->with('measurementField')
            ->orderBy('display_order')
            ->get();

        $addedFieldIds = $configured->pluck('measurement_field_id');

        $available = MeasurementField::whereNotIn('id', $addedFieldIds)
            ->whereHas('garmentTypes', fn ($q) => $q->where('garment_types.id', $garmentType->id))
            ->orderBy('name')
            ->get();

        return view('admin.garments.builder', compact('garmentType', 'configured', 'available'));
    }

    public function store(Request $request, GarmentType $garmentType)
    {
        $data = $request->validate([
            'measurement_field_id' => 'nullable|exists:measurement_fields,id',
            'new_field_name' => 'nullable|string|max:255',
            'new_field_name_ta' => 'nullable|string|max:255',
            'new_field_unit' => 'nullable|in:inch,cm',
            'field_type' => 'nullable|in:text,radio,select,checkbox',
            'options' => 'nullable|string|max:1000',
        ]);

        $shopId = $this->shopId();
        $fieldType = $data['field_type'] ?? 'text';
        $needsOptions = in_array($fieldType, ['radio', 'select', 'checkbox']);
        $options = $needsOptions ? ($data['options'] ?? null) : null;

        if ($needsOptions && empty($options)) {
            return back()->withErrors(['options' => 'Please add at least one option for this input type.']);
        }

        if (! empty($data['new_field_name'])) {
            $code = Str::slug($data['new_field_name'], '_');

            $measurementField = MeasurementField::firstOrCreate(
                ['code' => $code],
                [
                    'name' => $data['new_field_name'],
                    'name_ta' => $data['new_field_name_ta'] ?? null,
                    'unit' => $data['new_field_unit'] ?? 'inch',
                ]
            );

            $measurementField->garmentTypes()->syncWithoutDetaching([$garmentType->id]);

            $measurementFieldId = $measurementField->id;
        } elseif (! empty($data['measurement_field_id'])) {
            $measurementFieldId = $data['measurement_field_id'];
        } else {
            return back()->withErrors(['new_field_name' => 'Pick a field or type a new one.']);
        }

        $nextOrder = ShopGarmentField::where('shop_id', $shopId)
            ->where('garment_type_id', $garmentType->id)
            ->max('display_order') + 1;

        ShopGarmentField::firstOrCreate(
            [
                'shop_id' => $shopId,
                'garment_type_id' => $garmentType->id,
                'measurement_field_id' => $measurementFieldId,
            ],
            ['display_order' => $nextOrder, 'field_type' => $fieldType, 'options' => $options]
        );

        return back()->with('status', 'Field added.');
    }

    public function update(Request $request, GarmentType $garmentType, ShopGarmentField $field)
    {
        $this->authorizeField($field, $garmentType);

        $data = $request->validate([
            'custom_label' => 'nullable|string|max:255',
            'is_required' => 'boolean',
            'field_type' => 'required|in:text,radio,select,checkbox',
            'options' => 'nullable|string|max:1000',
        ]);

        $needsOptions = in_array($data['field_type'], ['radio', 'select', 'checkbox']);

        if ($needsOptions && empty($data['options'])) {
            return back()->withErrors(['options' => 'Please add at least one option for this input type.']);
        }

        $field->update([
            'custom_label' => $data['custom_label'] ?? null,
            'is_required' => $request->boolean('is_required'),
            'field_type' => $data['field_type'],
            'options' => $needsOptions ? ($data['options'] ?? null) : null,
        ]);

        return back()->with('status', 'Field updated.');
    }

    public function destroy(GarmentType $garmentType, ShopGarmentField $field)
    {
        $this->authorizeField($field, $garmentType);
        $field->delete();

        return back()->with('status', 'Field removed.');
    }

    public function reorder(Request $request, GarmentType $garmentType)
    {
        $data = $request->validate([
            'order' => 'required|array',
            'order.*' => 'exists:shop_garment_fields,id',
        ]);

        $shopId = $this->shopId();

        foreach ($data['order'] as $index => $fieldId) {
            ShopGarmentField::where('id', $fieldId)
                ->where('shop_id', $shopId)
                ->where('garment_type_id', $garmentType->id)
                ->update(['display_order' => $index]);
        }

        return response()->json(['status' => 'ok']);
    }

    protected function shopId(): int
    {
        return Auth::guard('admin')->user()->shop_id;
    }

    protected function authorizeField(ShopGarmentField $field, GarmentType $garmentType): void
    {
        abort_unless(
            $field->shop_id === $this->shopId() && $field->garment_type_id === $garmentType->id,
            403
        );
    }
}
