<?php
/**
 * Business Types repository for Local SEO schema.
 *
 * Provides schema.org LocalBusiness subtypes with hierarchical grouping.
 *
 * @package SEOvaultSEO\LocalSEO
 */

namespace SEOvaultSEO\LocalSEO;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class BusinessTypes {

	protected static $cache = null;

	public static function get_all() {
		if ( null !== self::$cache ) {
			return self::$cache;
		}

		self::$cache = array(
			'LocalBusiness' => array(
				'label'    => 'Local Business',
				'children' => array(
					'Store'                       => array(
						'label'    => 'Store',
						'children' => array(
							'AutoPartsStore'       => array( 'label' => 'Auto Parts Store' ),
							'BikeStore'            => array( 'label' => 'Bike Store' ),
							'BookStore'            => array( 'label' => 'Book Store' ),
							'ClothingStore'        => array( 'label' => 'Clothing Store' ),
							'ComputerStore'        => array( 'label' => 'Computer Store' ),
							'ConvenienceStore'     => array( 'label' => 'Convenience Store' ),
							'DepartmentStore'      => array( 'label' => 'Department Store' ),
							'ElectronicsStore'     => array( 'label' => 'Electronics Store' ),
							'Florist'              => array( 'label' => 'Florist' ),
							'FurnitureStore'       => array( 'label' => 'Furniture Store' ),
							'GardenStore'          => array( 'label' => 'Garden Store' ),
							'GroceryStore'         => array( 'label' => 'Grocery Store' ),
							'HardwareStore'        => array( 'label' => 'Hardware Store' ),
							'HobbyShop'            => array( 'label' => 'Hobby Shop' ),
							'HomeGoodsStore'       => array( 'label' => 'Home Goods Store' ),
							'JewelryStore'         => array( 'label' => 'Jewelry Store' ),
							'LiquorStore'          => array( 'label' => 'Liquor Store' ),
							'MensClothingStore'    => array( 'label' => "Men's Clothing Store" ),
							'MobilePhoneStore'     => array( 'label' => 'Mobile Phone Store' ),
							'MovieRentalStore'     => array( 'label' => 'Movie Rental Store' ),
							'MusicStore'           => array( 'label' => 'Music Store' ),
							'OfficeEquipmentStore' => array( 'label' => 'Office Equipment Store' ),
							'OutletStore'          => array( 'label' => 'Outlet Store' ),
							'PawnShop'             => array( 'label' => 'Pawn Shop' ),
							'PetStore'             => array( 'label' => 'Pet Store' ),
							'ShoeStore'            => array( 'label' => 'Shoe Store' ),
							'SportingGoodsStore'   => array( 'label' => 'Sporting Goods Store' ),
							'TireShop'             => array( 'label' => 'Tire Shop' ),
							'ToyStore'             => array( 'label' => 'Toy Store' ),
							'WholesaleStore'       => array( 'label' => 'Wholesale Store' ),
							'WomensClothingStore'  => array( 'label' => "Women's Clothing Store" ),
						),
					),
					'FoodEstablishment'           => array(
						'label'    => 'Food Establishment',
						'children' => array(
							'Bakery'             => array( 'label' => 'Bakery' ),
							'BarOrPub'           => array( 'label' => 'Bar or Pub' ),
							'Brewery'            => array( 'label' => 'Brewery' ),
							'CafeOrCoffeeShop'   => array( 'label' => 'Cafe or Coffee Shop' ),
							'FastFoodRestaurant' => array( 'label' => 'Fast Food Restaurant' ),
							'IceCreamShop'       => array( 'label' => 'Ice Cream Shop' ),
							'Restaurant'         => array( 'label' => 'Restaurant' ),
							'Winery'             => array( 'label' => 'Winery' ),
						),
					),
					'HealthAndBeautyBusiness'     => array(
						'label'    => 'Health and Beauty Business',
						'children' => array(
							'BeautySalon'  => array( 'label' => 'Beauty Salon' ),
							'DaySpa'       => array( 'label' => 'Day Spa' ),
							'HairSalon'    => array( 'label' => 'Hair Salon' ),
							'HealthClub'   => array( 'label' => 'Health Club' ),
							'NailSalon'    => array( 'label' => 'Nail Salon' ),
							'TattooParlor' => array( 'label' => 'Tattoo Parlor' ),
						),
					),
					'MedicalBusiness'             => array(
						'label'    => 'Medical Business',
						'children' => array(
							'Dentist'          => array( 'label' => 'Dentist' ),
							'Dermatology'      => array( 'label' => 'Dermatology' ),
							'DietNutrition'    => array( 'label' => 'Diet & Nutrition' ),
							'EmergencyService' => array( 'label' => 'Emergency Service' ),
							'GeneralPractice'  => array( 'label' => 'General Practice' ),
							'MedicalClinic'    => array( 'label' => 'Medical Clinic' ),
							'Optician'         => array( 'label' => 'Optician' ),
							'Pharmacy'         => array( 'label' => 'Pharmacy' ),
							'Physician'        => array( 'label' => 'Physician' ),
							'VeterinaryCare'   => array( 'label' => 'Veterinary Care' ),
						),
					),
					'HomeAndConstructionBusiness' => array(
						'label'    => 'Home and Construction Business',
						'children' => array(
							'Electrician'       => array( 'label' => 'Electrician' ),
							'GeneralContractor' => array( 'label' => 'General Contractor' ),
							'HousePainter'      => array( 'label' => 'House Painter' ),
							'Locksmith'         => array( 'label' => 'Locksmith' ),
							'MovingCompany'     => array( 'label' => 'Moving Company' ),
							'Plumber'           => array( 'label' => 'Plumber' ),
							'RoofingContractor' => array( 'label' => 'Roofing Contractor' ),
						),
					),
					'AutomotiveBusiness'          => array(
						'label'    => 'Automotive Business',
						'children' => array(
							'AutoBodyShop'     => array( 'label' => 'Auto Body Shop' ),
							'AutoDealer'       => array( 'label' => 'Auto Dealer' ),
							'AutoRental'       => array( 'label' => 'Auto Rental' ),
							'AutoRepair'       => array( 'label' => 'Auto Repair' ),
							'AutoWash'         => array( 'label' => 'Auto Wash' ),
							'GasStation'       => array( 'label' => 'Gas Station' ),
							'MotorcycleDealer' => array( 'label' => 'Motorcycle Dealer' ),
							'MotorcycleRepair' => array( 'label' => 'Motorcycle Repair' ),
						),
					),
					'LodgingBusiness'             => array(
						'label'    => 'Lodging Business',
						'children' => array(
							'BedAndBreakfast' => array( 'label' => 'Bed and Breakfast' ),
							'Hostel'          => array( 'label' => 'Hostel' ),
							'Hotel'           => array( 'label' => 'Hotel' ),
							'Motel'           => array( 'label' => 'Motel' ),
							'Resort'          => array( 'label' => 'Resort' ),
						),
					),
					'EntertainmentBusiness'       => array(
						'label'    => 'Entertainment Business',
						'children' => array(
							'AmusementPark'            => array( 'label' => 'Amusement Park' ),
							'ArtGallery'               => array( 'label' => 'Art Gallery' ),
							'Casino'                   => array( 'label' => 'Casino' ),
							'ComedyClub'               => array( 'label' => 'Comedy Club' ),
							'MovieTheater'             => array( 'label' => 'Movie Theater' ),
							'NightClub'                => array( 'label' => 'Night Club' ),
							'TouristAttraction'        => array( 'label' => 'Tourist Attraction' ),
							'TouristInformationCenter' => array( 'label' => 'Tourist Information Center' ),
						),
					),
					'EducationBusiness'           => array(
						'label'    => 'Education Business',
						'children' => array(
							'CollegeOrUniversity' => array( 'label' => 'College or University' ),
							'ElementarySchool'    => array( 'label' => 'Elementary School' ),
							'HighSchool'          => array( 'label' => 'High School' ),
							'MiddleSchool'        => array( 'label' => 'Middle School' ),
							'Preschool'           => array( 'label' => 'Preschool' ),
							'PrivateSchool'       => array( 'label' => 'Private School' ),
							'PublicSchool'        => array( 'label' => 'Public School' ),
							'School'              => array( 'label' => 'School' ),
						),
					),
					'FinancialService'            => array(
						'label'    => 'Financial Service',
						'children' => array(
							'AccountingService' => array( 'label' => 'Accounting Service' ),
							'AutomatedTeller'   => array( 'label' => 'Automated Teller' ),
							'BankOrCreditUnion' => array( 'label' => 'Bank or Credit Union' ),
							'InsuranceAgency'   => array( 'label' => 'Insurance Agency' ),
						),
					),
					'LegalService'                => array(
						'label'    => 'Legal Service',
						'children' => array(
							'Attorney' => array( 'label' => 'Attorney' ),
							'Notary'   => array( 'label' => 'Notary' ),
						),
					),
					'ProfessionalService'         => array(
						'label'    => 'Professional Service',
						'children' => array(
							'AccountingService'     => array( 'label' => 'Accounting Service' ),
							'ArchitecturalServices' => array( 'label' => 'Architectural Services' ),
							'EngineeringService'    => array( 'label' => 'Engineering Service' ),
							'LegalService'          => array( 'label' => 'Legal Service' ),
							'Notary'                => array( 'label' => 'Notary' ),
							'PrintingService'       => array( 'label' => 'Printing Service' ),
						),
					),
					'RealEstateAgent'             => array( 'label' => 'Real Estate Agent' ),
					'TravelAgency'                => array( 'label' => 'Travel Agency' ),
					'ChildCare'                   => array( 'label' => 'Child Care' ),
					'DryCleaningOrLaundry'        => array( 'label' => 'Dry Cleaning or Laundry' ),
					'EventVenue'                  => array( 'label' => 'Event Venue' ),
					'FitnessCenter'               => array( 'label' => 'Fitness Center' ),
					'InternetCafe'                => array( 'label' => 'Internet Cafe' ),
					'Library'                     => array( 'label' => 'Library' ),
					'Museum'                      => array( 'label' => 'Museum' ),
					'Park'                        => array( 'label' => 'Park' ),
					'PlaceOfWorship'              => array( 'label' => 'Place of Worship' ),
					'Playground'                  => array( 'label' => 'Playground' ),
					'RVPark'                      => array( 'label' => 'RV Park' ),
					'ShoppingCenter'              => array( 'label' => 'Shopping Center' ),
					'SportsActivityLocation'      => array( 'label' => 'Sports Activity Location' ),
					'StadiumOrArena'              => array( 'label' => 'Stadium or Arena' ),
					'TaxiService'                 => array( 'label' => 'Taxi Service' ),
					'TelevisionStation'           => array( 'label' => 'Television Station' ),
					'TouristAttraction'           => array( 'label' => 'Tourist Attraction' ),
					'Zoo'                         => array( 'label' => 'Zoo' ),
				),
			),
		);

		return self::$cache;
	}

	public static function flatten() {
		$types = self::get_all();
		$flat  = array();
		self::flatten_recursive( $types, '', $flat );
		return $flat;
	}

	protected static function flatten_recursive( $types, $parent, &$flat ) {
		foreach ( $types as $key => $data ) {
			$label    = $data['label'] ?? $key;
			$children = $data['children'] ?? array();

			if ( '' !== $parent ) {
				$flat[ $key ] = $parent . ' > ' . $label;
			} else {
				$flat[ $key ] = $label;
			}

			if ( ! empty( $children ) ) {
				self::flatten_recursive( $children, $flat[ $key ], $flat );
			}
		}
	}

	public static function is_valid( $type ) {
		if ( '' === $type || null === $type ) {
			return false;
		}
		$flat = self::flatten();
		return isset( $flat[ $type ] );
	}

	public static function is_child_of( $parent, $type ) {
		if ( $parent === $type ) {
			return true;
		}

		$types = self::get_all();
		$found = false;
		self::find_in_tree( $types, $parent, $type, $found );
		return $found;
	}

	protected static function find_in_tree( $types, $parent, $target, &$found ) {
		foreach ( $types as $key => $data ) {
			$children = $data['children'] ?? array();

			if ( $key === $parent ) {
				self::search_children( $children, $target, $found );
				return;
			}

			if ( ! empty( $children ) && ! $found ) {
				self::find_in_tree( $children, $parent, $target, $found );
			}
		}
	}

	protected static function search_children( $children, $target, &$found ) {
		foreach ( $children as $key => $data ) {
			if ( $key === $target ) {
				$found = true;
				return;
			}
			$sub = $data['children'] ?? array();
			if ( ! empty( $sub ) && ! $found ) {
				self::search_children( $sub, $target, $found );
			}
		}
	}
}
