<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class CaixaController extends Controller
{
    // Exibe a tela do caixa
    public function index()
    {
        return view('caixa.index');
    }

    /** Autocomplete AJAX */
    public function searchProduct(Request $request)
    {
        $term = trim($request->q);
        $usuario = auth()->user();

        if (!$term) {
            return response()->json([]);
        }

        $query = DB::table('produtos');

        // SE NÃO FOR ADMIN → FILTRA POR PREFIXO (BAR/ARM) via acesso_us
        if ($usuario && $usuario->tipo_us !== 'ADMIN') {
            $query->where('nome_pro', 'LIKE', $usuario->acesso_us . '%');
        }

        // Aplicar busca
        $query->where(function($q) use ($term) {
            $q->where('nome_pro', 'LIKE', "%{$term}%")
              ->orWhere('codigo_pro', 'LIKE', "%{$term}%");
        });

        $produtos = $query->limit(15)->get();

        return response()->json(
            $produtos->map(function($p){
                return [
                    'id'      => $p->codigo_pro,
                    'text'    => "{$p->nome_pro} (COD: {$p->codigo_pro}) — Estoque: {$p->quant_pro}",
                    'preco'   => $p->valor_pro,
                    'estoque' => (int) $p->quant_pro,
                ];
            })
        );
    }

    /** Checar estoque (front pode chamar antes de adicionar) */
    public function checarEstoque($codigo)
    {
        $produto = DB::table('produtos')->where('codigo_pro', $codigo)->first();

        if (!$produto) {
            return response()->json([
                'success' => false,
                'estoque' => null,
                'message' => 'Produto não encontrado.'
            ], 404);
        }

        $estoque = (int) $produto->quant_pro;

        if ($estoque <= 0) {
            return response()->json([
                'success' => false,
                'estoque' => 0,
                'message' => 'Produto sem estoque.'
            ]);
        }

        return response()->json([
            'success' => true,
            'estoque' => $estoque
        ]);
    }

    /** Finalizar venda (usado pelo caixa) */
    public function finalizarVenda(Request $request)
    {
        // Validação dos dados enviados
        $data = $request->validate([
            'itens'              => 'required|array|min:1',
            'itens.*.codigo'     => 'required|string',
            'itens.*.preco'      => 'required|numeric',
            'itens.*.quant'      => 'required|integer|min:1',
            'metodo_pagamento'   => 'nullable|string',
            'valor_recebido'     => 'nullable|numeric',
            'troco'              => 'nullable|numeric',
            'referencia'         => 'nullable|string',
        ]);

        // Usuário logado
        $usuarioLogado = auth()->user();
        if (!$usuarioLogado) {
            return response()->json(['error' => 'Usuário não autenticado.'], 401);
        }
        $usuario = $usuarioLogado->codigo_us;

        // Gera código sequencial FACT000X
        $ultimo = DB::table('vendas')->orderBy('codigo', 'desc')->first();
        if ($ultimo && preg_match('/FACT(\d+)/', $ultimo->codigo, $m)) {
            $num = intval($m[1]) + 1;
            $codigo = 'FACT' . str_pad($num, 4, '0', STR_PAD_LEFT);
        } else {
            $codigo = 'FACT0001';
        }

        // Calcula totais
        $nr_itens = 0;
        $valorPago = 0.0;
        foreach ($data['itens'] as $it) {
            $nr_itens += (int) $it['quant'];
            $valorPago += (float) $it['preco'] * (int) $it['quant'];
        }

        DB::beginTransaction();

        try {
            // Validação de estoque antes de qualquer gravação
            foreach ($data['itens'] as $it) {
                $produto = DB::table('produtos')
                    ->where('codigo_pro', $it['codigo'])
                    ->lockForUpdate()
                    ->first();

                if (!$produto) {
                    throw new \Exception("Produto {$it['codigo']} não encontrado.");
                }

                if ((int)$produto->quant_pro < (int)$it['quant']) {
                    throw new \Exception("Estoque insuficiente para o produto {$produto->nome_pro}. Disponível: {$produto->quant_pro}, solicitado: {$it['quant']}");
                }
            }

            // Inserir venda
            DB::table('vendas')->insert([
                'codigo'           => $codigo,
                'usuario'          => $usuario,
                'nr_itens'         => $nr_itens,
                'valorPago'        => $valorPago,
                'metodo_pagamento' => $data['metodo_pagamento'] ?? null,
                'valor_recebido'   => $data['valor_recebido'] ?? null,
                'troco'            => $data['troco'] ?? null,
                'referencia'       => $data['referencia'] ?? null,
                'data'             => now(),
            ]);

            // Inserir itens e atualizar estoque
            foreach ($data['itens'] as $it) {
                DB::table('produtos')
                    ->where('codigo_pro', $it['codigo'])
                    ->decrement('quant_pro', (int)$it['quant']);

                DB::table('itensvenda')->insert([
                    'codigoVenda' => $codigo,
                    'codProduto'  => $it['codigo'],
                    'preco'       => (float)$it['preco'],
                    'quantidade'  => (int)$it['quant'],
                    'subtotal'    => (float)$it['preco'] * (int)$it['quant'],
                ]);
            }

            DB::commit();

            return response()->json([
                'success'     => true,
                'codigoVenda' => $codigo,
                'nr_itens'    => $nr_itens,
                'valorPago'   => $valorPago
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'error'    => 'Erro ao finalizar venda',
                'detalhes' => $e->getMessage()
            ], 500);
        }
    }
}
