<?php

namespace App\Support;

/**
 * Mirrors detectCategory from bugets-smart-money/src/lib/categories.ts (keyword scoring).
 */
final class CategoryDetector
{
    /**
     * @return array<int, array{id: string, keywords: list<string>}>
     */
    private static function definitions(): array
    {
        return [
            ['id' => 'food', 'keywords' => ['restaurant', 'grocery', 'food', 'lunch', 'dinner', 'breakfast', 'mcdonald', 'burger', 'pizza', 'starbucks', 'coffee', 'cafe', 'bakery', 'sushi', 'taco', 'chipotle', 'subway', 'kfc', 'wendy', 'domino', 'uber eats', 'deliveroo', 'doordash', 'grubhub', 'lidl']],
            ['id' => 'transport', 'keywords' => ['uber', 'lyft', 'taxi', 'gas', 'fuel', 'petrol', 'parking', 'toll', 'bus', 'train', 'metro', 'subway', 'bolt', 'lime', 'bird', 'car wash', 'mechanic', 'auto']],
            ['id' => 'entertainment', 'keywords' => ['netflix', 'disney', 'hbo', 'hulu', 'cinema', 'movie', 'theater', 'concert', 'event', 'ticket', 'youtube', 'twitch', 'prime video', 'apple tv', 'paramount']],
            ['id' => 'shopping', 'keywords' => ['amazon', 'ebay', 'shop', 'store', 'mall', 'clothing', 'shoes', 'zara', 'nike', 'adidas', 'ikea', 'walmart', 'target', 'costco', 'aliexpress', 'etsy']],
            ['id' => 'health', 'keywords' => ['gym', 'doctor', 'pharmacy', 'hospital', 'dentist', 'therapy', 'vitamin', 'supplement', 'yoga', 'peloton', 'fitbit', 'medicine', 'clinic', 'health']],
            ['id' => 'utilities', 'keywords' => ['electric', 'water', 'gas bill', 'utility', 'power', 'energy', 'sewage', 'waste', 'trash']],
            ['id' => 'housing', 'keywords' => ['rent', 'mortgage', 'housing', 'apartment', 'lease', 'property', 'maintenance', 'repair', 'plumber', 'electrician']],
            ['id' => 'income', 'keywords' => ['salary', 'payroll', 'freelance', 'consulting', 'dividend', 'interest', 'refund', 'reimbursement', 'bonus', 'commission', 'revenue', 'payment received', 'deposit', 'project']],
            ['id' => 'education', 'keywords' => ['school', 'university', 'course', 'udemy', 'coursera', 'book', 'tuition', 'training', 'skillshare', 'masterclass']],
            ['id' => 'travel', 'keywords' => ['flight', 'hotel', 'airbnb', 'booking', 'hostel', 'vacation', 'trip', 'travel', 'airline', 'expedia', 'kayak']],
            ['id' => 'gifts', 'keywords' => ['gift', 'donation', 'charity', 'present', 'tip', 'gofundme', 'birthday']],
            ['id' => 'phone', 'keywords' => ['phone', 'mobile', 'cell', 'verizon', 'at&t', 't-mobile', 'vodafone', 'internet', 'broadband', 'fiber', 'wifi']],
            ['id' => 'subscriptions', 'keywords' => ['subscription', 'membership', 'spotify', 'apple music', 'icloud', 'google one', 'dropbox', 'notion', 'figma', 'canva', 'adobe', 'microsoft 365', 'chatgpt', 'openai']],
            ['id' => 'fitness', 'keywords' => ['crossfit', 'swimming', 'tennis', 'football', 'sports', 'equipment']],
            ['id' => 'pets', 'keywords' => ['pet', 'vet', 'veterinary', 'dog', 'cat', 'animal', 'pet food', 'grooming']],
            ['id' => 'personal', 'keywords' => ['haircut', 'salon', 'barber', 'spa', 'beauty', 'cosmetic', 'skincare', 'nail']],
            ['id' => 'insurance', 'keywords' => ['insurance', 'premium', 'policy', 'coverage', 'life insurance', 'health insurance', 'car insurance']],
            ['id' => 'debt', 'keywords' => ['loan', 'debt', 'credit card', 'payment', 'interest', 'installment', 'bnpl', 'klarna', 'afterpay', 'affirm']],
            ['id' => 'savings', 'keywords' => ['savings', 'investment', 'stock', 'etf', 'crypto', 'bitcoin', 'portfolio', '401k', 'ira', 'pension']],
            ['id' => 'transfer', 'keywords' => ['transfer', 'sent', 'received', 'wire', 'zelle', 'venmo', 'paypal', 'wise', 'revolut']],
        ];
    }

    public static function detect(string $text): ?string
    {
        if (mb_strlen(trim($text)) < 2) {
            return null;
        }
        $lower = mb_strtolower(trim($text));
        $bestMatch = null;
        $bestScore = 0;

        foreach (self::definitions() as $cat) {
            foreach ($cat['keywords'] as $keyword) {
                $kw = mb_strtolower($keyword);
                if (! str_contains($lower, $kw) && ! str_contains($kw, $lower)) {
                    continue;
                }
                if ($kw === $lower) {
                    $score = 100;
                } elseif (str_contains($lower, $kw)) {
                    $score = mb_strlen($kw) * 2;
                } else {
                    $score = mb_strlen($kw);
                }
                if ($score > $bestScore) {
                    $bestScore = $score;
                    $bestMatch = $cat['id'];
                }
            }
        }

        return $bestMatch;
    }
}
