<?php

namespace App\Http\Controllers;

use App\Mail\AvisoNuevoVentaConfirmacionCliente;
use App\Models\Venta;
use App\Models\VentaDetalle;
use App\Models\VentaSesion;
use App\Models\Vale;
use App\Models\Inventario;
use App\Models\Pago;
use App\Models\Tienda;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Validator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use App\Helpers\CorreoHelper;

class VentaController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(): JsonResponse
    {
        $venta=Venta::where(['estatus'=>'activo'])->get();
        return response()->json([
            'data' =>$venta,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request): JsonResponse
    {
        $data = $request->all();

        $rules = [
            'sucursal_id' => ['required', Rule::exists('sucursales', 'id')],
            'productos_temp' => ['required', 'array'],
            'productos_temp.*.cantidad' => ['required', 'numeric', 'max:999999999.99', 'gt:0'],
            'productos_temp.*.precio_unitario' => ['required', 'numeric', 'max:999999999.99', 'gt:0'],
            'pagos' => ['required', 'array'],
            'pagos.*.tipo_pago_id' => ['required', Rule::exists('tipos_pagos', 'id')],
            'pagos.*.pago' => ['required', 'numeric', 'max:999999999.99', 'gt:0'],
            'total' => ['required', 'numeric', 'gt:0'],
            'pago' => ['required', 'numeric', 'gte:total'],
            'cliente_id'=> ['required_if:tipo_pago_id,4'],
            'sesion_temp' => ['array'],
            'sesion_temp.*.sesion_id' => ['required', 'exists:sesiones,id'],
            'limpiar_tienda' => ['sometimes', 'in:si,no'],
            'limpiar_tienda_personal' => ['required_if:limpiar_tienda,si', 'in:si,no'],
        ];

        foreach ($data['pagos'] as $index => $pago) {
            if ($pago['tipo_pago_id'] == 2 ||  $pago['tipo_pago_id'] == 3) {
                $rules["pagos.$index.banco"] = ['required', 'string'];
                $rules["pagos.$index.folio_pago"] = ['required', 'string'];
            }
        }

        $messages = [
            'folio_pago.required' => 'El campo folio pago es obligatorio',
            'banco.required' => 'El campo banco es obligatorio',
            'productos_temp.required' => 'Productos es obligatorio',
            'productos_temp.array' => 'Productos debe ser una lista',
            'pagos.required' => 'Pago es obligatorio',
            'pagos.array' => 'Pagos debe ser una lista',
            'pago.gte' => 'Pago debe ser mayor o igual al valor total',
            'total.required' => 'El total es obligatorio',
            'total.gt' => 'El total debe ser mayor a 0',
            'cliente_id.required_if' => 'El cliente es obligatorio para pagos a crédito',
            'limpiar_tienda_personal.required_if' => 'Debe especificar si la limpieza es personal cuando se limpia la tienda',
        ];

        Validator::make($data, $rules, $messages)->validate();

        $params = $request->only([
            'sucursal_id',
            'cliente_id',
            'tipo_baja_id',
            'total',
            'subtotal',
            'iva',
        ]);

        // if($request->tipo_pago_id == 4){
        //     $params['es_credito']='si';
        // }


        $venta = Venta::create($params);
        usleep(500000);

        foreach ($data['pagos'] as $pago) {
            Pago::create([
                'venta_id' => $venta->id,
                'tipo_pago_id' => $pago['tipo_pago_id'],
                'pago' => $pago['pago'],
                'banco' => $pago['banco'] ?? null,
                'folio_pago' => $pago['folio_pago'] ?? null,
                'cambio' => $request->cambio,
                'total' => $request->total,
            ]);
        }

        foreach ($request->productos_temp as $key => $productos) {
            $params_det =[
                'descripcion'=>$productos['descripcion'],
                'cliente_id'=>isset($productos['cliente_id'])?$productos['cliente_id']:null,
                'producto_id'=>isset($productos['producto_id'])?$productos['producto_id']:null,
                'tratamiento_id'=>isset($productos['tratamiento_id'])?$productos['tratamiento_id']:null,
                'vale_id'=>isset($productos['vale_id'])?$productos['vale_id']:null,
                'total'=>$productos['total'],
                'subtotal'=>$productos['subtotal'],
                'precio_unitario'=>$productos['precio_unitario'],
                'cantidad'=>$productos['cantidad'],
                'iva'=>$productos['iva'],
                'ieps'=>$productos['ieps'],
            ];

            if (isset($productos['vale_id'])) {
                $fecha_actual = date("Y-m-d");
                $fecha_final = date("Y-m-d", strtotime($fecha_actual . "+ 31 days"));
                $params_val =[
                    'total'=>$productos['total'],
                    'precio_unitario'=>$productos['precio_unitario'],
                    'iva'=>$productos['iva'],
                    'ieps'=>$productos['ieps'],
                    'vigencia'=>$fecha_final,
                    'token'=>'V' . date('YmdHi') . str_pad(rand(1, 999), 3, '0', STR_PAD_LEFT),
                ];
                $vale = Vale::create($params_val);
                $params_det['vale_id']= $vale->id;
                usleep(500000);
            }
            $params_det['venta_id']= $venta->id;

            VentaDetalle::create($params_det);
            if(isset($productos['producto_id'])){
                $model_inventario=Inventario::where([
                    'sucursal_id'=>$request->sucursal_id,
                    'producto_id'=>$productos['producto_id']
                ])->first();

                if($model_inventario){
                    $cantidad_existente=$model_inventario->cantidad_existente-$productos['cantidad'];
                    $cantidad_vendido=$model_inventario->cantidad_vendido+$productos['cantidad'];
                    $model_inventario->update([
                        'cantidad_existente' => $cantidad_existente,
                        'cantidad_vendido' => $cantidad_vendido,
                    ]);
                } else {
                    $model_inventario = Inventario::create([
                        'sucursal_id'=>$request->sucursal_id,
                        'producto_id'=>$productos['producto_id'],
                        'cantidad_existente'=> (-$productos['cantidad']),
                        'cantidad_vendido'=> ($productos['cantidad']),
                        'cantidad_vendido'=>0,
                    ]);
                }
            }
            usleep(500000);
        }

        foreach ($request->sesion_temp as $key => $sesion) {
            $params_det =[
                'sesion_id'=>$sesion['sesion_id']
            ];
            $params_det['venta_id']= $venta->id;
            VentaSesion::create($params_det);
            usleep(500000);
        }

        $venta = Venta::with('sucursal','ventaDetalle.producto','ventaDetalle.tratamiento','ventaDetalle.vale')
        ->selectRaw("
        *,
        date_format(ventas.fecha_registro,'%d-%m-%Y %l %p') fecha_asignada_custom
        ")
        ->where(['id'=>$venta->id])->first();

        if ($request->limpiar_tienda=='si') {
            $user_id = 0;
            if($request->limpiar_tienda_personal=='si'){
                $user_id = $request->user()->id;
            } else {
                $user_id = $venta->cliente->user->id;
            }
            $tiendas = Tienda::where(['user_id'=>$user_id])->get();
            foreach ($tiendas as $key => $tienda) {
                $tienda->delete();
                usleep(500000);
            }
        }

        return response()->json([
            'data' => $venta,
        ], JsonResponse::HTTP_OK);
    }


    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Venta $venta): JsonResponse
    {
        $venta = Venta::with('cliente','sucursal','ventaDetalle.producto','ventaDetalle.tratamiento','ventaDetalle.vale','direccion','datosFiscales','envio','direccion', 'opcionPagoTransferencia')
        ->selectRaw("
            *,
            date_format(ventas.fecha_registro,'%d-%m-%Y %l %p') fecha_asignada_custom
        ")
        ->where(['ventas.id'=>$venta->id])->first();
        return response()->json([
            'data' => $venta,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function canledado(Request $request, Venta $venta): JsonResponse
    {
        $request->validate([
            'observacion_cancelado' => ['required'],
        ],
        [
            'observacion_cancelado.required'=>'El campo Observación es obligatorio'
        ]);

        foreach ($venta->ventaDetalle as $key => $value) {
            if($value->producto_id){
                $model_inventario=Inventario::where(['sucursal_id'=>$venta->sucursal_id,'producto_id'=>$value->producto_id])->first();

                if($model_inventario){
                    $cantidad=$model_inventario->cantidad_existente+$value->cantidad;
                    $model_inventario->update([
                        'cantidad_existente' => $cantidad
                    ]);
                } else {
                    Inventario::create([
                        'sucursal_id'=>$venta->sucursal_id,
                        'producto_id'=>$value->producto_id,
                        'cantidad_existente'=>$value->cantidad,
                        'cantidad_vendido'=>0,
                    ]);
                }
            } else if($value->vale_id){
                $fecha_actual = date("Y-m-d").' 01:00:00';
                $fecha_inicio = date("Y-m-d", strtotime($fecha_actual . "- 12 days")) . ' 00:00:00';
                $value->vale->update([
                    'vigencia'=>$fecha_inicio,
                    'estatus'=>'inactivo',
                ]);
            }
        }

        $venta->update([
            'observacion_cancelado'=>$request->observacion_cancelado,
            'cancelado'=>'si',
        ]);



        return response()->json([
            'data' => $venta,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Venta $venta): JsonResponse
    {
        $venta->delete();
        // return $venta;

        return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
    }

    public function paginacion(Request $request): JsonResponse
    {
        $producto=Venta::with('vale')
        ->leftjoin('sucursales', 'sucursales.id', '=', 'ventas.sucursal_id')
        ->leftjoin('clientes', 'clientes.id', '=', 'ventas.cliente_id')
        ->leftjoin('ventas_cortes', 'ventas_cortes.venta_id', '=', 'ventas.id')
        ->selectRaw("
            ventas.*,
            sucursales.nombre sucursal,
            clientes.razonSocial cliente,
            date_format(ventas.fecha_registro,'%d-%m-%Y %l %p') fecha_asignada_custom,
            (
                case
                    when isnull(ventas_cortes.venta_id) and cancelado='no' then 'si'
                    else 'no'
                end
            ) puede_cancelar
        ")
        ->when($request->sucursal_id,function (Builder $builder) use ($request) {
            $builder->Where(['sucursales.id'=>$request->sucursal_id]);
        })
        ->when($request->search,function (Builder $builder) use ($request) {
            $builder->orWhere('ventas.id', 'like', "%{$request->search}%")
            ->orWhereRaw("DATE_FORMAT(ventas.fecha_registro, '%Y-%m-%d') LIKE ?", ["%{$request->search}%"])
            ->orWhereRaw("DATE_FORMAT(ventas.fecha_registro, '%d-%m-%Y') LIKE ?", ["%{$request->search}%"])
            ->orWhere("clientes.razonSocial", 'like', "%{$request->search}%")
            ->orWhere("sucursales.nombre", 'like', "%{$request->search}%");
        })
        ->where(['ventas.estatus'=>'activo'])
        ->where('ventas.es_pago_tienda','si')
        ->orderBy('updated_at','DESC')
        ->paginate($request->perPage);
        return response()->json([
            'data' =>$producto,
        ], JsonResponse::HTTP_OK);
    }

    public function paginacionTiendaVerificar(Request $request): JsonResponse
    {
        $producto=Venta::with('vale')
        ->leftjoin('sucursales', 'sucursales.id', '=', 'ventas.sucursal_id')
        ->leftjoin('clientes', 'clientes.id', '=', 'ventas.cliente_id')
        ->leftjoin('ventas_cortes', 'ventas_cortes.venta_id', '=', 'ventas.id')
        ->selectRaw("
            ventas.*,
            sucursales.nombre sucursal,
            clientes.razonSocial cliente,
            date_format(ventas.fecha_registro,'%d-%m-%Y %l %p') fecha_asignada_custom,
            (
                case
                    when isnull(ventas_cortes.venta_id) and cancelado='no' then 'si'
                    else 'no'
                end
            ) puede_cancelar
        ")
        ->when($request->sucursal_id,function (Builder $builder) use ($request) {
            $builder->Where(['sucursales.id'=>$request->sucursal_id]);
        })
        ->when($request->search,function (Builder $builder) use ($request) {
            $builder->orWhere('ventas.id', 'like', "%{$request->search}%")
            ->orWhereRaw("DATE_FORMAT(ventas.fecha_registro, '%Y-%m-%d %l %p') LIKE ?", ["%{$request->search}%"])
            ->orWhereRaw("DATE_FORMAT(ventas.fecha_registro, '%d-%m-%Y %l %p') LIKE ?", ["%{$request->search}%"])
            ->orWhere("clientes.razonSocial", 'like', "%{$request->search}%")
            ->orWhere("sucursales.nombre", 'like', "%{$request->search}%");
        })
        ->where(['ventas.estatus'=>'activo'])
        ->where(['cancelado'=>'no'])
        ->where('ventas.es_pago_tienda','no')
        ->orderBy('updated_at','DESC')
        ->paginate($request->perPage);
        return response()->json([
            'data' =>$producto,
        ], JsonResponse::HTTP_OK);
    }

    public function misVentas(Request $request): JsonResponse
    {
        $venta=Venta::with('direccion','datosFiscales')
        ->leftjoin('sucursales', 'sucursales.id', '=', 'ventas.sucursal_id')
        ->leftjoin('clientes', 'clientes.id', '=', 'ventas.cliente_id')
        ->selectRaw("
            ventas.*,
            sucursales.nombre sucursal,
            clientes.razonSocial cliente,
            date_format(ventas.fecha_registro,'%d-%m-%Y %l %p') fecha_asignada_custom,
            'si' puede_cancelar
        ")
        ->when($request->sucursal_id,function (Builder $builder) use ($request) {
            $builder->Where(['sucursales.id'=>$request->sucursal_id]);
        })
        ->where(['ventas.estatus'=>'activo','cliente_id'=>$request->user()->cliente_id,'cancelado'=>'no'])
        ->whereNotNull('ventas.cliente_id')
        ->orderBy('ventas.created_at','DESC')->get();
        return response()->json([
            'data' =>$venta,
        ], JsonResponse::HTTP_OK);
    }

    public function seedTicket(Request $request, Venta $venta): JsonResponse
    {
        try {
            // Validar que exista el ticket
            if (!$request->hasFile('ticket')) {
                return response()->json(['error' => 'Se requiere el archivo del ticket'], 400);
            }

            $ticket = $request->file('ticket');

            // Validar que el ticket sea una imagen válida
            $allowedExtensions = ['png', 'jpg', 'jpeg', 'gif'];
            if (!$ticket->isValid() || !in_array($ticket->getClientOriginalExtension(), $allowedExtensions)) {
                return response()->json(['error' => 'Archivo de ticket no válido'], 400);
            }

            // Guardar el ticket
            $pathTicket = $ticket->store('tickets', 'public');
            $pathVales = null;

            // Determinar el correo del destinatario usando la nueva configuración
            $correo = CorreoHelper::getCorreoDestino($venta->cliente->email ?? null);

            // Enviar el correo
            Mail::send([], [], function ($message) use ($pathTicket, $request, $correo, $allowedExtensions, $pathVales) {
                $message->to($correo)
                       ->subject('EGURROLA - Tu comprobante de compra')
                       ->html('<p>Adjuntamos tu comprobante de compra.</p>')
                       ->attach(storage_path("app/public/{$pathTicket}"), [
                           'as' => 'ticket.png',
                           'mime' => 'image/png'
                       ]);

                // Adjuntar vales solo si existe
                if ($request->hasFile('vales')) {
                    $vales = $request->file('vales');
                    if ($vales->isValid() && in_array($vales->getClientOriginalExtension(), $allowedExtensions)) {
                        $pathVales = $vales->store('vales', 'public');
                        $message->attach(storage_path("app/public/{$pathVales}"), [
                            'as' => 'vales.png',
                            'mime' => 'image/png'
                        ]);
                    }
                }
            });

            $response = [
                'message' => 'Ticket enviado correctamente',
                'ticket_url' => Storage::url($pathTicket)
            ];

            // Agregar URL de vales solo si se enviaron
            if ($request->hasFile('vales')) {
                $response['vales_url'] = Storage::url($pathVales);
            }

            return response()->json($response, JsonResponse::HTTP_OK);

        } catch (\Exception $e) {

            return response()->json([
                'error' => 'Error al enviar el correo',
                'details' => $e->getMessage()
            ], 500);
        }
    }

    public function autorizar(Request $request, Venta $venta): JsonResponse
    {
        $request->validate(
            [
                'es_pago_tienda' => ['required', 'in:si,no']
            ],
            [
                'es_pago_tienda.required' => 'El campo es obligatorio',
                'es_pago_tienda.in' => 'El campo debe ser si o no'
            ]
        );
        $venta->update([
            'es_pago_tienda' => $request->es_pago_tienda
        ]);
        foreach ($venta->ventaDetalle as $key => $value) {
            if($value->producto_id){
                $model_inventario=Inventario::where(['sucursal_id'=>$venta->sucursal_id,'producto_id'=>$value->producto_id])->first();

                if($model_inventario){
                    $cantidad=$model_inventario->cantidad_existente-$value->cantidad;
                    $model_inventario->update([
                        'cantidad_existente' => $cantidad
                    ]);
                } else {
                    Inventario::create([
                        'sucursal_id'=>$venta->sucursal_id,
                        'producto_id'=>$value->producto_id,
                        'cantidad_existente'=>$value->cantidad,
                        'cantidad_vendido'=>0,
                    ]);
                }
            }
        }

        if($venta->es_pago_tienda == 'si'){
            $correo_cliente = CorreoHelper::getCorreoDestino($venta->cliente->email ?? null);
            $venta= Venta::find($venta->id);
            Mail::to($correo_cliente)->send(new AvisoNuevoVentaConfirmacionCliente($venta));
        }

        return response()->json($venta, JsonResponse::HTTP_OK);
    }
}
