import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:nearledaily/controllers/search_controller/product_match.dart';
import '../../modules/search/grocery_item.dart';

class GrocerySearchController extends ChangeNotifier {
  // ─── Controllers & Focus ──────────────────────────────────────────────────

  final TextEditingController textController = TextEditingController();
  final FocusNode focusNode = FocusNode();

  // ─── Animation ────────────────────────────────────────────────────────────

  late AnimationController cartBarController;
  late Animation<Offset> cartBarSlide;

  // ─── State ────────────────────────────────────────────────────────────────

  List<GroceryItem> items = [];
  List<GroceryItem> cartItems = [];
  bool loading = false;
  bool hasSearched = false;
  String lastQuery = '';

  // ─── API ──────────────────────────────────────────────────────────────────

  static const String _apiKey =
      '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';

  // ─── Quick Chips ──────────────────────────────────────────────────────────

  final List<Map<String, String>> quickChips = [
    {'label': '🍛 Biryani', 'query': 'Biryani'},
    {'label': '🍝 Pasta', 'query': 'Pasta'},
    {'label': '🎂 Cake', 'query': 'Cake'},
    {'label': '🥞 Pancakes', 'query': 'Pancakes'},
    {'label': '🫘 Dal Tadka', 'query': 'Dal Tadka'},
    {'label': '🥘 Idli Sambar', 'query': 'Idli Sambar'},
    {'label': '🍕 Pizza', 'query': 'Pizza'},
    {'label': '🍜 Noodles', 'query': 'Noodles'},
  ];

  final List<Map<String, String>> naturalChips = [
    {
      'label': '🤧 I have a cold — what should I eat?',
      'query': 'I have a cold, what fruits or foods should I eat?'
    },
    {
      'label': '💪 Post-workout nutrition',
      'query': 'Post-workout recovery foods and snacks'
    },
    {
      'label': '🍽️ Biryani + Curd Rice together',
      'query': 'I want to make biryani and also curd rice'
    },
    {
      'label': '🍳 Quick egg breakfast',
      'query': 'Quick breakfast with eggs and bread'
    },
  ];

  // ─── Init / Dispose ───────────────────────────────────────────────────────

  void init(TickerProvider vsync) {
    // Register StoreMatchController if not already registered
    if (!Get.isRegistered<StoreMatchController>()) {
      Get.put(StoreMatchController());
    }
    initAnimations(vsync);
  }

  void initAnimations(TickerProvider vsync) {
    cartBarController = AnimationController(
      vsync: vsync,
      duration: const Duration(milliseconds: 300),
    );
    cartBarSlide = Tween<Offset>(
      begin: const Offset(0, 1),
      end: Offset.zero,
    ).animate(CurvedAnimation(
      parent: cartBarController,
      curve: Curves.easeOutCubic,
    ));
  }

  void disposeAll() {
    textController.dispose();
    focusNode.dispose();
    cartBarController.dispose();
  }

  // ─── Search ───────────────────────────────────────────────────────────────

  Future<void> search(String query) async {
    final q = query.trim();
    if (q.isEmpty) return;

    focusNode.unfocus();
    loading = true;
    hasSearched = true;
    lastQuery = q;
    items = [];
    notifyListeners();

    try {
      final res = await http.post(
        Uri.parse('https://api.groq.com/openai/v1/chat/completions'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_apiKey',
        },
        body: jsonEncode({
          'model': 'llama-3.1-8b-instant',
          'max_tokens': 800,
          'messages': [
            {
              'role': 'system',
              'content': '''You are a smart product search engine for a super-app with grocery stores, restaurants, pharmacies, and general stores.

Your ONLY job is to return a raw JSON array. No markdown, no code fences, no explanations. Raw JSON only.

═══════════════════════════════════════════
GOLDEN RULE — LITERAL FIRST:
If the user types a RAW INGREDIENT, PRODUCT, or ITEM NAME (e.g. "tomato", "milk", "onion", "shampoo", "paracetamol"),
return THAT EXACT ITEM as a grocery/store product. Do NOT transform it into a dish or recipe.
═══════════════════════════════════════════

INTENT DETECTION — pick ONE mode:

MODE 1 — DIRECT PRODUCT SEARCH (user types a product/ingredient name):
  Signals: single word or short phrase that IS a product (e.g. "tomato", "milk", "bread", "eggs", "rice")
  Action: Return that exact product with 2–4 size/variant options only.
          Do NOT suggest dishes made from it.
  type: "grocery"
  Example — query "tomato":
  [
    {"name": "Tomato",        "quantity": "500g",  "emoji": "🍅", "type": "grocery"},
    {"name": "Tomato",        "quantity": "1 kg",  "emoji": "🍅", "type": "grocery"},
    {"name": "Cherry Tomato", "quantity": "250g",  "emoji": "🍅", "type": "grocery"}
  ]

MODE 2 — RESTAURANT ORDER (user wants a ready-made dish delivered):
  Signals: dish name WITH food-order context, or words like "order", "hungry", "eat",
           "food delivery", "i want to eat [dish]", "get me [dish]"
  Action: Return the dish as 1–3 variants.
  type: "restaurant"
  Example — query "i want biryani":
  [
    {"name": "Chicken Biryani", "quantity": "1 portion", "emoji": "🍛", "type": "restaurant"},
    {"name": "Veg Biryani",     "quantity": "1 portion", "emoji": "🍚", "type": "restaurant"}
  ]

MODE 3 — COOK AT HOME (user wants to cook):
  Signals: "cook", "recipe", "ingredients for", "how to make", "groceries for", "i will make"
  Action: Return grocery ingredient list (6–12 items).
  type: "grocery"

MODE 4 — SITUATION / NEED (health, mood, lifestyle):
  Signals: "sick", "fever", "diet", "weight loss", "party", "snacks", "breakfast", "workout"
  Action: Return 5–10 relevant products. Mix types if appropriate.

═══════════════════════════════════════════
STRICT ACCURACY RULES:
- A product name is a product — never auto-upgrade it to a dish
- Only return items the user actually needs — no upsells, no extras
- If query is ambiguous between product vs dish, choose MODE 1 (product)
- "tomato" → tomatoes, NOT tomato rice or tomato sauce
- "chicken" → raw chicken cuts, NOT chicken curry or chicken burger
- "lemon" → lemons, NOT lemon juice or lemon cake
═══════════════════════════════════════════

OUTPUT RULES:
- Raw JSON array only. Nothing else.
- Every item: exactly 4 keys — "name", "quantity", "emoji", "type"
- "type": only "restaurant" or "grocery"
- No duplicates. No nulls. No empty strings.
- Max 6 items total unless MODE 3 (ingredients list).''',
            },
            {'role': 'user', 'content': q},
          ],
        }),
      );

      if (res.statusCode != 200) {
        throw Exception('API error ${res.statusCode}: ${res.body}');
      }

      final data = jsonDecode(res.body) as Map<String, dynamic>;
      final content = data['choices'][0]['message']['content'] as String;

      final start = content.indexOf('[');
      final end = content.lastIndexOf(']') + 1;
      if (start == -1 || end == 0) {
        throw Exception('No JSON array found in response');
      }

      final List parsed =
      jsonDecode(content.substring(start, end)) as List;

      final newItems = parsed
          .asMap()
          .entries
          .map((e) =>
          GroceryItem.fromJson(e.key, e.value as Map<String, dynamic>))
          .toList();

      // Preserve cart state for already-added items
      for (final item in newItems) {
        if (cartItems.any((c) => c.name == item.name)) {
          item.inCart = true;
        }
      }

      items = newItems;

      // ── Trigger store matching ──────────────────────────────────────────
      if (items.isNotEmpty) {
        try {
          final storeCtrl = Get.find<StoreMatchController>();
          await storeCtrl.matchAiItems(items);
        } catch (e, st) {
          print('[StoreMatch] Error during matching: $e');
          print('  StackTrace: $st');
        }
      }

    } on FormatException catch (e) {
      print('[GrocerySearch] FormatException: $e');
    } on http.ClientException catch (e) {
      print('[GrocerySearch] Network error: $e');
    } catch (e, st) {
      print('[GrocerySearch] Unexpected error: $e');
      print('  StackTrace: $st');
    } finally {
      loading = false;
      notifyListeners();
    }
  }
  // ─── Cart ─────────────────────────────────────────────────────────────────

  void toggleCart(GroceryItem item) {
    HapticFeedback.lightImpact();
    if (item.inCart) {
      item.inCart = false;
      cartItems.removeWhere((c) => c.id == item.id && c.name == item.name);
    } else {
      item.inCart = true;
      cartItems.add(item);
    }
    cartItems.isNotEmpty
        ? cartBarController.forward()
        : cartBarController.reverse();
    notifyListeners();
  }

  void addAllToCart() {
    HapticFeedback.mediumImpact();
    for (final item in items) {
      if (!item.inCart) {
        item.inCart = true;
        cartItems.add(item);
      }
    }
    cartBarController.forward();
    notifyListeners();
  }

  bool get allInCart => items.isNotEmpty && items.every((i) => i.inCart);

  void removeFromCart(GroceryItem item) {
    item.inCart = false;
    cartItems.removeWhere((c) => c.id == item.id && c.name == item.name);
    if (cartItems.isEmpty) cartBarController.reverse();
    notifyListeners();
  }

  // ─── Helpers ──────────────────────────────────────────────────────────────

  void clearSearch() {
    textController.clear();
    hasSearched = false;
    items = [];
    lastQuery = '';
    focusNode.requestFocus();
    notifyListeners();
  }

  void fillSearch(String query) {
    textController.text = query;
    search(query);
  }
}