import type { NextApiRequest, NextApiResponse } from 'next';
import { createConnection } from 'mysql2/promise';
import { v4 as uuidv4 } from 'uuid';
import jwt from 'jsonwebtoken';
import { getToken } from 'next-auth/jwt';

interface CartItem {
  variantId: number;
  productId: number;
  productName: string;
  productSlug: string;
  brandName: string;
  volume: string;
  price: number;
  quantity: number;
  image: string;
  voucherId?: number;
  productType?: string;
  variantKind?: 'SAMPLE' | 'BOTTLE' | 'OTHER';
}

interface CartResponse {
  success: boolean;
  items?: CartItem[];
  cartId?: number;
  message?: string;
  error?: string;
}

async function createDatabaseConnection() {
  return await createConnection({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
  });
}

// Získá nebo vytvoří session ID pro neregistrované uživatele
function getSessionId(req: NextApiRequest, res: NextApiResponse): string {
  let sessionId = req.cookies['cart-session-id'];
  
  if (!sessionId) {
    sessionId = uuidv4();
    res.setHeader('Set-Cookie', `cart-session-id=${sessionId}; Path=/; Max-Age=31536000; HttpOnly`);
  }
  
  return sessionId;
}

async function getUserId(req: NextApiRequest): Promise<number | null> {
  const token = req.cookies.auth_token;
  const secret = process.env.JWT_SECRET;
  if (token && secret) {
    try {
      const decoded = jwt.verify(token, secret) as { id?: number };
      if (Number.isInteger(decoded.id)) return decoded.id!;
    } catch {
      // Pokračujeme kontrolou standardní NextAuth relace.
    }
  }

  try {
    const sessionToken = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
    const id = Number(sessionToken?.id);
    return Number.isInteger(id) && id > 0 ? id : null;
  } catch {
    return null;
  }
}

// Získá nebo vytvoří košík uživatele
async function getOrCreateCart(
  connection: any,
  sessionId: string,
  userId: number | null
): Promise<number> {
  // Zkusíme najít existující košík
  const [carts] = await connection.execute(
    'SELECT id FROM carts WHERE session_id = ?',
    [sessionId]
  );

  if ((carts as any[]).length > 0) {
    const cartId = (carts as any[])[0].id;
    if (userId) {
      await connection.execute(
        'UPDATE carts SET user_id = ? WHERE id = ? AND (user_id IS NULL OR user_id = ?)',
        [userId, cartId, userId]
      );
    }
    return cartId;
  }

  // Vytvoříme nový košík
  const [result] = await connection.execute(
    'INSERT INTO carts (user_id, session_id, created_at, updated_at) VALUES (?, ?, NOW(), NOW())',
    [userId, sessionId]
  );

  return (result as any).insertId;
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<CartResponse>
) {
  const sessionId = getSessionId(req, res);
  const userId = await getUserId(req);
  let connection: any = null;

  try {
    connection = await createDatabaseConnection();

    if (req.method === 'GET') {
      // Načtení košíku
      const cartId = await getOrCreateCart(connection, sessionId, userId);

      const [items] = await connection.execute(
        `SELECT ci.*, p.name as productName, p.slug as productSlug, b.name as brandName, pv.label as volume, pv.kind as variantKind, pr.price, img.url as image, pv.product_id, p.type as productType
         FROM cart_items ci
         LEFT JOIN product_variants pv ON ci.variant_id = pv.id
         LEFT JOIN products p ON pv.product_id = p.id
         LEFT JOIN brands b ON p.brand_id = b.id
         LEFT JOIN prices pr ON pr.variant_id = pv.id AND pr.valid_to IS NULL
         LEFT JOIN product_images img ON img.product_id = p.id AND img.is_primary = 1
         WHERE ci.cart_id = ?`,
        [cartId]
      );

      const cartItems: CartItem[] = (items as any[]).map(item => {
        const cartItem: CartItem = {
          variantId: item.variant_id,
          productId: item.product_id,
          productName: item.productName || '',
          productSlug: item.productSlug || '',
          brandName: item.brandName || '',
          volume: item.volume || '',
          price: parseFloat(item.price) || 0,
          quantity: item.quantity,
          image: item.image || '',
          productType: item.productType || 'perfume',
          variantKind: item.variantKind || 'SAMPLE',
        };

        if (item.voucher_id) {
          cartItem.voucherId = item.voucher_id;
        }

        return cartItem;
      });

      return res.status(200).json({
        success: true,
        items: cartItems,
        cartId,
      });
    } else if (req.method === 'POST') {
      // Přidání nebo aktualizace položky
      const { variantId, productId, quantity, voucherId } = req.body;
      if (!variantId || !productId) {
        return res.status(400).json({
          success: false,
          error: 'Chybí variantId nebo productId',
        });
      }

      // Ověřit, zda jde o bundle
      const [productType] = await connection.execute(
        `SELECT p.type as productType FROM products p WHERE p.id = ?`,
        [productId]
      );

      if ((productType as any[]).length === 0) {
        return res.status(404).json({
          success: false,
          error: 'Produkt nenalezen',
        });
      }

      const isBundle = (productType as any[])[0].productType === 'bundle';

      // Pokud je to bundle, kontrolovat stock produktů V bundlu
      if (isBundle) {
        const [bundleProducts] = await connection.execute(
          `SELECT selected_pv.volume_ml, selected_pv.kind, selected_pv.stock AS variant_stock, ps.stock AS sample_stock
           FROM bundles b
           JOIN bundle_items bi ON bi.bundle_id = b.id
           JOIN product_variants source_pv ON source_pv.id = bi.product_variant_id
           JOIN product_variants selected_pv
             ON selected_pv.product_id = source_pv.product_id
            AND selected_pv.volume_ml = (SELECT volume_ml FROM product_variants WHERE id = ?)
            AND selected_pv.is_active = 1
           LEFT JOIN product_stock ps ON ps.product_id = selected_pv.product_id
           WHERE b.product_id = ?`,
          [variantId, productId]
        );

        // Zkontrolovat, že všechny produkty v bundlu mají dostatek stocku
        for (const bundleProduct of (bundleProducts as any[])) {
          const isSample = (bundleProduct.kind || 'SAMPLE') === 'SAMPLE';
          const requiredMl = isSample ? (bundleProduct.volume_ml || 0) : 1;
          const availableMl = isSample ? (bundleProduct.sample_stock || 0) : (bundleProduct.variant_stock || 0);

          if (requiredMl > availableMl) {
            return res.status(409).json({
              success: false,
              error: `Nedostatek stocku pro produkt v sadě. Potřebujete ${requiredMl}ml, skladem je ${availableMl}ml`,
            });
          }
        }
      } else {
        // Normální produkt - kontrolovat stock varianty
        const [variantRows] = await connection.execute(
          `SELECT pv.volume_ml, pv.kind, pv.stock AS variant_stock, pv.is_active,
                  ps.stock AS sample_stock, p.type as productType
           FROM product_variants pv
           LEFT JOIN product_stock ps ON ps.product_id = ?
           LEFT JOIN products p ON p.id = pv.product_id
           WHERE pv.id = ?`,
          [productId, variantId]
        );

        if ((variantRows as any[]).length === 0) {
          return res.status(404).json({
            success: false,
            error: 'Varianta produktu nenalezena',
          });
        }

        const variant = (variantRows as any[])[0];
        const isVoucher = variant.productType === 'voucher';
        if (!variant.is_active) {
          return res.status(409).json({ success: false, error: 'Varianta už není dostupná.' });
        }
        const isSample = (variant.kind || 'SAMPLE') === 'SAMPLE';
        const requiredStock = isSample ? variant.volume_ml : 1;
        const availableStock = isSample ? (variant.sample_stock || 0) : (variant.variant_stock || 0);

        const cartId = await getOrCreateCart(connection, sessionId, userId);

        // Zjistíme, zda položka už v košíku je
        const [existing] = await connection.execute(
          'SELECT id, quantity FROM cart_items WHERE cart_id = ? AND variant_id = ?',
          [cartId, variantId]
        );

        let newQuantity = quantity || 1;

        if ((existing as any[]).length > 0) {
          // Již je v košíku - sčítáme s tím, co tam je
          const currentQuantity = (existing as any[])[0].quantity;
          newQuantity = (quantity || 1) + currentQuantity;
        }

        // Vypočítat CELKOVÝ stock používaný pro VŠECHNY varianty tohoto produktu v košíku
        // včetně aktualizované varianty - pouze pokud to není voucher
        if (!isVoucher) {
          const [allCartItems] = await connection.execute(
            `SELECT ci.variant_id, ci.quantity, pv.volume_ml, pv.kind
             FROM cart_items ci
             LEFT JOIN product_variants pv ON pv.id = ci.variant_id
             WHERE ci.cart_id = ? AND ci.product_id = ?`,
            [cartId, productId]
          );

          let totalUsedStock = 0;

          // Sečíst všechny varianty kromě aktuální (kterou později přidáme s newQuantity)
          for (const item of (allCartItems as any[])) {
            if (isSample && item.variant_id !== variantId && (item.kind || 'SAMPLE') === 'SAMPLE') {
              totalUsedStock += (item.quantity || 0) * (item.volume_ml || 0);
            }
          }

          // Přidat aktuální variantu s novým quantity
          totalUsedStock += newQuantity * requiredStock;

          // Zkontrolovat, zda celkový stock nepřekročí dostupný
          if (totalUsedStock > availableStock) {
            return res.status(409).json({
              success: false,
              error: `Nedostatek zásob.`,
            });
          }
        }
      }

      // Pro bundly i normální produkty - přidat do košíku
      const cartId = await getOrCreateCart(connection, sessionId, userId);

      // Zjistíme, zda položka už v košíku je
      const [existing] = await connection.execute(
        'SELECT id, quantity FROM cart_items WHERE cart_id = ? AND variant_id = ?',
        [cartId, variantId]
      );

      let newQuantity = quantity || 1;

      if ((existing as any[]).length > 0) {
        // Již je v košíku - sčítáme s tím, co tam je
        const currentQuantity = (existing as any[])[0].quantity;
        newQuantity = (quantity || 1) + currentQuantity;
      }

      if ((existing as any[]).length > 0) {
        // Aktualizujeme quantity
        await connection.execute(
          'UPDATE cart_items SET quantity = ?, updated_at = NOW() WHERE cart_id = ? AND variant_id = ?',
          [newQuantity, cartId, variantId]
        );
      } else {
        // Přidáme novou položku
        await connection.execute(
          `INSERT INTO cart_items (cart_id, product_id, variant_id, quantity, voucher_id, created_at, updated_at)
           VALUES (?, ?, ?, ?, ?, NOW(), NOW())`,
          [cartId, productId, variantId, newQuantity, voucherId || null]
        );
      }

      // Aktualizujeme updated_at na carts
      await connection.execute(
        'UPDATE carts SET updated_at = NOW() WHERE id = ?',
        [cartId]
      );

      return res.status(200).json({
        success: true,
        message: 'Položka přidána do košíku',
        cartId,
      });
    } else if (req.method === 'DELETE') {
      // Odebrání položky
      const { variantId } = req.body;

      if (!variantId) {
        return res.status(400).json({
          success: false,
          error: 'Chybí variantId',
        });
      }

      const cartId = await getOrCreateCart(connection, sessionId, userId);

      await connection.execute(
        'DELETE FROM cart_items WHERE cart_id = ? AND variant_id = ?',
        [cartId, variantId]
      );

      // Aktualizujeme updated_at na carts
      await connection.execute(
        'UPDATE carts SET updated_at = NOW() WHERE id = ?',
        [cartId]
      );

      return res.status(200).json({
        success: true,
        message: 'Položka odebrána z košíku',
      });
    } else if (req.method === 'PATCH') {
      // Aktualizace quantity
      const { variantId, quantity } = req.body;

      if (!variantId || quantity === undefined) {
        return res.status(400).json({
          success: false,
          error: 'Chybí variantId nebo quantity',
        });
      }

      const cartId = await getOrCreateCart(connection, sessionId, userId);

      if (quantity <= 0) {
        // Odstraníme položku pokud je quantity 0 nebo menší
        await connection.execute(
          'DELETE FROM cart_items WHERE cart_id = ? AND variant_id = ?',
          [cartId, variantId]
        );
      } else {
        // Ověřit stock produktu před aktualizací
        const [cartItem] = await connection.execute(
          `SELECT ci.product_id, p.type as productType
           FROM cart_items ci
           LEFT JOIN products p ON p.id = ci.product_id
           WHERE ci.cart_id = ? AND ci.variant_id = ?`,
          [cartId, variantId]
        );

        if ((cartItem as any[]).length === 0) {
          return res.status(404).json({
            success: false,
            error: 'Položka v košíku nenalezena',
          });
        }

        const productId = (cartItem as any[])[0].product_id;
        const isVoucher = (cartItem as any[])[0].productType === 'voucher';

        if (!isVoucher) {
          const [variantRows] = await connection.execute(
            `SELECT pv.volume_ml, pv.kind, pv.stock AS variant_stock,
                    ps.stock AS sample_stock
             FROM product_variants pv
             LEFT JOIN product_stock ps ON ps.product_id = ?
             WHERE pv.id = ?`,
            [productId, variantId]
          );

          if ((variantRows as any[]).length === 0) {
            return res.status(404).json({
              success: false,
              error: 'Varianta produktu nenalezena',
            });
          }

          const variant = (variantRows as any[])[0];
          const isSample = (variant.kind || 'SAMPLE') === 'SAMPLE';
          const requiredStock = isSample ? variant.volume_ml : 1;
          const availableStock = isSample ? (variant.sample_stock || 0) : (variant.variant_stock || 0);

          // Vypočítat CELKOVÝ stock používaný pro VŠECHNY varianty tohoto produktu v košíku
          // včetně aktualizované varianty
          const [allCartItems] = await connection.execute(
            `SELECT ci.variant_id, ci.quantity, pv.volume_ml, pv.kind
             FROM cart_items ci
             LEFT JOIN product_variants pv ON pv.id = ci.variant_id
             WHERE ci.cart_id = ? AND ci.product_id = ?`,
            [cartId, productId]
          );

          let totalUsedStock = 0;

          // Sečíst všechny varianty kromě aktuální (kterou později přidáme s novým quantity)
          for (const item of (allCartItems as any[])) {
            if (isSample && item.variant_id !== variantId && (item.kind || 'SAMPLE') === 'SAMPLE') {
              totalUsedStock += (item.quantity || 0) * (item.volume_ml || 0);
            }
          }

          // Přidat aktuální variantu s novým quantity
          totalUsedStock += quantity * requiredStock;

          // Zkontrolovat, zda celkový stock nepřekročí dostupný
          if (totalUsedStock > availableStock) {
            return res.status(409).json({
              success: false,
              error: `Nedostatek zásob.`,
            });
          }
        }

        // Aktualizujeme quantity
        await connection.execute(
          'UPDATE cart_items SET quantity = ?, updated_at = NOW() WHERE cart_id = ? AND variant_id = ?',
          [quantity, cartId, variantId]
        );
      }

      // Aktualizujeme updated_at na carts
      await connection.execute(
        'UPDATE carts SET updated_at = NOW() WHERE id = ?',
        [cartId]
      );

      return res.status(200).json({
        success: true,
        message: 'Množství aktualizováno',
      });
    } else {
      return res.status(405).json({
        success: false,
        error: 'Metoda není povolena',
      });
    }
  } catch (error) {
    return res.status(500).json({
      success: false,
      error: error instanceof Error ? error.message : 'Chyba serveru',
    });
  } finally {
    if (connection) {
      try {
        await connection.end();
      } catch (e) {
      }
    }
  }
}
