<?php

namespace App\Models;

use App\Core\Model;
use App\Core\Database;

class Order extends Model
{
    protected string $table = 'orders';
    protected string $primaryKey = 'order_id';

    public function createFromCart(int $userId, array $cartItems, array $orderData): ?array
    {
        $db = Database::getInstance();
        
        try {
            $db->beginTransaction();

            $subtotal = 0;
            foreach ($cartItems as $item) {
                $subtotal += $item['price'] * $item['quantity'];
            }

            $discountAmount = (float) ($orderData['discount'] ?? 0);
            $deliveryPrice = (float) ($orderData['delivery_price'] ?? 2000);
            $finalAmount = $subtotal - $discountAmount + $deliveryPrice;

            $orderNumber = 'ORD-' . date('Ymd-His') . '-' . rand(1000, 9999);

            $orderId = $this->create([
                'user_id' => $userId,
                'order_number' => $orderNumber,
                'customer_name' => $orderData['customer_name'],
                'customer_email' => $orderData['customer_email'],
                'customer_phone' => $orderData['customer_phone'],
                'delivery_address' => $orderData['delivery_address'],
                'delivery_region' => $orderData['delivery_region'] ?? null,
                'postal_code' => $orderData['postal_code'] ?? null,
                'delivery_method' => $orderData['delivery_method'] ?? 'courier',
                'payment_method' => $orderData['payment_method'] ?? 'card',
                'subtotal' => $subtotal,
                'discount_amount' => $discountAmount,
                'delivery_price' => $deliveryPrice,
                'final_amount' => $finalAmount,
                'promo_code' => $orderData['promo_code'] ?? null,
                'status' => 'pending',
                'notes' => $orderData['notes'] ?? null
            ]);

            if (!$orderId) {
                throw new \Exception('Не удалось создать заказ');
            }

            foreach ($cartItems as $item) {
                $this->addOrderItem($orderId, $item);
            }

            $productModel = new Product();
            foreach ($cartItems as $item) {
                $productModel->decreaseStock($item['product_id'], $item['quantity']);
            }

            $cartModel = new Cart();
            $cartModel->clearCart($userId);

            $db->commit();

            return [
                'order_id' => $orderId,
                'order_number' => $orderNumber,
                'final_amount' => $finalAmount
            ];

        } catch (\Exception $e) {
            $db->rollBack();
            throw $e;
        }
    }

    private function addOrderItem(int $orderId, array $item): void
    {
        $sql = "INSERT INTO order_items 
                (order_id, product_id, product_name, quantity, product_price, total_price)
                VALUES (?, ?, ?, ?, ?, ?)";
        
        $totalPrice = $item['price'] * $item['quantity'];
        
        $this->execute($sql, [
            $orderId,
            $item['product_id'],
            $item['name'],
            $item['quantity'],
            $item['price'],
            $totalPrice
        ]);
    }

    public function getWithDetails(int $orderId): ?array
    {
        $sql = "SELECT o.*, u.email as user_email, u.full_name as user_full_name
                FROM {$this->table} o
                LEFT JOIN users u ON o.user_id = u.user_id
                WHERE o.order_id = ?";
        
        $order = $this->queryOne($sql, [$orderId]);
        
        if ($order) {
            $order['items'] = $this->getOrderItems($orderId);
        }
        
        return $order;
    }

    public function getOrderItems(int $orderId): array
    {
        $sql = "SELECT oi.*, p.image_url
                FROM order_items oi
                LEFT JOIN products p ON oi.product_id = p.product_id
                WHERE oi.order_id = ?";
        return $this->query($sql, [$orderId]);
    }

    public function getUserOrders(int $userId, int $limit = 50): array
    {
        $sql = "SELECT * FROM {$this->table}
                WHERE user_id = ?
                ORDER BY created_at DESC
                LIMIT ?";
        return $this->query($sql, [$userId, $limit]);
    }

    public function getAllForAdmin(int $limit = 50): array
    {
        $sql = "SELECT o.*, u.email as user_email
                FROM {$this->table} o
                LEFT JOIN users u ON o.user_id = u.user_id
                ORDER BY o.created_at DESC
                LIMIT ?";
        return $this->query($sql, [$limit]);
    }

    public function updateStatus(int $orderId, string $status): bool
    {
        $updateData = [
            'status' => $status,
            'updated_at' => date('Y-m-d H:i:s')
        ];
        
        if ($status === 'completed') {
            $updateData['completed_at'] = date('Y-m-d H:i:s');
        }
        
        return $this->update($orderId, $updateData);
    }

    public function getStats(): array
    {
        $stats = [];
        
        $result = $this->queryOne("SELECT COUNT(*) as cnt FROM {$this->table}");
        $stats['total'] = (int) $result['cnt'];
        
        $result = $this->queryOne(
            "SELECT COALESCE(SUM(final_amount), 0) as revenue 
             FROM {$this->table} WHERE status = 'completed'"
        );
        $stats['revenue'] = (float) $result['revenue'];
        
        $statuses = $this->query(
            "SELECT status, COUNT(*) as cnt FROM {$this->table} GROUP BY status"
        );
        $stats['by_status'] = [];
        foreach ($statuses as $s) {
            $stats['by_status'][$s['status']] = (int) $s['cnt'];
        }
        
        return $stats;
    }
}
