<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Offer;
use App\Models\Position;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class PositionController extends Controller
{
    /**
     * If you're using central connection, keep everything consistent.
     */
    private string $conn = 'central';

    /**
     * GET /api/offers/{offer}/positions
     */
    public function index(Offer $offer)
    {
        // Ensure Offer is read from same DB connection
        $offer->setConnection($this->conn);

        $positions = Position::on($this->conn)
            ->where('offer_id', $offer->id)
            ->orderBy('id', 'asc')
            ->get();

        return response()->json(
    $positions->map(fn($p) => $this->expand($p))->values()
);
    }

    /**
     * POST /api/offers/{offer}/positions
     * Create a single position (stores full payload into data JSON).
     */
     public function store(Request $request, Offer $offer)
    {
        $offer->setConnection($this->conn);

        // ✅ Validate important fields, but DON'T use validated array as payload
        $this->validatePosition($request);

        // ✅ Save EVERYTHING the frontend sends
        $payload = $request->all();

        $position = Position::on($this->conn)->create([
            'offer_id'  => $offer->id,
            'name'      => $payload['name'] ?? null,
        
          
            'data'      => $payload,
        ]);

        return response()->json($position, 201);
    }

    /**
     * GET /api/positions/{position}
     */
    public function show(Position $position)
    {
        $position->setConnection($this->conn);
        return response()->json($this->expand($position));
    }

    /**
     * PUT/PATCH /api/positions/{position}
     */
    public function update(Request $request, Position $position)
    {
        $position->setConnection($this->conn);

        $this->validatePosition($request, partial: true);

        $incoming = $request->all();

        // merge into existing data (keep old keys if frontend didn't send them)
        $existing = is_array($position->data)
            ? $position->data
            : (json_decode($position->data ?? '[]', true) ?: []);

        $merged = array_merge($existing, $incoming);

        $position->update([
            'name'     => $merged['name'] ?? $position->name,
            'subtotal' => $merged['subtotal'] ?? $position->subtotal,
            'total'    => $merged['total'] ?? $position->total,
            'data'     => $merged,
        ]);

        return response()->json($position->fresh());
    }

    /**
     * DELETE /api/positions/{position}
     */
    public function destroy(Position $position)
    {
        $position->setConnection($this->conn);
        $position->delete();
        return response()->json(['ok' => true]);
    }

    /**
     * POST /api/offers/{offer}/positions/sync
     * This is the BEST endpoint for your React flow:
     * When React updates offer.positions array, you call sync with that array.
     * It deletes old positions and inserts new ones (atomic).
     */
    public function sync(Request $request, Offer $offer)
    {
        $offer->setConnection($this->conn);

        $positions = $request->input('positions');
        if (!is_array($positions)) {
            throw ValidationException::withMessages([
                'positions' => ['positions must be an array'],
            ]);
        }

        DB::connection($this->conn)->transaction(function () use ($offer, $positions) {
            Position::on($this->conn)->where('offer_id', $offer->id)->delete();

            foreach ($positions as $p) {
                if (!is_array($p)) continue;

                // optional: validate minimal keys per position
                // (don’t block saving if extra keys exist)
                // if you want strict validation here, tell me and I’ll add it.

                Position::on($this->conn)->create([
                    'offer_id' => $offer->id,
                    'name'     => $p['name'] ?? null,
                
               
                    'data'     => $p, // ✅ store full object (roll, glass, everything)
                ]);
            }
        });

        return response()->json(
            Position::on($this->conn)
                ->where('offer_id', $offer->id)
                ->orderBy('id', 'asc')
                ->get()
        );
    }

    private function validatePosition(Request $request, bool $partial = false): void
    {
        // ✅ We validate only the "core" types, but we STILL save full payload in `data`
        $rules = [
            'name' => [$partial ? 'sometimes' : 'nullable', 'string', 'max:255'],

            'frameW' => [$partial ? 'sometimes' : 'nullable', 'numeric'],
            'frameH' => [$partial ? 'sometimes' : 'nullable', 'numeric'],

            'extraBottomProfile' => [$partial ? 'sometimes' : 'nullable', 'numeric'],
            'isDoor' => [$partial ? 'sometimes' : 'nullable', 'boolean'],

            'hasRoll' => [$partial ? 'sometimes' : 'nullable', 'boolean'],
            'rollHeight' => [$partial ? 'sometimes' : 'nullable', 'numeric'],

            'shapeType' => [$partial ? 'sometimes' : 'nullable', 'string'],
            'topLeftOffsetMm' => [$partial ? 'sometimes' : 'nullable', 'numeric'],
            'topRightOffsetMm' => [$partial ? 'sometimes' : 'nullable', 'numeric'],

            'tProfiles' => [$partial ? 'sometimes' : 'nullable', 'array'],
            'sashes' => [$partial ? 'sometimes' : 'nullable', 'array'],
            'segmentsGlass' => [$partial ? 'sometimes' : 'nullable', 'array'],

            'glassTypeId' => [$partial ? 'sometimes' : 'nullable'],
            'profileId' => [$partial ? 'sometimes' : 'nullable'],
            'ironId' => [$partial ? 'sometimes' : 'nullable'],
        ];

        $request->validate($rules);
    }



    private function expand(Position $p): array
{
    $data = is_array($p->data) ? $p->data : (json_decode($p->data ?? '[]', true) ?: []);

    return array_merge($data, [
        '_db_id'   => $p->id,
        'offer_id' => $p->offer_id,
    ]);
}

}
