<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;

class CustomerController extends Controller
{
    /**
     * List customers
     * GET /api/v1/customers
     */
    public function index(Request $request)
    {
        $query = Customer::query()
            ->withCount('orders')
            ->with('orders:id,customer_id,total_amount,created_at');

        // Search
        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('first_name', 'like', "%{$search}%")
                  ->orWhere('last_name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%");
            });
        }

        // Filter by segment
        if ($request->has('segment')) {
            switch ($request->segment) {
                case 'vip':
                    $query->vip();
                    break;
                case 'regular':
                    $query->regular();
                    break;
                case 'new':
                    $query->new();
                    break;
                case 'inactive':
                    $query->inactive();
                    break;
            }
        }

        // Filter by status
        if ($request->has('is_active')) {
            $query->where('is_active', $request->is_active === 'true' || $request->is_active === '1');
        }

        // Sorting
        $sortBy = $request->get('sort_by', 'created_at');
        $sortOrder = $request->get('sort_order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        // Pagination
        $perPage = $request->get('per_page', 20);
        $customers = $query->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $customers->items(),
            'pagination' => [
                'current_page' => $customers->currentPage(),
                'last_page' => $customers->lastPage(),
                'per_page' => $customers->perPage(),
                'total' => $customers->total(),
            ],
        ]);
    }

    /**
     * Get single customer
     * GET /api/v1/customers/{id}
     */
    public function show($id)
    {
        $customer = Customer::with([
            'orders.store',
            'orders.items.product'
        ])
            ->withCount('orders')
            ->findOrFail($id);

        // Calculate statistics
        $totalSpent = $customer->orders()->where('status', '!=', 'cancelled')->sum('total_amount');
        $averageOrderValue = $customer->orders()->where('status', '!=', 'cancelled')->avg('total_amount');
        $lastOrderDate = $customer->orders()->latest()->value('created_at');

        return response()->json([
            'success' => true,
            'data' => [
                'customer' => $customer,
                'stats' => [
                    'total_spent' => (float) $totalSpent,
                    'average_order_value' => (float) $averageOrderValue,
                    'last_order_date' => $lastOrderDate,
                ],
            ],
        ]);
    }

    /**
     * Create customer
     * POST /api/v1/customers
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'nullable|email|unique:customers,email',
            'phone' => 'required|string|unique:customers,phone|max:20',
            'birth_date' => 'nullable|date',
            'gender' => 'nullable|in:male,female,other',
            'address' => 'nullable|string',
            'city' => 'nullable|string|max:100',
            'state' => 'nullable|string|max:100',
            'postal_code' => 'nullable|string|max:20',
            'notes' => 'nullable|string',
        ]);

        $customer = Customer::create($validated);

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

    /**
     * Update customer
     * PUT /api/v1/customers/{id}
     */
    public function update(Request $request, $id)
    {
        $customer = Customer::findOrFail($id);

        $validated = $request->validate([
            'first_name' => 'sometimes|string|max:255',
            'last_name' => 'sometimes|string|max:255',
            'email' => 'nullable|email|unique:customers,email,' . $id,
            'phone' => 'sometimes|string|unique:customers,phone,' . $id . '|max:20',
            'birth_date' => 'nullable|date',
            'gender' => 'nullable|in:male,female,other',
            'address' => 'nullable|string',
            'city' => 'nullable|string|max:100',
            'state' => 'nullable|string|max:100',
            'postal_code' => 'nullable|string|max:20',
            'notes' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        $customer->update($validated);

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

    /**
     * Delete customer
     * DELETE /api/v1/customers/{id}
     */
    public function destroy($id)
    {
        $customer = Customer::findOrFail($id);

        // Check if customer has orders
        if ($customer->orders()->count() > 0) {
            return response()->json([
                'success' => false,
                'message' => 'Não é possível deletar cliente com pedidos',
            ], 400);
        }

        $customer->delete();

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

    /**
     * Get customer statistics
     * GET /api/v1/customers/stats
     */
    public function stats($id)
    {
        $customer = Customer::findOrFail($id);

        $ordersQuery = $customer->orders();

        $totalOrders   = (clone $ordersQuery)->count();
        $totalSpent    = (clone $ordersQuery)->where('status', '!=', 'cancelled')->sum('total_amount');
        $avgOrderValue = $totalOrders > 0 ? $totalSpent / $totalOrders : 0;

        $lastOrder = (clone $ordersQuery)
            ->latest('created_at')
            ->select('created_at', 'status', 'total_amount')
            ->first();

        $completedOrders  = (clone $ordersQuery)->where('status', 'delivered')->count();
        $pendingOrders    = (clone $ordersQuery)->whereIn('status', ['pending', 'confirmed', 'processing'])->count();
        $cancelledOrders  = (clone $ordersQuery)->where('status', 'cancelled')->count();

        return response()->json([
            'success' => true,
            'data' => [
                'total_orders'     => $totalOrders,
                'total_spent'      => (float) $totalSpent,
                'avg_order_value'  => (float) $avgOrderValue,
                'last_order_at'    => $lastOrder?->created_at?->toIso8601String(),
                'completed_orders' => $completedOrders,
                'pending_orders'   => $pendingOrders,
                'cancelled_orders' => $cancelledOrders,
            ],
        ]);
    }

    /**
     * Get customer segments analysis
     * GET /api/v1/customers/segments
     */
    public function segments()
    {
        $vip = Customer::vip()->count();
        $regular = Customer::regular()->count();
        $new = Customer::new()->count();
        $inactive = Customer::inactive()->count();

        return response()->json([
            'success' => true,
            'data' => [
                'segments' => [
                    [
                        'name' => 'VIP',
                        'count' => $vip,
                        'description' => 'Clientes com mais de 10 pedidos',
                    ],
                    [
                        'name' => 'Regular',
                        'count' => $regular,
                        'description' => 'Clientes com 1-10 pedidos',
                    ],
                    [
                        'name' => 'Novo',
                        'count' => $new,
                        'description' => 'Clientes sem pedidos',
                    ],
                    [
                        'name' => 'Inativo',
                        'count' => $inactive,
                        'description' => 'Sem compras nos últimos 6 meses',
                    ],
                ],
                'total' => $vip + $regular + $new + $inactive,
            ],
        ]);
    }

    /**
     * Get customer orders (CRM endpoint for admin viewing specific customer)
     * GET /api/crm/customers/{id}/orders
     */
    public function getCustomerOrders($id)
    {
        $customer = Customer::findOrFail($id);
        
        $orders = $customer->orders()
            ->with(['store', 'items.product'])
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        return response()->json([
            'success' => true,
            'data' => $orders->items(),
            'pagination' => [
                'current_page' => $orders->currentPage(),
                'last_page' => $orders->lastPage(),
                'per_page' => $orders->perPage(),
                'total' => $orders->total(),
            ],
        ]);
    }

    /**
     * Toggle customer status
     * POST /api/v1/customers/{id}/toggle-status
     */
    public function toggleStatus($id)
    {
        $customer = Customer::findOrFail($id);
        $customer->is_active = !$customer->is_active;
        $customer->save();

        return response()->json([
            'success' => true,
            'message' => 'Status do cliente atualizado',
            'data' => $customer,
        ]);
    }

    /**
     * Get top customers by revenue
     * GET /api/v1/customers/top
     */
    public function topCustomers(Request $request)
    {
        $limit = $request->get('limit', 10);

        $customers = Customer::select('customers.*')
            ->join('orders', 'customers.id', '=', 'orders.customer_id')
            ->where('orders.status', '!=', 'cancelled')
            ->selectRaw('SUM(orders.total_amount) as total_spent')
            ->selectRaw('COUNT(orders.id) as orders_count')
            ->groupBy('customers.id')
            ->orderByDesc('total_spent')
            ->limit($limit)
            ->get();

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

    // ========================================
    // MÉTODOS PARA CLIENTE AUTENTICADO
    // ========================================

    /**
     * Get authenticated customer orders (for logged in customer viewing their own orders)
     * GET /api/customer/orders
     */
    public function customerOrders(Request $request)
    {
        $user = $request->user();
        
        // Verificar se é um Customer
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado. Esta rota é apenas para clientes.',
            ], 403);
        }

        $orders = Order::where('customer_id', $user->id)
            ->with(['store', 'items.product', 'orderTracking', 'shippingAddress'])
            ->orderBy('created_at', 'desc')
            ->get();

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

    /**
     * Get authenticated customer order details
     * GET /api/customer/orders/{id}
     */
    public function orderDetails($id, Request $request)
    {
        $user = $request->user();
        
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado',
            ], 403);
        }

        try {
            $order = Order::where('customer_id', $user->id)
                ->where('id', $id)
                ->with(['store', 'items.product', 'orderTracking', 'shippingAddress'])
                ->firstOrFail();

            return response()->json([
                'success' => true,
                'data' => $order,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Erro ao buscar pedido: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get authenticated customer addresses
     * GET /api/customer/addresses
     */
    public function addresses(Request $request)
    {
        $user = $request->user();
        
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado',
            ], 403);
        }

        $addresses = DB::table('customer_addresses')
            ->where('customer_id', $user->id)
            ->orderBy('is_default', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();

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

    /**
     * Create customer address
     * POST /api/customer/addresses
     */
    public function createAddress(Request $request)
    {
        $user = $request->user();
        
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado',
            ], 403);
        }

        // ✅ VALIDAÇÃO ATUALIZADA - Campos NOVOS da tabela
        $validated = $request->validate([
            'label' => 'nullable|string|max:50',
            'address_line1' => 'required|string|max:255',
            'address_line2' => 'nullable|string|max:255',
            'city' => 'required|string|max:100',
            'state' => 'required|string|max:100',
            'zip_code' => 'nullable|string|max:20',
            'country' => 'nullable|string|max:100',
            'phone' => 'nullable|string|max:20',
            'is_default' => 'boolean',
        ]);

        // Se não tiver label, usar "Endereço" como padrão
        $label = $validated['label'] ?? 'Endereço';
        
        // Se não tiver country, usar Moçambique como padrão
        $country = $validated['country'] ?? 'Moçambique';

        // Se este é o endereço padrão, remover o padrão dos outros
        if ($request->is_default) {
            DB::table('customer_addresses')
                ->where('customer_id', $user->id)
                ->update(['is_default' => false]);
        }

        // Se é o primeiro endereço, marcar como padrão automaticamente
        $hasAddresses = DB::table('customer_addresses')
            ->where('customer_id', $user->id)
            ->exists();
        
        $isDefault = $hasAddresses ? ($validated['is_default'] ?? false) : true;

        // ✅ INSERÇÃO ATUALIZADA - Campos NOVOS
        $addressId = DB::table('customer_addresses')->insertGetId([
            'customer_id' => $user->id,
            'label' => $label,
            'address_line1' => $validated['address_line1'],
            'address_line2' => $validated['address_line2'] ?? null,
            'city' => $validated['city'],
            'state' => $validated['state'],
            'zip_code' => $validated['zip_code'] ?? null,
            'country' => $country,
            'phone' => $validated['phone'] ?? null,
            'is_default' => $isDefault,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $address = DB::table('customer_addresses')->where('id', $addressId)->first();

        return response()->json([
            'success' => true,
            'message' => 'Endereço criado com sucesso',
            'data' => $address,
        ], 201);
    }

    /**
     * Update customer address
     * PUT /api/customer/addresses/{id}
     */
    public function updateAddress(Request $request, $id)
    {
        $user = $request->user();
        
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado',
            ], 403);
        }

        // Verificar se o endereço pertence ao cliente
        $address = DB::table('customer_addresses')
            ->where('id', $id)
            ->where('customer_id', $user->id)
            ->first();

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

        // ✅ VALIDAÇÃO ATUALIZADA - Campos NOVOS da tabela
        $validated = $request->validate([
            'label' => 'sometimes|string|max:50',
            'address_line1' => 'sometimes|string|max:255',
            'address_line2' => 'nullable|string|max:255',
            'city' => 'sometimes|string|max:100',
            'state' => 'sometimes|string|max:100',
            'zip_code' => 'sometimes|string|max:20',
            'country' => 'sometimes|string|max:100',
            'phone' => 'sometimes|string|max:20',
            'is_default' => 'boolean',
        ]);

        // Se este é o endereço padrão, remover o padrão dos outros
        if (isset($validated['is_default']) && $validated['is_default']) {
            DB::table('customer_addresses')
                ->where('customer_id', $user->id)
                ->where('id', '!=', $id)
                ->update(['is_default' => false]);
        }

        $validated['updated_at'] = now();

        // ✅ UPDATE ATUALIZADO - Campos NOVOS
        DB::table('customer_addresses')
            ->where('id', $id)
            ->update($validated);

        $updatedAddress = DB::table('customer_addresses')->where('id', $id)->first();

        return response()->json([
            'success' => true,
            'message' => 'Endereço atualizado com sucesso',
            'data' => $updatedAddress,
        ]);
    }

    /**
     * Delete customer address
     * DELETE /api/customer/addresses/{id}
     */
    public function deleteAddress(Request $request, $id)
    {
        $user = $request->user();
        
        if (!($user instanceof Customer)) {
            return response()->json([
                'success' => false,
                'message' => 'Acesso não autorizado',
            ], 403);
        }

        // Verificar se o endereço pertence ao cliente
        $address = DB::table('customer_addresses')
            ->where('id', $id)
            ->where('customer_id', $user->id)
            ->first();

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

        DB::table('customer_addresses')->where('id', $id)->delete();

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

    /**
     * Add note to customer
     * POST /api/crm/customers/{id}/notes
     */
    public function addNote(Request $request, $id)
    {
        $customer = Customer::findOrFail($id);

        $validated = $request->validate([
            'note' => 'required|string',
        ]);

        $notes = $customer->notes ?? [];
        $notes[] = [
            'note' => $validated['note'],
            'created_by' => auth()->user()->name ?? 'System',
            'created_at' => now()->toDateTimeString(),
        ];

        $customer->notes = $notes;
        $customer->save();

        return response()->json([
            'success' => true,
            'message' => 'Nota adicionada com sucesso',
            'data' => $customer,
        ]);
    }

    /**
     * Get CRM tags
     * GET /api/crm/tags
     */
    public function tags()
    {
        $tags = [
            ['id' => 1, 'name' => 'VIP', 'color' => 'purple'],
            ['id' => 2, 'name' => 'Novo', 'color' => 'green'],
            ['id' => 3, 'name' => 'Inativo', 'color' => 'gray'],
            ['id' => 4, 'name' => 'Fidelizado', 'color' => 'blue'],
            ['id' => 5, 'name' => 'Risco', 'color' => 'red'],
        ];

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

    /**
     * Add tag to customer
     * POST /api/crm/customers/{id}/tags
     */
    public function addTag(Request $request, $id)
    {
        $customer = Customer::findOrFail($id);

        $validated = $request->validate([
            'tag_id' => 'required|integer',
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Tag adicionada com sucesso',
            'data' => $customer,
        ]);
    }
}