<?php

namespace Modules\Mobile\Controllers;

use Gestoreasy\Core\Http\Request;
use Gestoreasy\Core\Http\Response;
use Gestoreasy\Core\Tenant\ConnectionManager;
use Gestoreasy\Core\Tenant\TenantContext;

/**
 * Controller para API Mobile
 * Endpoints otimizados para força de vendas
 */
class MobileController {
    private function getTenantId(): string {
        return TenantContext::getTenantId();
    }

    /**
     * Lista produtos com suporte a sincronização incremental
     */
    public function getProducts(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            
            $lastSync = $req->query['last_sync'] ?? null;
            
            $sql = '
                SELECT 
                    id, codigo, nome, descricao, preco, estoque, unidade,
                    categoria, imagem_url, ativo, updated_at
                FROM products
                WHERE tenant_id = ?
            ';
            
            $params = [$tenantId];
            
            if ($lastSync) {
                $sql .= ' AND UNIX_TIMESTAMP(updated_at) > ?';
                $params[] = (int)$lastSync;
            }
            
            $sql .= ' ORDER BY updated_at DESC LIMIT 1000';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $products = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            // Converter updated_at para timestamp
            foreach ($products as &$product) {
                $product['last_sync'] = strtotime($product['updated_at']);
                unset($product['updated_at']);
            }
            
            return Response::json([
                'success' => true,
                'data' => $products
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista clientes com suporte a sincronização incremental
     */
    public function getClients(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            
            $lastSync = $req->query['last_sync'] ?? null;
            
            $sql = '
                SELECT 
                    id, nome, tipo, cpf_cnpj, email, telefone,
                    endereco, cidade, estado, cep, ativo, updated_at
                FROM clients
                WHERE tenant_id = ?
            ';
            
            $params = [$tenantId];
            
            if ($lastSync) {
                $sql .= ' AND UNIX_TIMESTAMP(updated_at) > ?';
                $params[] = (int)$lastSync;
            }
            
            $sql .= ' ORDER BY updated_at DESC LIMIT 1000';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $clients = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            // Converter updated_at para timestamp
            foreach ($clients as &$client) {
                $client['last_sync'] = strtotime($client['updated_at']);
                unset($client['updated_at']);
            }
            
            return Response::json([
                'success' => true,
                'data' => $clients
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista pedidos com suporte a sincronização incremental
     */
    public function getOrders(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            
            $lastSync = $req->query['last_sync'] ?? null;
            
            $sql = '
                SELECT 
                    id, client_id, numero, data, status,
                    subtotal, desconto, total, observacoes,
                    vendedor_id, created_at, updated_at
                FROM sales_orders
                WHERE tenant_id = ?
            ';
            
            $params = [$tenantId];
            
            if ($lastSync) {
                $sql .= ' AND UNIX_TIMESTAMP(updated_at) > ?';
                $params[] = (int)$lastSync;
            }
            
            $sql .= ' ORDER BY updated_at DESC LIMIT 500';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $orders = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            // Converter datas para timestamp
            foreach ($orders as &$order) {
                $order['data'] = strtotime($order['data']);
                $order['created_at'] = strtotime($order['created_at']);
                $order['updated_at'] = strtotime($order['updated_at']);
            }
            
            return Response::json([
                'success' => true,
                'data' => $orders
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista itens de um pedido específico
     */
    public function getOrderItems(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $orderId = (int)($req->get('params')[0] ?? 0);
            
            if (!$orderId) {
                return new Response(422, [
                    'success' => false,
                    'message' => 'ID do pedido é obrigatório'
                ]);
            }
            
            // Verificar se o pedido existe e pertence ao tenant
            $stmt = $pdo->prepare('SELECT id FROM sales_orders WHERE id = ? AND tenant_id = ? LIMIT 1');
            $stmt->execute([$orderId, $tenantId]);
            if (!$stmt->fetch()) {
                return new Response(404, [
                    'success' => false,
                    'message' => 'Pedido não encontrado'
                ]);
            }
            
            // Buscar itens do pedido
            // Nota: Backend usa sales_order_id, mas mapeamos para order_id no app
            $stmt = $pdo->prepare('
                SELECT 
                    id, sales_order_id as order_id, product_id, quantidade,
                    preco_unitario, desconto, total, created_at
                FROM sales_order_items
                WHERE sales_order_id = ? AND tenant_id = ?
                ORDER BY id ASC
            ');
            $stmt->execute([$orderId, $tenantId]);
            $items = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            // Converter created_at para timestamp
            foreach ($items as &$item) {
                $item['created_at'] = strtotime($item['created_at']);
            }
            
            return Response::json([
                'success' => true,
                'data' => $items
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Cria um novo pedido
     */
    public function createOrder(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $body = is_array($req->body) ? $req->body : [];
            
            $pdo->beginTransaction();
            
            // Criar pedido
            $stmt = $pdo->prepare('
                INSERT INTO sales_orders 
                (tenant_id, client_id, numero, data, status, subtotal, desconto, total, observacoes, vendedor_id)
                VALUES (?, ?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?)
            ');
            
            $numero = $body['numero'] ?? 'MOB-' . time();
            $data = $body['data'] ?? time();
            $status = $body['status'] ?? 'rascunho';
            
            $stmt->execute([
                $tenantId,
                $body['client_id'] ?? null,
                $numero,
                $data,
                $status,
                $body['subtotal'] ?? 0,
                $body['desconto'] ?? 0,
                $body['total'] ?? 0,
                $body['observacoes'] ?? null,
                $body['vendedor_id'] ?? null
            ]);
            
            $orderId = $pdo->lastInsertId();
            
            // Criar itens do pedido
            if (!empty($body['items'])) {
                $stmt = $pdo->prepare('
                    INSERT INTO sales_order_items
                    (tenant_id, sales_order_id, product_id, quantidade, preco_unitario, desconto, total)
                    VALUES (?, ?, ?, ?, ?, ?, ?)
                ');
                
                foreach ($body['items'] as $item) {
                    $stmt->execute([
                        $tenantId,
                        $orderId,
                        $item['product_id'] ?? null,
                        $item['quantidade'] ?? 0,
                        $item['preco_unitario'] ?? 0,
                        $item['desconto'] ?? 0,
                        $item['total'] ?? 0
                    ]);
                }
            }
            
            $pdo->commit();
            
            return Response::json([
                'success' => true,
                'data' => ['id' => $orderId, 'numero' => $numero]
            ], 201);
        } catch (\Exception $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Atualiza um pedido
     */
    public function updateOrder(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $orderId = (int)($req->get('params')[0] ?? 0);
            $body = is_array($req->body) ? $req->body : [];
            
            if (!$orderId) {
                return new Response(422, [
                    'success' => false,
                    'message' => 'ID do pedido é obrigatório'
                ]);
            }
            
            $allowedFields = ['status', 'observacoes', 'desconto', 'total'];
            $updates = [];
            $params = [];
            
            foreach ($allowedFields as $field) {
                if (isset($body[$field])) {
                    $updates[] = "{$field} = ?";
                    $params[] = $body[$field];
                }
            }
            
            if (empty($updates)) {
                return new Response(422, [
                    'success' => false,
                    'message' => 'Nenhum campo para atualizar'
                ]);
            }
            
            $params[] = $orderId;
            $params[] = $tenantId;
            
            $sql = 'UPDATE sales_orders SET ' . implode(', ', $updates) . ' WHERE id = ? AND tenant_id = ?';
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            
            return Response::json([
                'success' => true,
                'data' => ['id' => $orderId]
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Sincronização completa
     */
    public function syncAll(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $body = is_array($req->body) ? $req->body : [];
            
            $result = [
                'products_updated' => 0,
                'clients_updated' => 0,
                'orders_updated' => 0
            ];
            
            // Sincronizar produtos
            if (isset($body['last_sync_products'])) {
                $productsReq = new Request();
                $productsReq->query = ['last_sync' => $body['last_sync_products']];
                $productsResp = $this->getProducts($productsReq);
                $productsData = json_decode($productsResp->body, true);
                $result['products_updated'] = count($productsData['data'] ?? []);
            }
            
            // Sincronizar clientes
            if (isset($body['last_sync_clients'])) {
                $clientsReq = new Request();
                $clientsReq->query = ['last_sync' => $body['last_sync_clients']];
                $clientsResp = $this->getClients($clientsReq);
                $clientsData = json_decode($clientsResp->body, true);
                $result['clients_updated'] = count($clientsData['data'] ?? []);
            }
            
            // Sincronizar pedidos
            if (isset($body['last_sync_orders'])) {
                $ordersReq = new Request();
                $ordersReq->query = ['last_sync' => $body['last_sync_orders']];
                $ordersResp = $this->getOrders($ordersReq);
                $ordersData = json_decode($ordersResp->body, true);
                $result['orders_updated'] = count($ordersData['data'] ?? []);
            }
            
            return Response::json([
                'success' => true,
                'data' => $result
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista metas e objetivos
     */
    public function getGoals(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $vendedorId = $req->query['vendedor_id'] ?? null;
            
            $sql = '
                SELECT 
                    id, tipo, titulo, descricao, valor_meta, valor_atual,
                    periodo, UNIX_TIMESTAMP(data_inicio) as data_inicio,
                    UNIX_TIMESTAMP(data_fim) as data_fim, ativo
                FROM goals
                WHERE tenant_id = ? AND ativo = 1
            ';
            
            $params = [$tenantId];
            
            if ($vendedorId) {
                // Se houver filtro por vendedor no futuro
                // $sql .= ' AND vendedor_id = ?';
                // $params[] = $vendedorId;
            }
            
            $sql .= ' ORDER BY data_inicio DESC';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $goals = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            return Response::json([
                'success' => true,
                'data' => $goals
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista comissões do vendedor
     */
    public function getCommissions(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $vendedorId = $req->query['vendedor_id'] ?? null;
            $startDate = $req->query['start_date'] ?? null;
            $endDate = $req->query['end_date'] ?? null;
            
            if (!$vendedorId) {
                return new Response(422, [
                    'success' => false,
                    'message' => 'vendedor_id é obrigatório'
                ]);
            }
            
            $sql = '
                SELECT 
                    id, order_id, vendedor_id, valor_pedido, percentual_comissao,
                    valor_comissao, status, UNIX_TIMESTAMP(data_calculo) as data_calculo,
                    UNIX_TIMESTAMP(data_pagamento) as data_pagamento
                FROM commissions
                WHERE tenant_id = ? AND vendedor_id = ?
            ';
            
            $params = [$tenantId, $vendedorId];
            
            if ($startDate && $endDate) {
                $sql .= ' AND data_calculo >= FROM_UNIXTIME(?) AND data_calculo <= FROM_UNIXTIME(?)';
                $params[] = (int)$startDate;
                $params[] = (int)$endDate;
            }
            
            $sql .= ' ORDER BY data_calculo DESC';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $commissions = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            return Response::json([
                'success' => true,
                'data' => $commissions
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Resumo de comissões
     */
    public function getCommissionsSummary(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $vendedorId = $req->query['vendedor_id'] ?? null;
            
            if (!$vendedorId) {
                return new Response(422, [
                    'success' => false,
                    'message' => 'vendedor_id é obrigatório'
                ]);
            }
            
            $stmt = $pdo->prepare('
                SELECT 
                    COUNT(*) as total_pedidos,
                    SUM(valor_pedido) as total_vendas,
                    SUM(valor_comissao) as total_comissao,
                    SUM(CASE WHEN status = "paga" THEN valor_comissao ELSE 0 END) as comissao_paga,
                    SUM(CASE WHEN status = "pendente" THEN valor_comissao ELSE 0 END) as comissao_pendente
                FROM commissions
                WHERE tenant_id = ? AND vendedor_id = ?
            ');
            $stmt->execute([$tenantId, $vendedorId]);
            $summary = $stmt->fetch(\PDO::FETCH_ASSOC);
            
            return Response::json([
                'success' => true,
                'data' => $summary
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Cria um check-in/check-out
     */
    public function createCheckIn(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $body = is_array($req->body) ? $req->body : [];
            
            $stmt = $pdo->prepare('
                INSERT INTO checkins
                (tenant_id, client_id, tipo, latitude, longitude, accuracy, endereco, observacoes)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            ');
            
            $stmt->execute([
                $tenantId,
                $body['client_id'] ?? null,
                $body['tipo'] ?? 'checkin',
                $body['latitude'] ?? null,
                $body['longitude'] ?? null,
                $body['accuracy'] ?? null,
                $body['endereco'] ?? null,
                $body['observacoes'] ?? null
            ]);
            
            $checkInId = $pdo->lastInsertId();
            
            return Response::json([
                'success' => true,
                'data' => ['id' => $checkInId]
            ], 201);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Lista check-ins
     */
    public function getCheckIns(Request $req): Response {
        try {
            $tenantId = $this->getTenantId();
            $pdo = ConnectionManager::forTenant($tenantId);
            $clientId = $req->query['client_id'] ?? null;
            
            $sql = '
                SELECT 
                    id, client_id, tipo, latitude, longitude, accuracy,
                    endereco, observacoes, UNIX_TIMESTAMP(created_at) as created_at
                FROM checkins
                WHERE tenant_id = ?
            ';
            
            $params = [$tenantId];
            
            if ($clientId) {
                $sql .= ' AND client_id = ?';
                $params[] = $clientId;
            }
            
            $sql .= ' ORDER BY created_at DESC LIMIT 100';
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $checkIns = $stmt->fetchAll(\PDO::FETCH_ASSOC);
            
            return Response::json([
                'success' => true,
                'data' => $checkIns
            ]);
        } catch (\Exception $e) {
            return new Response(500, [
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }
}

