<template>
	<span
		class="v-icon"
		:class="[sizeClass, { 'has-click': !disabled && clickable, left, right }]"
		:role="clickable ? 'button' : null"
		:tabindex="clickable ? 0 : null"
		:style="{ '--v-icon-color': color }"
		@click="emitClick"
	>
		<component :is="customIconName" v-if="customIconName" />
		<socialIcon v-else-if="socialIconName" :name="socialIconName" />
		<i v-else :class="{ filled }" :data-icon="name"></i>
	</span>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue';
import { library } from '@fortawesome/fontawesome-svg-core';
import { fab } from '@fortawesome/free-brands-svg-icons';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';

import CustomIconDirectus from './custom-icons/directus.vue';
import CustomIconBookmarkSave from './custom-icons/bookmark_save.vue';
import CustomIconBox from './custom-icons/box.vue';
import CustomIconCommitNode from './custom-icons/commit_node.vue';
import CustomIconGrid1 from './custom-icons/grid_1.vue';
import CustomIconGrid2 from './custom-icons/grid_2.vue';
import CustomIconGrid3 from './custom-icons/grid_3.vue';
import CustomIconGrid4 from './custom-icons/grid_4.vue';
import CustomIconGrid5 from './custom-icons/grid_5.vue';
import CustomIconGrid6 from './custom-icons/grid_6.vue';
import CustomIconSignalWifi1Bar from './custom-icons/signal_wifi_1_bar.vue';
import CustomIconSignalWifi2Bar from './custom-icons/signal_wifi_2_bar.vue';
import CustomIconSignalWifi3Bar from './custom-icons/signal_wifi_3_bar.vue';
import CustomIconFlipHorizontal from './custom-icons/flip_horizontal.vue';
import CustomIconFlipVertical from './custom-icons/flip_vertical.vue';
import CustomIconFolderMove from './custom-icons/folder_move.vue';
import CustomIconFolderLock from './custom-icons/folder_lock.vue';
import CustomIconLogout from './custom-icons/logout.vue';

import SocialIcon from './social-icon.vue';

library.add(fab);

const customIcons: string[] = [
	'directus',
	'bookmark_save',
	'box',
	'commit_node',
	'grid_1',
	'grid_2',
	'grid_3',
	'grid_4',
	'grid_5',
	'grid_6',
	'signal_wifi_1_bar',
	'signal_wifi_2_bar',
	'signal_wifi_3_bar',
	'flip_horizontal',
	'flip_vertical',
	'folder_move',
	'folder_lock',
	'logout',
];

const socialIcons: string[] = [
	'500px',
	'accessible_icon',
	'accusoft',
	'acquisitions_incorporated',
	'adn',
	'adversal',
	'affiliatetheme',
	'airbnb',
	'algolia',
	'alipay',
	'amazon',
	'amazon_pay',
	'amilia',
	'android',
	'angellist',
	'angrycreative',
	'angular',
	'app_store',
	'app_store_ios',
	'apper',
	'apple',
	'apple_pay',
	'artstation',
	'asymmetrik',
	'atlassian',
	'audible',
	'autoprefixer',
	'avianex',
	'aviato',
	'aws',
	'bandcamp',
	'battle_net',
	'behance',
	'behance_square',
	'bimobject',
	'bitbucket',
	'bitcoin',
	'bity',
	'black_tie',
	'blackberry',
	'blogger',
	'blogger_b',
	'bluetooth',
	'bluetooth_b',
	'bootstrap',
	'btc',
	'buffer',
	'buromobelexperte',
	'buy_n_large',
	'buysellads',
	'canadian_maple_leaf',
	'cc_amazon_pay',
	'cc_amex',
	'cc_apple_pay',
	'cc_diners_club',
	'cc_discover',
	'cc_jcb',
	'cc_mastercard',
	'cc_paypal',
	'cc_stripe',
	'cc_visa',
	'centercode',
	'centos',
	'chrome',
	'chromecast',
	'cloudflare',
	'cloudscale',
	'cloudsmith',
	'cloudversify',
	'codepen',
	'codiepie',
	'confluence',
	'connectdevelop',
	'contao',
	'cotton_bureau',
	'cpanel',
	'creative_commons',
	'creative_commons_by',
	'creative_commons_nc',
	'creative_commons_nc_eu',
	'creative_commons_nc_jp',
	'creative_commons_nd',
	'creative_commons_pd',
	'creative_commons_pd_alt',
	'creative_commons_remix',
	'creative_commons_sa',
	'creative_commons_sampling',
	'creative_commons_sampling_plus',
	'creative_commons_share',
	'creative_commons_zero',
	'critical_role',
	'css3',
	'css3_alt',
	'cuttlefish',
	'd_and_d',
	'd_and_d_beyond',
	'dailymotion',
	'dashcube',
	'deezer',
	'delicious',
	'deploydog',
	'deskpro',
	'dev',
	'deviantart',
	'dhl',
	'diaspora',
	'digg',
	'digital_ocean',
	'discord',
	'discourse',
	'dochub',
	'docker',
	'draft2digital',
	'dribbble',
	'dribbble_square',
	'dropbox',
	'drupal',
	'dyalog',
	'earlybirds',
	'ebay',
	'edge',
	'edge_legacy',
	'elementor',
	'ello',
	'ember',
	'empire',
	'envira',
	'erlang',
	'ethereum',
	'etsy',
	'evernote',
	'expeditedssl',
	'facebook',
	'facebook_f',
	'facebook_messenger',
	'facebook_square',
	'fantasy_flight_games',
	'fedex',
	'fedora',
	'figma',
	'firefox',
	'firefox_browser',
	'first_order',
	'first_order_alt',
	'firstdraft',
	'flickr',
	'flipboard',
	'fly',
	'font_awesome',
	'font_awesome_alt',
	'font_awesome_flag',
	'fonticons',
	'fonticons_fi',
	'fort_awesome',
	'fort_awesome_alt',
	'forumbee',
	'foursquare',
	'free_code_camp',
	'freebsd',
	'fulcrum',
	'galactic_republic',
	'galactic_senate',
	'get_pocket',
	'gg',
	'gg_circle',
	'git',
	'git_alt',
	'git_square',
	'github',
	'github_alt',
	'github_square',
	'gitkraken',
	'gitlab',
	'gitter',
	'glide',
	'glide_g',
	'gofore',
	'goodreads',
	'goodreads_g',
	'google',
	'google_drive',
	'google_pay',
	'google_play',
	'google_plus',
	'google_plus_g',
	'google_plus_square',
	'google_wallet',
	'gratipay',
	'grav',
	'gripfire',
	'grunt',
	'guilded',
	'gulp',
	'hacker_news',
	'hacker_news_square',
	'hackerrank',
	'hips',
	'hire_a_helper',
	'hive',
	'hooli',
	'hornbill',
	'hotjar',
	'houzz',
	'html5',
	'hubspot',
	'ideal',
	'imdb',
	'innosoft',
	'instagram',
	'instagram_square',
	'instalod',
	'intercom',
	'internet_explorer',
	'invision',
	'ioxhost',
	'itch_io',
	'itunes',
	'itunes_note',
	'java',
	'jedi_order',
	'jenkins',
	'jira',
	'joget',
	'joomla',
	'js',
	'js_square',
	'jsfiddle',
	'kaggle',
	'keybase',
	'keycdn',
	'kickstarter',
	'kickstarter_k',
	'korvue',
	'laravel',
	'lastfm',
	'lastfm_square',
	'leanpub',
	'less',
	'line',
	'linkedin',
	'linkedin_in',
	'linode',
	'linux',
	'lyft',
	'magento',
	'mailchimp',
	'mandalorian',
	'markdown',
	'mastodon',
	'maxcdn',
	'mdb',
	'medapps',
	'medium',
	'medium_m',
	'medrt',
	'meetup',
	'megaport',
	'mendeley',
	'microblog',
	'microsoft',
	'mix',
	'mixcloud',
	'mixer',
	'mizuni',
	'modx',
	'monero',
	'napster',
	'neos',
	'nimblr',
	'node',
	'node_js',
	'npm',
	'ns8',
	'nutritionix',
	'octopus_deploy',
	'odnoklassniki',
	'odnoklassniki_square',
	'old_republic',
	'opencart',
	'openid',
	'opera',
	'optin_monster',
	'orcid',
	'osi',
	'page4',
	'pagelines',
	'palfed',
	'patreon',
	'paypal',
	'penny_arcade',
	'perbyte',
	'periscope',
	'phabricator',
	'phoenix_framework',
	'phoenix_squadron',
	'php',
	'pied_piper',
	'pied_piper_alt',
	'pied_piper_hat',
	'pied_piper_pp',
	'pied_piper_square',
	'pinterest',
	'pinterest_p',
	'pinterest_square',
	'playstation',
	'product_hunt',
	'pushed',
	'python',
	'qq',
	'quinscape',
	'quora',
	'r_project',
	'raspberry_pi',
	'ravelry',
	'react',
	'reacteurope',
	'readme',
	'rebel',
	'red_river',
	'reddit',
	'reddit_alien',
	'reddit_square',
	'redhat',
	'renren',
	'replyd',
	'researchgate',
	'resolving',
	'rev',
	'rocketchat',
	'rockrms',
	'rust',
	'safari',
	'salesforce',
	'sass',
	'schlix',
	'scribd',
	'searchengin',
	'sellcast',
	'sellsy',
	'servicestack',
	'shirtsinbulk',
	'shopify',
	'shopware',
	'simplybuilt',
	'sistrix',
	'sith',
	'sketch',
	'skyatlas',
	'skype',
	'slack',
	'slack_hash',
	'slideshare',
	'snapchat',
	'snapchat_ghost',
	'snapchat_square',
	'soundcloud',
	'sourcetree',
	'speakap',
	'speaker_deck',
	'spotify',
	'squarespace',
	'stack_exchange',
	'stack_overflow',
	'stackpath',
	'staylinked',
	'steam',
	'steam_square',
	'steam_symbol',
	'sticker_mule',
	'strava',
	'stripe',
	'stripe_s',
	'studiovinari',
	'stumbleupon',
	'stumbleupon_circle',
	'superpowers',
	'supple',
	'suse',
	'swift',
	'symfony',
	'teamspeak',
	'telegram',
	'telegram_plane',
	'tencent_weibo',
	'the_red_yeti',
	'themeco',
	'themeisle',
	'think_peaks',
	'tiktok',
	'trade_federation',
	'trello',
	'tumblr',
	'tumblr_square',
	'twitch',
	'twitter',
	'twitter_square',
	'typo3',
	'uber',
	'ubuntu',
	'uikit',
	'umbraco',
	'uncharted',
	'uniregistry',
	'unity',
	'unsplash',
	'untappd',
	'ups',
	'usb',
	'usps',
	'ussunnah',
	'vaadin',
	'viacoin',
	'viadeo',
	'viadeo_square',
	'viber',
	'vimeo',
	'vimeo_square',
	'vimeo_v',
	'vine',
	'vk',
	'vnv',
	'vuejs',
	'watchman_monitoring',
	'waze',
	'weebly',
	'weibo',
	'weixin',
	'whatsapp',
	'whatsapp_square',
	'whmcs',
	'wikipedia_w',
	'windows',
	'wix',
	'wizards_of_the_coast',
	'wodu',
	'wolf_pack_battalion',
	'wordpress',
	'wordpress_simple',
	'wpbeginner',
	'wpexplorer',
	'wpforms',
	'wpressr',
	'xbox',
	'xing',
	'xing_square',
	'y_combinator',
	'yahoo',
	'yammer',
	'yandex',
	'yandex_international',
	'yarn',
	'yelp',
	'yoast',
	'youtube',
	'youtube_square',
	'zhihu',
];

export default defineComponent({
	components: {
		CustomIconDirectus,
		CustomIconBookmarkSave,
		CustomIconBox,
		CustomIconCommitNode,
		CustomIconGrid1,
		CustomIconGrid2,
		CustomIconGrid3,
		CustomIconGrid4,
		CustomIconGrid5,
		CustomIconGrid6,
		CustomIconSignalWifi1Bar,
		CustomIconSignalWifi2Bar,
		CustomIconSignalWifi3Bar,
		CustomIconFlipHorizontal,
		CustomIconFlipVertical,
		CustomIconFolderMove,
		CustomIconFolderLock,
		CustomIconLogout,
		SocialIcon,
	},
	props: {
		name: {
			type: String,
			required: true,
		},
		filled: {
			type: Boolean,
			default: false,
		},
		sup: {
			type: Boolean,
			default: false,
		},
		left: {
			type: Boolean,
			default: false,
		},
		right: {
			type: Boolean,
			default: false,
		},
		disabled: {
			type: Boolean,
			default: false,
		},
		clickable: {
			type: Boolean,
			default: false,
		},
		color: {
			type: String,
			default: null,
		},
		...sizeProps,
	},
	emits: ['click'],

	setup(props, { emit }) {
		const sizeClass = computed<string | null>(() => {
			if (props.sup) return 'sup';
			return useSizeClass(props).value;
		});

		const customIconName = computed<string | null>(() => {
			if (customIcons.includes(props.name)) return `custom-icon-${props.name}`.replace(/_/g, '-');
			return null;
		});

		const socialIconName = computed<string | null>(() => {
			if (socialIcons.includes(props.name)) return props.name.replace(/_/g, '-');
			return null;
		});

		return {
			sizeClass,
			customIconName,
			socialIconName,
			emitClick,
		};

		function emitClick(event: MouseEvent) {
			if (props.disabled) return;
			emit('click', event);
		}
	},
});
</script>

<style>
body {
	--v-icon-color: currentColor;
	--v-icon-color-hover: currentColor;
	--v-icon-size: 24px;
}
</style>

<style lang="scss" scoped>
.v-icon {
	position: relative;
	display: inline-block;
	width: var(--v-icon-size);
	min-width: var(--v-icon-size);
	height: var(--v-icon-size);
	color: var(--v-icon-color);
	font-size: 0;
	vertical-align: middle;

	i {
		display: block;
		font-weight: normal;
		font-size: var(--v-icon-size);
		font-family: 'Material Icons Outline';
		font-style: normal;
		line-height: 1;
		letter-spacing: normal;
		white-space: nowrap;
		text-transform: none;
		word-wrap: normal;
		font-feature-settings: 'liga';

		&::after {
			content: attr(data-icon);
		}

		&.filled {
			font-family: 'Material Icons';
		}
	}

	svg {
		display: inline-block;
		color: inherit;
		fill: currentColor;

		&.svg-inline--fa {
			width: auto;
			height: auto;
		}
	}

	&.has-click {
		cursor: pointer;
		transition: color var(--fast) var(--transition);

		&:hover {
			color: var(--v-icon-color-hover);
		}
	}

	&.sup {
		--v-icon-size: 8px;

		vertical-align: 5px;
	}

	&.x-small {
		--v-icon-size: 12px;
	}

	&.small {
		--v-icon-size: 18px;
	}

	&.large {
		--v-icon-size: 36px;
	}

	&.x-large {
		--v-icon-size: 48px;
	}

	&.left {
		margin-right: 8px;

		&.small {
			margin-right: 4px;
			margin-left: -2px;
		}
	}

	&.right {
		margin-left: 6px;

		&.small {
			margin-right: 4px;
			margin-left: -2px;
		}
	}
}
</style>
