<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Coupon;
use App\Models\CouponUsage;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;

class CouponController extends Controller
{
    /**
     * Validar cupom antes de aplicar
     * POST /api/coupons/validate
     */
    public function validate(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'code' => 'required|string',
            'total' => 'required|numeric|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Dados inválidos',
                'errors' => $validator->errors()
            ], 422);
        }

        $coupon = Coupon::where('code', strtoupper($request->code))
            ->where('status', 'active')
            ->first();

        if (!$coupon) {
            return response()->json([
                'success' => false,
                'message' => 'Cupom inválido ou não encontrado'
            ], 404);
        }

        // Verificar validade (datas)
        $now = Carbon::now();
        if ($coupon->valid_from && $now->lt(Carbon::parse($coupon->valid_from))) {
            return response()->json([
                'success' => false,
                'message' => 'Este cupom ainda não está válido'
            ], 400);
        }

        if ($coupon->valid_until && $now->gt(Carbon::parse($coupon->valid_until))) {
            // Atualizar status para expirado
            $coupon->update(['status' => 'expired']);
            
            return response()->json([
                'success' => false,
                'message' => 'Este cupom expirou'
            ], 400);
        }

        // Verificar valor mínimo de compra
        if ($coupon->min_purchase && $request->total < $coupon->min_purchase) {
            return response()->json([
                'success' => false,
                'message' => "Valor mínimo de compra é MT " . number_format($coupon->min_purchase, 2, ',', '.')
            ], 400);
        }

        // Verificar limite total de usos
        if ($coupon->max_uses && $coupon->current_uses >= $coupon->max_uses) {
            return response()->json([
                'success' => false,
                'message' => 'Este cupom já atingiu o limite de usos'
            ], 400);
        }

        // Verificar usos por cliente (se autenticado)
        if (auth('sanctum')->check()) {
            $customerId = auth('sanctum')->id();
            $usageCount = CouponUsage::where('coupon_id', $coupon->id)
                ->where('customer_id', $customerId)
                ->count();
            
            if ($usageCount >= $coupon->max_uses_per_customer) {
                return response()->json([
                    'success' => false,
                    'message' => 'Você já usou este cupom o número máximo de vezes'
                ], 400);
            }
        }

        // Calcular desconto
        $discount = 0;
        if ($coupon->type === 'percentage') {
            $discount = ($request->total * $coupon->value) / 100;
            // Aplicar desconto máximo se existir
            if ($coupon->max_discount && $discount > $coupon->max_discount) {
                $discount = $coupon->max_discount;
            }
        } else {
            $discount = $coupon->value;
        }

        return response()->json([
            'success' => true,
            'message' => 'Cupom válido!',
            'data' => [
                'id' => $coupon->id,
                'code' => $coupon->code,
                'type' => $coupon->type,
                'value' => $coupon->value,
                'description' => $coupon->description,
                'min_purchase' => $coupon->min_purchase,
                'max_discount' => $coupon->max_discount,
                'discount_amount' => round($discount, 2),
            ]
        ]);
    }

    /**
     * Aplicar cupom (registrar uso)
     * POST /api/coupons/apply
     */
    public function apply(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'code' => 'required|string',
            'order_id' => 'nullable|exists:orders,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Dados inválidos',
                'errors' => $validator->errors()
            ], 422);
        }

        $coupon = Coupon::where('code', strtoupper($request->code))
            ->where('status', 'active')
            ->first();

        if (!$coupon) {
            return response()->json([
                'success' => false,
                'message' => 'Cupom inválido'
            ], 404);
        }

        // Se tiver order_id, registrar o uso
        if ($request->order_id && auth('sanctum')->check()) {
            CouponUsage::create([
                'coupon_id' => $coupon->id,
                'customer_id' => auth('sanctum')->id(),
                'order_id' => $request->order_id,
                'discount_amount' => $request->discount_amount ?? 0,
                'used_at' => now(),
            ]);

            // Incrementar contador de usos
            $coupon->increment('current_uses');
        }

        return response()->json([
            'success' => true,
            'message' => 'Cupom aplicado com sucesso!',
            'data' => $coupon
        ]);
    }

    /**
     * Listar cupons disponíveis (público)
     * GET /api/coupons/available
     */
    public function available()
    {
        $now = Carbon::now();

        $coupons = Coupon::where('status', 'active')
            ->where(function($query) use ($now) {
                $query->whereNull('valid_until')
                      ->orWhere('valid_until', '>=', $now);
            })
            ->where(function($query) use ($now) {
                $query->whereNull('valid_from')
                      ->orWhere('valid_from', '<=', $now);
            })
            ->where(function($query) {
                $query->whereNull('max_uses')
                      ->orWhereRaw('current_uses < max_uses');
            })
            ->orderBy('created_at', 'desc')
            ->get();

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

    /**
     * Listar todos os cupons (Admin)
     * GET /api/coupons
     */
    public function index(Request $request)
    {
        $query = Coupon::query();

        // Filtros
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        $coupons = $query->orderBy('created_at', 'desc')->get();

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

    /**
     * Criar novo cupom (Admin)
     * POST /api/coupons
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'code' => 'required|string|unique:coupons,code|max:50',
            'type' => 'required|in:percentage,fixed',
            'value' => 'required|numeric|min:0',
            'min_purchase' => 'nullable|numeric|min:0',
            'max_discount' => 'nullable|numeric|min:0',
            'valid_from' => 'nullable|date',
            'valid_until' => 'nullable|date|after_or_equal:valid_from',
            'max_uses' => 'nullable|integer|min:1',
            'max_uses_per_customer' => 'nullable|integer|min:1',
            'description' => 'nullable|string|max:255',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Dados inválidos',
                'errors' => $validator->errors()
            ], 422);
        }

        // Validar valor de percentual
        if ($request->type === 'percentage' && $request->value > 100) {
            return response()->json([
                'success' => false,
                'message' => 'Percentual não pode ser maior que 100%'
            ], 422);
        }

        $coupon = Coupon::create([
            'code' => strtoupper($request->code),
            'type' => $request->type,
            'value' => $request->value,
            'min_purchase' => $request->min_purchase,
            'max_discount' => $request->max_discount,
            'valid_from' => $request->valid_from,
            'valid_until' => $request->valid_until,
            'max_uses' => $request->max_uses,
            'max_uses_per_customer' => $request->max_uses_per_customer ?? 1,
            'description' => $request->description,
            'status' => 'active',
            'current_uses' => 0,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Cupom criado com sucesso!',
            'data' => $coupon
        ], 201);
    }

    /**
     * Atualizar cupom (Admin)
     * PUT /api/coupons/{id}
     */
    public function update(Request $request, $id)
    {
        $coupon = Coupon::find($id);

        if (!$coupon) {
            return response()->json([
                'success' => false,
                'message' => 'Cupom não encontrado'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'code' => 'sometimes|string|unique:coupons,code,'.$id.'|max:50',
            'type' => 'sometimes|in:percentage,fixed',
            'value' => 'sometimes|numeric|min:0',
            'min_purchase' => 'nullable|numeric|min:0',
            'max_discount' => 'nullable|numeric|min:0',
            'valid_from' => 'nullable|date',
            'valid_until' => 'nullable|date',
            'max_uses' => 'nullable|integer|min:1',
            'max_uses_per_customer' => 'nullable|integer|min:1',
            'description' => 'nullable|string|max:255',
            'status' => 'sometimes|in:active,inactive,expired',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Dados inválidos',
                'errors' => $validator->errors()
            ], 422);
        }

        $data = $request->only([
            'code', 'type', 'value', 'min_purchase', 'max_discount',
            'valid_from', 'valid_until', 'max_uses', 'max_uses_per_customer',
            'description', 'status'
        ]);

        if (isset($data['code'])) {
            $data['code'] = strtoupper($data['code']);
        }

        $coupon->update($data);

        return response()->json([
            'success' => true,
            'message' => 'Cupom atualizado com sucesso!',
            'data' => $coupon
        ]);
    }

    /**
     * Deletar cupom (Admin)
     * DELETE /api/coupons/{id}
     */
    public function destroy($id)
    {
        $coupon = Coupon::find($id);

        if (!$coupon) {
            return response()->json([
                'success' => false,
                'message' => 'Cupom não encontrado'
            ], 404);
        }

        // Verificar se o cupom foi usado
        $usageCount = CouponUsage::where('coupon_id', $coupon->id)->count();
        
        if ($usageCount > 0) {
            // Não deletar, apenas inativar
            $coupon->update(['status' => 'inactive']);
            
            return response()->json([
                'success' => true,
                'message' => 'Cupom inativado (não pode ser deletado pois já foi usado)'
            ]);
        }

        $coupon->delete();

        return response()->json([
            'success' => true,
            'message' => 'Cupom deletado com sucesso!'
        ]);
    }

    /**
     * Obter estatísticas de uso do cupom (Admin)
     * GET /api/coupons/{id}/stats
     */
    public function stats($id)
    {
        $coupon = Coupon::find($id);

        if (!$coupon) {
            return response()->json([
                'success' => false,
                'message' => 'Cupom não encontrado'
            ], 404);
        }

        $usage = CouponUsage::where('coupon_id', $coupon->id)->get();

        $stats = [
            'total_uses' => $usage->count(),
            'total_discount' => $usage->sum('discount_amount'),
            'unique_customers' => $usage->unique('customer_id')->count(),
            'recent_uses' => $usage->sortByDesc('used_at')->take(10)->values(),
        ];

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