<?php

declare(strict_types=1);

namespace CliqThemes\StoreLocator\Support;

defined('ABSPATH') || exit;

use CliqThemes\StoreLocator\Models\Category;
use CliqThemes\StoreLocator\Models\Store;
use CliqThemes\StoreLocator\Repository\CategoryRepository;
use CliqThemes\StoreLocator\Repository\StoreRepository;

/**
 * One-click demo content for onboarding. Each "vertical" is a self-contained
 * industry preset based in a DIFFERENT country (Pizza→India, Pharmacy→USA,
 * Restaurants→UK, Amusement Parks→Australia, Hotels→Canada, Coffee→Italy), so a
 * user can spin up a realistic 20-store locator in one click and see how it all
 * looks. Idempotent: stores with an existing slug are skipped.
 */
final class DemoData
{
    /**
     * Vertical presets: industry → { label, emoji, color, country, cities[],
     * name templates }. `cities` rows: [city, region, postal, lat, lng].
     *
     * @return array<string, array<string, mixed>>
     */
    private static function presets(): array
    {
        return [
            'pizza' => [
                'label' => __('Pizza Shops', 'cliq-store-locator'),
                'emoji' => '🍕',
                'color' => '#e4572e',
                'category' => __('Pizza', 'cliq-store-locator'),
                'country' => 'IN',
                'countryLabel' => __('India', 'cliq-store-locator'),
                'phoneCc' => '+91',
                'desc' => '%s is a neighbourhood pizzeria serving hand-stretched, wood-fired pizzas with a desi twist — tandoori paneer, butter-chicken, and classic Margherita on a crisp thin crust.',
                'names' => ['Pizza Adda', 'Tandoori Crust', 'Slice of {city}', 'Masala Pizza Co.', 'The Crust Company', 'Namaste Pizzeria', 'Curry Leaf Pizza', '{city} Brick Oven', 'Tikka & Crust', 'Wood Fired {city}'],
                'cities' => [
                    ['Mumbai', 'MH', '400001', 19.0760, 72.8777], ['New Delhi', 'DL', '110001', 28.6139, 77.2090],
                    ['Bengaluru', 'KA', '560001', 12.9716, 77.5946], ['Pune', 'MH', '411001', 18.5204, 73.8567],
                    ['Jaipur', 'RJ', '302001', 26.9124, 75.7873], ['Chennai', 'TN', '600001', 13.0827, 80.2707],
                    ['Hyderabad', 'TS', '500001', 17.3850, 78.4867], ['Coimbatore', 'TN', '641001', 11.0168, 76.9558],
                    ['Amritsar', 'PB', '143001', 31.6340, 74.8723], ['Panaji', 'GA', '403001', 15.4909, 73.8278],
                    ['Lucknow', 'UP', '226001', 26.8467, 80.9462], ['Kochi', 'KL', '682001', 9.9312, 76.2673],
                    ['Kolkata', 'WB', '700001', 22.5726, 88.3639], ['Ahmedabad', 'GJ', '380001', 23.0225, 72.5714],
                    ['Chandigarh', 'CH', '160001', 30.7333, 76.7794], ['Indore', 'MP', '452001', 22.7196, 75.8577],
                    ['Surat', 'GJ', '395001', 21.1702, 72.8311], ['Nagpur', 'MH', '440001', 21.1458, 79.0882],
                    ['Bhopal', 'MP', '462001', 23.2599, 77.4126], ['Visakhapatnam', 'AP', '530001', 17.6868, 83.2185],
                ],
            ],
            'pharmacy' => [
                'label' => __('Pharmacies', 'cliq-store-locator'),
                'emoji' => '💊',
                'color' => '#16a34a',
                'category' => __('Pharmacy', 'cliq-store-locator'),
                'country' => 'US',
                'countryLabel' => __('United States', 'cliq-store-locator'),
                'phoneCc' => '+1',
                'desc' => '%s is a full-service community pharmacy offering prescriptions, vaccinations, and round-the-clock health advice from licensed pharmacists.',
                'names' => ['{city} Pharmacy', 'MediPlus {city}', 'CarePoint {city}', '{city} Drugstore', 'HealthFirst {city}'],
                'cities' => [
                    ['New York', 'NY', '10001', 40.7128, -74.0060], ['Los Angeles', 'CA', '90001', 34.0522, -118.2437],
                    ['Chicago', 'IL', '60601', 41.8781, -87.6298], ['Houston', 'TX', '77001', 29.7604, -95.3698],
                    ['Phoenix', 'AZ', '85001', 33.4484, -112.0740], ['Philadelphia', 'PA', '19101', 39.9526, -75.1652],
                    ['San Diego', 'CA', '92101', 32.7157, -117.1611], ['Dallas', 'TX', '75201', 32.7767, -96.7970],
                    ['San Jose', 'CA', '95101', 37.3382, -121.8863], ['Austin', 'TX', '73301', 30.2672, -97.7431],
                    ['Boston', 'MA', '02108', 42.3601, -71.0589], ['Seattle', 'WA', '98101', 47.6062, -122.3321],
                    ['Denver', 'CO', '80201', 39.7392, -104.9903], ['Miami', 'FL', '33101', 25.7617, -80.1918],
                    ['Atlanta', 'GA', '30301', 33.7490, -84.3880], ['Portland', 'OR', '97201', 45.5152, -122.6784],
                    ['Las Vegas', 'NV', '88901', 36.1699, -115.1398], ['Minneapolis', 'MN', '55401', 44.9778, -93.2650],
                    ['Nashville', 'TN', '37201', 36.1627, -86.7816], ['Washington', 'DC', '20001', 38.9072, -77.0369],
                ],
            ],
            'restaurant' => [
                'label' => __('Restaurants', 'cliq-store-locator'),
                'emoji' => '🍽️',
                'color' => '#d97706',
                'category' => __('Restaurant', 'cliq-store-locator'),
                'country' => 'GB',
                'countryLabel' => __('United Kingdom', 'cliq-store-locator'),
                'phoneCc' => '+44',
                'desc' => '%s is a much-loved local restaurant pairing seasonal British produce with a warm, relaxed dining room and an award-winning wine list.',
                'names' => ['The {city} Kitchen', '{city} Bistro', 'Taste of {city}', '{city} Brasserie', 'The {city} Table'],
                'cities' => [
                    ['London', 'England', 'EC1A', 51.5074, -0.1278], ['Manchester', 'England', 'M1', 53.4808, -2.2426],
                    ['Birmingham', 'England', 'B1', 52.4862, -1.8904], ['Leeds', 'England', 'LS1', 53.8008, -1.5491],
                    ['Glasgow', 'Scotland', 'G1', 55.8642, -4.2518], ['Liverpool', 'England', 'L1', 53.4084, -2.9916],
                    ['Edinburgh', 'Scotland', 'EH1', 55.9533, -3.1883], ['Bristol', 'England', 'BS1', 51.4545, -2.5879],
                    ['Sheffield', 'England', 'S1', 53.3811, -1.4701], ['Cardiff', 'Wales', 'CF10', 51.4816, -3.1791],
                    ['Belfast', 'N. Ireland', 'BT1', 54.5973, -5.9301], ['Nottingham', 'England', 'NG1', 52.9548, -1.1581],
                    ['Newcastle', 'England', 'NE1', 54.9783, -1.6178], ['Brighton', 'England', 'BN1', 50.8225, -0.1372],
                    ['Cambridge', 'England', 'CB1', 52.2053, 0.1218], ['Oxford', 'England', 'OX1', 51.7520, -1.2577],
                    ['York', 'England', 'YO1', 53.9600, -1.0873], ['Bath', 'England', 'BA1', 51.3811, -2.3590],
                    ['Leicester', 'England', 'LE1', 52.6369, -1.1398], ['Southampton', 'England', 'SO14', 50.9097, -1.4044],
                ],
            ],
            'amusement' => [
                'label' => __('Amusement Parks', 'cliq-store-locator'),
                'emoji' => '🎢',
                'color' => '#7c3aed',
                'category' => __('Amusement Park', 'cliq-store-locator'),
                'country' => 'AU',
                'countryLabel' => __('Australia', 'cliq-store-locator'),
                'phoneCc' => '+61',
                'desc' => '%s is a thrill-packed amusement park with roller coasters, water rides, live shows and family attractions across acres of landscaped fun.',
                'names' => ['{city} Adventure Park', 'FunWorld {city}', '{city} Thrills', '{city} Wonderland', 'Splash {city}'],
                'cities' => [
                    ['Sydney', 'NSW', '2000', -33.8688, 151.2093], ['Melbourne', 'VIC', '3000', -37.8136, 144.9631],
                    ['Brisbane', 'QLD', '4000', -27.4698, 153.0251], ['Perth', 'WA', '6000', -31.9505, 115.8605],
                    ['Adelaide', 'SA', '5000', -34.9285, 138.6007], ['Gold Coast', 'QLD', '4217', -28.0167, 153.4000],
                    ['Canberra', 'ACT', '2600', -35.2809, 149.1300], ['Newcastle', 'NSW', '2300', -32.9283, 151.7817],
                    ['Wollongong', 'NSW', '2500', -34.4278, 150.8931], ['Hobart', 'TAS', '7000', -42.8821, 147.3272],
                    ['Geelong', 'VIC', '3220', -38.1499, 144.3617], ['Cairns', 'QLD', '4870', -16.9186, 145.7781],
                    ['Darwin', 'NT', '0800', -12.4634, 130.8456], ['Townsville', 'QLD', '4810', -19.2590, 146.8169],
                    ['Ballarat', 'VIC', '3350', -37.5622, 143.8503], ['Bendigo', 'VIC', '3550', -36.7570, 144.2794],
                    ['Launceston', 'TAS', '7250', -41.4332, 147.1441], ['Mackay', 'QLD', '4740', -21.1411, 149.1860],
                    ['Maroochydore', 'QLD', '4558', -26.6500, 153.0667], ['Toowoomba', 'QLD', '4350', -27.5598, 151.9507],
                ],
            ],
            'hotel' => [
                'label' => __('Hotels', 'cliq-store-locator'),
                'emoji' => '🏨',
                'color' => '#2563eb',
                'category' => __('Hotel', 'cliq-store-locator'),
                'country' => 'CA',
                'countryLabel' => __('Canada', 'cliq-store-locator'),
                'phoneCc' => '+1',
                'desc' => '%s is a four-star hotel in the heart of the city — spacious rooms, a rooftop bar, fitness centre and easy access to local landmarks.',
                'names' => ['Grand {city} Hotel', 'The {city} Suites', '{city} Plaza Hotel', 'Hotel {city} Central', 'The {city} Inn'],
                'cities' => [
                    ['Toronto', 'ON', 'M5H', 43.6532, -79.3832], ['Montreal', 'QC', 'H2Y', 45.5017, -73.5673],
                    ['Vancouver', 'BC', 'V6B', 49.2827, -123.1207], ['Calgary', 'AB', 'T2P', 51.0447, -114.0719],
                    ['Ottawa', 'ON', 'K1P', 45.4215, -75.6972], ['Edmonton', 'AB', 'T5J', 53.5461, -113.4938],
                    ['Quebec City', 'QC', 'G1R', 46.8139, -71.2080], ['Winnipeg', 'MB', 'R3C', 49.8951, -97.1384],
                    ['Hamilton', 'ON', 'L8P', 43.2557, -79.8711], ['Halifax', 'NS', 'B3J', 44.6488, -63.5752],
                    ['Victoria', 'BC', 'V8W', 48.4284, -123.3656], ['Saskatoon', 'SK', 'S7K', 52.1332, -106.6700],
                    ['Regina', 'SK', 'S4P', 50.4452, -104.6189], ["St John's", 'NL', 'A1C', 47.5615, -52.7126],
                    ['Kelowna', 'BC', 'V1Y', 49.8880, -119.4960], ['Windsor', 'ON', 'N9A', 42.3149, -83.0364],
                    ['Kingston', 'ON', 'K7L', 44.2312, -76.4860], ['Banff', 'AB', 'T1L', 51.1784, -115.5708],
                    ['Niagara Falls', 'ON', 'L2G', 43.0896, -79.0849], ['London', 'ON', 'N6A', 42.9849, -81.2453],
                ],
            ],
            'coffee' => [
                'label' => __('Coffee Shops', 'cliq-store-locator'),
                'emoji' => '☕',
                'color' => '#92400e',
                'category' => __('Coffee Shop', 'cliq-store-locator'),
                'country' => 'IT',
                'countryLabel' => __('Italy', 'cliq-store-locator'),
                'phoneCc' => '+39',
                'desc' => '%s is an artisan espresso bar roasting single-origin beans in-house and serving the city its morning cappuccino since day one.',
                'names' => ['{city} Coffee Co.', 'Brew {city}', 'Caffè {city}', '{city} Roasters', 'Bean {city}'],
                'cities' => [
                    ['Rome', 'Lazio', '00100', 41.9028, 12.4964], ['Milan', 'Lombardy', '20100', 45.4642, 9.1900],
                    ['Naples', 'Campania', '80100', 40.8518, 14.2681], ['Turin', 'Piedmont', '10100', 45.0703, 7.6869],
                    ['Florence', 'Tuscany', '50100', 43.7696, 11.2558], ['Venice', 'Veneto', '30100', 45.4408, 12.3155],
                    ['Bologna', 'Emilia-R.', '40100', 44.4949, 11.3426], ['Genoa', 'Liguria', '16100', 44.4056, 8.9463],
                    ['Palermo', 'Sicily', '90100', 38.1157, 13.3615], ['Verona', 'Veneto', '37100', 45.4384, 10.9916],
                    ['Pisa', 'Tuscany', '56100', 43.7228, 10.4017], ['Bari', 'Apulia', '70100', 41.1171, 16.8719],
                    ['Catania', 'Sicily', '95100', 37.5079, 15.0830], ['Padua', 'Veneto', '35100', 45.4064, 11.8768],
                    ['Siena', 'Tuscany', '53100', 43.3188, 11.3308], ['Como', 'Lombardy', '22100', 45.8081, 9.0852],
                    ['Rimini', 'Emilia-R.', '47900', 44.0678, 12.5695], ['Perugia', 'Umbria', '06100', 43.1107, 12.3908],
                    ['Lecce', 'Apulia', '73100', 40.3515, 18.1750], ['Trieste', 'F-VG', '34100', 45.6495, 13.7768],
                ],
            ],
        ];
    }

    /**
     * Wizard-facing list of verticals (no heavy store data).
     *
     * @return array<int, array<string, mixed>>
     */
    public static function verticals(): array
    {
        $out = [];
        foreach (self::presets() as $key => $p) {
            $out[] = [
                'key' => $key,
                'label' => $p['label'],
                'color' => $p['color'],
                'category' => $p['category'],
                'country' => $p['country'],
                'countryLabel' => $p['countryLabel'],
                'count' => count($p['cities']),
            ];
        }

        return $out;
    }

    /**
     * Seed a vertical: create (or reuse) its category and up to 20 stores across
     * the country's cities, each with a primary geocoded location, opening hours,
     * one shared bundled hero fallback and the category assigned. Idempotent by
     * slug. The hero remains a plugin asset and is never uploaded to Media.
     *
     * @return array{vertical:string,category:int,created:int,skipped:int,total:int}
     */
    public static function seed(string $key): array
    {
        $presets = self::presets();
        if (! isset($presets[$key])) {
            return ['vertical' => $key, 'category' => 0, 'created' => 0, 'skipped' => 0, 'total' => 0];
        }
        $p = $presets[$key];

        $categoryId = self::ensureCategory((string) $p['category'], (string) $p['color']);
        if ($categoryId <= 0) {
            throw new \RuntimeException('The demo category could not be created.');
        }
        $hours = self::defaultHours();
        $sharedMeta = [
            'opening_hours' => $hours,
            DemoHero::META_KEY => '1',
            'demo_type' => $key,
        ];

        $repo = new StoreRepository();
        $created = 0;
        $skipped = 0;

        foreach (array_values($p['cities']) as $i => $city) {
            [$cityName, $region, $postal, $lat, $lng] = $city;
            $template = $p['names'][$i % count($p['names'])];
            $name = str_replace('{city}', $cityName, $template);
            // The name list is shorter than the city list, so it cycles. A
            // template without a {city} placeholder therefore yields the SAME
            // name on its second lap, whose slug collides and gets skipped as a
            // duplicate — a 20-city vertical quietly seeded 13 stores. Qualify
            // the repeat with its city: cities are unique, so the pair is too.
            if (! str_contains($template, '{city}') && $i >= count($p['names'])) {
                $name .= ' ' . $cityName;
            }
            $slug = sanitize_title($name);
            $domain = preg_replace('/[^a-z0-9]/', '', strtolower($name));
            $phoneTail = str_pad((string) (1000000 + $i * 73 * 137), 7, '0', STR_PAD_LEFT);
            $featured = $i < 3;
            $rating = round(4.1 + (($i % 9) * 0.1), 1);
            $storeData = [
                'name' => $name,
                'slug' => $slug,
                'status' => 'active',
                'featured' => $featured ? 1 : 0,
                'rating' => $rating,
                'rating_count' => 18 + ($i * 7),
                'description' => sprintf((string) $p['desc'], $name),
                'phone' => $p['phoneCc'] . ' ' . substr($phoneTail, 0, 3) . ' ' . substr($phoneTail, 3),
                'email' => 'hello@' . substr($domain, 0, 24) . '.example',
                'website' => 'https://' . substr($domain, 0, 24) . '.example',
                'city' => $cityName,
                'country' => $p['country'],
                'categories' => [$categoryId],
                'locations' => [[
                    'label' => 'Main',
                    'address_line1' => ($i * 7 % 90 + 1) . ' ' . $cityName . ' High Street',
                    'city' => $cityName,
                    'state' => $region,
                    'postal_code' => $postal,
                    'country' => $p['country'],
                    'latitude' => $lat,
                    'longitude' => $lng,
                    'is_primary' => 1,
                    'hours' => $hours,
                ]],
                'meta' => array_merge($sharedMeta, [
                    'featured_store' => $featured ? '1' : '0',
                ]),
            ];

            $existing = Store::query()->where('slug', '=', $slug)->first();
            if ($existing) {
                DemoHero::detachDemoAssignment((int) $existing->getKey());
                $repo->update((int) $existing->getKey(), $storeData);
                $skipped++;
                continue;
            }

            $repo->create($storeData);
            $created++;
        }

        return [
            'vertical' => $key,
            'category' => $categoryId,
            'created' => $created,
            'skipped' => $skipped,
            'total' => (int) Store::query()->whereNull('source_id')->count(),
        ];
    }

    /** Find a category by name, or create it. Returns its id. */
    private static function ensureCategory(string $name, string $color): int
    {
        $slug = sanitize_title($name);
        $existing = Category::query()->where('slug', '=', $slug)->whereNull('source_id')->first();
        if ($existing) {
            return (int) $existing->getKey();
        }
        $cat = (new CategoryRepository())->create([
            'name' => $name,
            'slug' => $slug,
            'color' => $color,
            'is_active' => 1,
        ]);

        return (int) ($cat['id'] ?? 0);
    }

    /** Default opening hours (Mon–Fri 9–6, Sat 10–4, Sun closed) as the structured shape. */
    private static function defaultHours(): array
    {
        $weekday = ['closed' => false, 'open24' => false, 'slots' => [['from' => '09:00', 'to' => '18:00']]];
        return [
            'mon' => $weekday,
            'tue' => $weekday,
            'wed' => $weekday,
            'thu' => $weekday,
            'fri' => $weekday,
            'sat' => ['closed' => false, 'open24' => false, 'slots' => [['from' => '10:00', 'to' => '16:00']]],
            'sun' => ['closed' => true, 'open24' => false, 'slots' => []],
        ];
    }
}
