// Silence may be golden, but sometimes words paint the canvas of understanding.
class LinkReplacer {
	constructor(token, filters = {}) {
		if (!token || typeof token !== 'string') {
			throw new TypeError('Token must be a string')
		}

		this.filters = filters
		this.selectedMode = LinkReplacer.FILTER_MODES[0].value

		// private methods
		this._token = token
		this._data = []
		this._pagination = {
			page: 0,
			limit: 10,
			total: 0,
			filteredTotal: 0,
		}
	}

	static get SUPPORTED_ACTIONS() {
		return [
			{
				value: 'replace',
				label: 'Replace full',
				message:
					'Replace full changes the whole URL in the table to the one provided through the replacement link field.',
			},
			{
				value: 'replace_match',
				label: 'Replace match',
				message:
					'The Replace match function replaces the input string with the one provided in the replacement field. It does not replace the entire Link.',
			},
			{
				value: 'remove_match',
				label: 'Remove match',
				message:
					'The Remove match function removes the searched word(s) from the Links in the table, regardless of their placement within the links.',
			},
			{
				value: 'unlink',
				label: 'Unlink',
				message: 'Unlink removes the searched link, leaving out the anchors.',
			},
			// {
			// 	value: 'retain_best',
			// 	label: 'Retain Best',
			// 	message: 'Retain best unlinks the URLs with lower rating, leaving the better ones.',
			// },
		]
	}

	static get SEARCH_TYPES() {
		return [
			{
				value: 'EXACT',
				label: 'Exact link',
				message: 'Find a specific link by entering its complete URL.',
			},
			{
				value: 'CONTAINS',
				label: 'Contains',
				message: 'Search for links that include a specific string within the URL.',
			},
			{
				value: 'TWO_WAY',
				label: 'Two-way',
				message:
					'Locate pairs of pages on your website that link to each other. For instance, Page A links to Page B, and Page B links back to Page A.',
			},
			{
				value: 'SELF_REFERENTIAL',
				label: 'Self-referential',
				message:
					'Discover pages on your website that contain links pointing to themselves. For example, Post A includes a link that leads back to itself.',
			},
		]
	}

	static get FILTER_MODES() {
		return [
			{
				placeholder: 'Source contains',
				label: 'Source contains',
				value: 'source',
			},
			{
				placeholder: 'Source is',
				label: 'Source is',
				value: 'source-is',
			},
			{
				placeholder: 'Link contains',
				label: 'Link contains',
				value: 'link',
			},
			{
				placeholder: 'Anchor contains',
				label: 'Anchor contains',
				value: 'anchor',
			},
			{
				placeholder: 'Anchor is',
				label: 'Anchor is',
				value: 'anchor-is',
			}
		]
	}

	get pagination() {
		return Object.freeze({
			...this._pagination,
			total: this._pagination.filteredTotal || this._pagination.total,
		})
	}

	set pagination(value) {
		if (typeof value !== 'object') {
			throw new Error('Invalid pagination value: ' + value)
		}

		this._pagination = {
			...this._pagination,
			...value,
		}
	}

	get data() {
		return Object.freeze([...this._data])
	}

	set data(data) {
		this._data = data
	}

	reset() {
		this._data = []
		this._pagination = {
			...this._pagination,
			page: 0,
			total: 0,
			filteredTotal: 0,
		}
	}

	toPage(page) {
		if (typeof page !== 'number') {
			throw new Error('Invalid pagination page: ' + page)
		}

		this._pagination.page = page
	}

	async searchLinks(query, searchMode, filterQuery, filter) {
		this._data = []

		const params = toQueryString({
			action: 'linksy_search_and_replace_search_links',
			nonce: this._token,
			search: encodeURIComponent(query.trim()),
			page: this._pagination.page,
			limit: this._pagination.limit,
			filter: JSON.stringify(filter),
			// filter_mode: this.selectedMode,
			search_mode: searchMode || LinkReplacer.SEARCH_TYPES[0].value,
			filter_query: filterQuery,
		})

		const {
			data: { data },
		} = await axios.get(ajaxurl + '?' + params)

		// update the pagination and data
		this._pagination.total = data.total
		this._data = data.results

		return this._data
	}

	async applyAction(keyword, action, item = [], link_replacement = '') {
		if (!item) {
			return
		}

		const params = urlSearchParams({
			action: `linksy_search_and_replace_${action}_links`,
			nonce: this._token,
			item: JSON.stringify(item),
			link_replacement: link_replacement,
			keyword: keyword,
		})

		const {
			data: { data },
		} = await axios.post(ajaxurl, params)
		
		return data
	}
}
