// Silence may be golden, but sometimes words paint the canvas of understanding.
const TitleReplace = {
	name: 'TitleReplace',
	directives: {
		'linksy-tooltip': LinksyTooltip,
	},
	components: {
		LinksyButton,
		LinksyDropdown,
		LinksyDataTable,
		LinksyPagination,
		LinksySearchAndReplaceFilter,
		LinksySearchAndReplaceBulkAction,
		LinksySearchAndReplaceTableHeader,
		LinksySearchAndReplaceUserControls,
		LinkOccurrence,
	},
	data() {
		return {
			query: '',
			search: '',
			filter: {
                search_mode: ['title'],
                title: "",
				link: ""
            },
			searchPlaceholder: 'Enter title to search',
			columns: [
				{
					name: 'Pages',
				},
				{
					name: 'Post Type'
				}
			],
			isLoading: false,
			titleReplacement: '',
			selectedItems: [],
			selectedSearchType: 'EXACT',
			selectedAction: null,
			filterSearch: '',
			replacer: new TitleReplacer(LINKSY_SECURE_TOKEN),
			isTitleReplacing: false,
			showFilter: false
		}
	},
	computed: {
		pageLength: {
			get() {
				return Object.keys(this.items).length
			},
		},
		items: {
			get() {
				return this.replacer.data
			},
		},
		pagination: {
			get() {
				return this.replacer.pagination
			},
		},
		actions() {
			if (['EXACT'].includes(this.selectedSearchType)) {
				return TitleReplacer.SUPPORTED_ACTIONS.filter((a) => a.value != 'remove')
			}

			return TitleReplacer.SUPPORTED_ACTIONS
		},
		searchTypes: {
			get() {
				return TitleReplacer.SEARCH_TYPES
			},
		},
		filterModes: {
			get() {
				return TitleReplacer.FILTER_MODES
			},
		},
		isAllRowsSelected: {
			get() {
				if (this.items.length === 0) return false

				return this.selectedItems.length === this.items.length
			},
		},
	},
	methods: {
		toggleFilter() {
            this.showFilter = !this.showFilter
        },
		handleSearch(q) {
			if (q == '') {
				this.replacer.reset()
			}

			if (this.search !== q) {
				this.search = q
			}
		},
		handleChangePage(page) {
			this.replacer.toPage(page - 1)
			this.getTitles()
		},
		handleChangeRowsPerPage(limit) {
			if (limit != this.pagination.limit) {
				this.replacer.pagination = { limit }
				this.getTitles()
			}
		},
		async getTitles() {
			if (!this.search) return
			try {
				this.query = this.search
				this.isLoading = true

				const searchType = this.searchTypes.find((e) => e.value === this.selectedSearchType)
				await this.replacer.searchTitles(this.search, searchType.value, this.filterSearch, this.filter)
			} catch (error) {
				this.$toast.error(error.response?.data?.data || error.message)
			} finally {
				this.isLoading = false
			}
		},
		async replaceSource(replacement, row) {
			this.isTitleReplacing = true

			try {
				const stat = await this.replacer.applySelectedAction(
					row.source,
					'replace',
					[row],
					replacement
				)

				this.$toast.success('Title edited successfully!')
				row.source = replacement
				row.isEditing = false

				this.isTitleReplacing = false
				this.getTitles()
			} catch (error) {
				this.$toast.error(error.response?.data?.data || error.message)
			}
			
		},
		async applyAction(s, r) {
			s()
			r()
			
			try {
				if (this.search !== this.query) {
					this.$toast.error('Search parameter has changed')
					return
				} else if (!this.titleReplacement && this.selectedAction === 'replace') {
					this.$toast.error('Replacement field cannot be empty')
					return
				} else {
					this.isLoading = true

					await this.replacer.applySelectedAction(
						this.search,
						this.selectedAction,
						this.selectedItems,
						this.titleReplacement,
					)

					this.getTitles()

					let successMsg = ''
					if (this.selectedItems.length == 0) {
						successMsg = 'No title was processed'
					} else {
						const actions = {
							replace: 'replaced',
							remove: 'keyword(s) deleted',
						}

						successMsg = `Title replace: ${this.selectedItems.length} ${actions[this.selectedAction]}`
						this.selectedItems = []
					}

					this.$toast.success(successMsg)
				}
			} catch (error) {
				this.$toast.error(error.message || 'Title replacement failed')
			} finally {
				this.isLoading = false
				this.selectedAction = null
			}
		},
		selectAction(index) {
			let action = Object.values(this.actions)[index]

			if (action.value === this.selectedAction) {
				this.selectedAction = null
			} else {
				this.selectedAction = action?.value
			}
		},
		selectRow(row) {
			const idx = this.selectedItems.findIndex((item) => {
				return item.post_id === row.post_id && item.title === row.title
			})

			if (idx === -1) {
				this.selectedItems.push(row)
			} else {
				this.selectedItems.splice(idx, 1)
			}
		},
		selectAllRows() {
			this.selectedItems = this.selectedItems.length === this.items.length ? [] : [...this.items]
		},
		isRowSelected(row) {
			const idx = this.selectedItems.findIndex((item) => {
				return item.post_id === row.post_id && item.title === row.title
			})

			return idx > -1
		},

		handleFilterChange(values) {
			this.filter = { ...values }
			this.replacer.reset()

			this.getTitles()
		},
		handleCancel() {
			this.selectedAction = null
		},
		handleTitleSearch() {
			if (this.search || this.isSearchDisabled) {
				this.getTitles()
			}
		},
		onSelectSearchType(label) {
			const type = this.searchTypes.find((type) => type.value === label)
			if (type) {
				this.selectedSearchType = type.value

				// reset total items and selected items
				this.replacer.reset()
				this.selectedItems = []
			}
		},
	},
	template: `
        <div id="title-replace" class="d-flex flex-column gap-4">
			<div class="d-flex flex-column flex-lg-row justify-content-between column-gap-2 column-gap-xl-5 row-gap-3">
				<div class="action-dropdown d-flex justify-content-between">
					<LinksySearchAndReplaceBulkAction
						:is-loading="isLoading"
						:actions="actions"
						:selected-action="selectedAction"
						@on-apply-action="applyAction"
						@select-action="selectAction"
						@on-cancel="handleCancel"
					/>
					<linksy-button variant="white_outline" class="d-flex d-lg-none filter-btn-toggle text-nowrap" :class="{active: showFilter}" @click="toggleFilter">
						<i class="fa-solid fa-bars-staggered me-2"></i><span>Filter</span>
					</linksy-button>
				</div>

				<div class="d-flex flex-column flex-lg-row align-items-center gap-2 w-100">
					<LinksySearchAndReplaceUserControls
						:search-types="searchTypes"
						:is-search-disabled="isSearchDisabled"
						:search-placeholder=" selectedSearchType === 'TITLE_CONTAINS' ? 'Enter word or title to search' : searchPlaceholder "
						@on-select-search-type="onSelectSearchType"
						@on-search-change="handleSearch"
						@on-item-search="handleTitleSearch"
					/>
					<div class="replacement d-flex flex-fill w-100 p-0">
						<input
							type="text"
							:placeholder="selectedSearchType === 'EXACT' ? 'Enter replacement title' : 'Enter replacement word or title'"
							class="flex-grow-1 fs-14px border border-1 rounded-3"
							:class="{ 'is-disabled': selectedAction === 'remove' }"
							v-model="titleReplacement"
						/>
					</div>
				</div>

				<linksy-button variant="white_outline" class="filter-btn-toggle text-nowrap d-none d-lg-flex align-items-center" :class="{active: showFilter}" @click="toggleFilter">
                    <i class="fa-solid fa-bars-staggered me-2"></i><span>Filter</span>
                </linksy-button>
			</div>

			<linksy-search-and-replace-filter
				v-if="showFilter"
				replace-type="title"
				:filter="filter"
				:filter-modes="filterModes"
				@on-change="handleFilterChange"
			>
			</linksy-search-and-replace-filter>

            <linksy-data-table
				class="shadow-sm overflow-auto"
                :columns="columns"
                :data="items"
                :loading="isLoading"
            >
                <template v-slot:column-header-0>
                    <LinksySearchAndReplaceTableHeader
						header-name="Title"
                        :is-all-rows-selected="isAllRowsSelected"
                        :select-all-rows="selectAllRows"
                        :replacer="replacer"
                        :pagination="pagination"
						:disabled="isTitleReplacing || isLoading"
                    />
                </template>
                <template v-slot:column-0="{item, index}">
                    <link-occurrence
                        title-replace
                        :data="item"
                        class="pb-4"
                        :is-selected="isRowSelected"
                        :on-select="selectRow"
						:is-field-replacing="isTitleReplacing"
						@on-replace-field="replaceSource"
                    ></link-occurrence>
                </template>
				<template v-slot:column-1="{item, index}">
                    <span class="fw-normal">{{item.post_type}}</span>
                </template>
            </linksy-data-table>

            <linksy-pagination
                :pageLength="pageLength"
                :perPage="pagination.limit"
                :currentPage="pagination.page+1"
                :total="pagination.total"
                @on-change-page="handleChangePage"
                @on-change-rows-per-page="handleChangeRowsPerPage"
            >
            </linksy-pagination>
        </div>
    `,
}
