<template>
	<fragment>
		<div class="wcc-loader-view" v-if="!isLoaded">
			<p class="wcc-loading-text">
			<loader />
			{{ $i18n.__("Fetching scan data", "webtoffee-cookie-consent") }}
			</p>
		</div>
		<div v-else class = "wcc-nav-tab-section wcc-nav-tab-section-cookies">
			<div class = "wcc-scanner-main-container">
				<div v-if = "isLocalhost" class="wcc-localhost-warning-screen">
					<localhost />
				</div>
				<div v-else-if ="'active' === licenseStatus">
					<div v-if ="firstscan" class = "wcc-initial-scanner-screen">
						<initial-scanner />
					</div>
					<div v-else class = "wcc-scanner-screen">
						<!-- Pass responseData as a prop to ScanResult component -->
						<scan-result :responseData = "responseData" />
					</div>
				</div>
				<div v-else class = "wcc-license-warning-screen">
					<!-- Pass responseData as a prop to ScanResult component -->
					<license-notice :responseData = "responseData" />
				</div>
			</div>
		</div>
	</fragment>
  </template>

<script>
import api from "@/modules/scanner/helpers/api";
import { Fragment } from "vue-frag";
import InitialScanner from "@/modules/scanner/views/InitialScan.vue";
import ScanResult from "@/modules/scanner/views/ScanResult.vue";
import Localhost from "@/modules/scanner/views/LocalhostNotice.vue";
import Loader from "@/components/elements/Loader.vue";
import LicenseNotice from '../views/LicenseNotice.vue';
import { mapState } from "vuex";

export default {
	name: "TabScanner",
	components: {
		Fragment,
        InitialScanner,
        ScanResult,
		Loader,
		Localhost,
		LicenseNotice
	},
	data() {
		return {
            firstscan: true,
            currentLanguage: "",
			responseData: null, // Initialize responseData as null
			scanning: false,
            scan_token: null,
            scanResult: null,
            showScanDetails: false,
            loading: !this.responseData,
            selectedScanData: {},
            scanResponseData:{},
			scan_status: null,
			isLocalhost: false,
			ipFetched: false,
			db_scan_status: null,
			db_scan_result: null,
		};
	},
	methods: {
		async ScannerConnect() {
			try {
				this.scanning = true;
				const response = await api.initiateScan();
				// Check for webtoffee_api_error format
				if (response && response.code === 'webtoffee_api_error') {
					this.showErrors(response.message);
					this.scanning = false;
					// Emit event to notify ScanResult component
					this.$root.$emit("scan-error");
					return false;
				}

				// Check for status error format
				if (response && response.status === 'error') {
					this.showErrors(response.error_message);
					this.scanning = false;
					// Emit event to notify ScanResult component
					this.$root.$emit("scan-error");
					return false;
				}

				if(response) {
					this.scanId = response.scan_id;
					this.scan_token = response.scan_token;
					this.scan_status = response.scan_status ? response.scan_status : 'initiated';
					// // Fetch the scan history after initiating the scan
					// let newScanData = await api.checkScanHistory();
					// this.responseData = newScanData.data;
					// // Update the scan history after initiating the scan
					// if (this.scan_status === 'initiated') {
					// 	this.$nextTick(() => {
					// 		this.$forceUpdate();
					// 	});
					// }
					// this.$emit('scan-connect', this.responseData);
				}

			} catch (error) {
				this.scanning = false;
				this.showErrors(error.message || this.$i18n.__('An error occurred during scan initiation', 'webtoffee-cookie-consent'));
				// Emit event to notify ScanResult component
				this.$root.$emit("scan-error");
				console.error('API Error:', error);
				return false;
			} finally {
				if(this.scanning){
					this.firstscan = false;
					this.checkScanData();
					this.startScan();
				}
			}
		},
		async startScan() {
            try {
                if (!this.scanId) {
                    // If there is no scanId, do nothing
                    return;
                }
                if (this.scan_token !== false) {
                    await api.startScan( this.scanId, this.scan_token );
                }
            } catch (error) {
                // Handle errors here
                console.error('API Error:', error);
            }
            finally {
                // Set the loading state back to false, whether the request succeeds or fails
                this.scanning = true;
            }
        },
		async abortScan() {
            try {
                if (!this.scanId) {
                    // If there is no scanId, do nothing
                    return;
                }
                if (this.scan_token !== false) {
                    await api.abortScan(this.scanId,this.scan_token);
                }
            } catch (error) {
                // Handle errors here
                console.error('API Error:', error);
            }
            finally {
                // Set the loading state back to false, whether the request succeeds or fails
                this.scanning = false;
				this.checkScanData();
            }
        },
		async checkScanData(){
			// Make an HTTP request to your API endpoint to check the database
			const response = await api.checkScanHistory();
			const responseData = response.data;
			// Check if responseData is defined and is an object with properties
			if (
				typeof responseData === "object" &&
				responseData !== null &&
				Object.keys(responseData).length > 0
			) {
				// If responseData is an object with properties, set firstscan to false
				this.firstscan = false;
				// Set responseData to pass it to ScanResult
				this.responseData = responseData;
				this.loading = true;
				// Check if responseData is defined and is an object
				if (typeof responseData === 'object' && responseData !== null) {
					// Get the keys (property names) of the object
					const keys = Object.keys(responseData);

					// Get the last key, which should correspond to the last item
					const lastKey = keys[keys.length - 1];

					// Get the last item using the last key
					const lastItem = responseData[lastKey];
					// Set the db scanID to the scanId of the last item
					this.scanId = lastItem.scan_id;
					// Set this.db_scan_status to the scan_status of the last item
					this.db_scan_status = lastItem.scan_status;
					// Set this.db_scan_result to the scan_result of the last item
					this.db_scan_result = lastItem.scan_history;
					// Set this.db_scan_token to the scan_token of the last item
					this.scan_token = lastItem.scan_token;
				}
				// Filter objects with scan_status initiated
				const initiatedScans = Object.values(responseData).filter(
					(item) => item.scan_status === "initiated"
				);

				if (initiatedScans.length > 0) {
					// Set this.scanId to the scan_id of the first initiated scan
					this.scanId = initiatedScans[0].scan_id;
					// Set this.scan_status to the scan_status of the first initiated scan
					this.db_scan_status = initiatedScans[0].scan_status;
					this.scan_token  = initiatedScans[0].scan_token;
					this.scanning    = true;
				}
			}
			else if (Array.isArray(responseData) && responseData.length === 0) {
				// If responseData is an empty array, set firstscan to false
				this.firstscan = true;
				this.loading = true;
			} else {
				// If responseData is an empty object, null, or not an object, set firstscan to true
				this.firstscan = true;
				this.loading = true;
			}
		},
		async fetchScanStatus() {
            try {
				if (!this.scanId) {
					// If there is no scanId, do nothing
					return;
				}
				if (this.scan_token !== false) {
					await this.checkScanData();
					const response = await api.fetchScanStatus(this.scanId,this.scan_token);
					this.scan_status = response.scan_status;
				}
            } catch (error) {
				// Handle errors here
				console.error('API Error:', error);
            }
			finally {
				this.checkScanData();
            }
        },
		async fetchDBScanStatus() {
            try {
				if (!this.scanId) {
					// If there is no scanId, do nothing
					return;
				}
				if (this.scan_token !== false) {
					await this.checkScanData();
				}
            } catch (error) {
				// Handle errors here
				console.error('API Error:', error);
            }
        },
		async fetchFinalResult(){
            try {
				if (!this.scanId) {
					// If there is no scanId, do nothing
					return;
				}
				if (this.scan_token !== false) {
					const response = await api.getScanResult(this.scanId,this.scan_token);
					this.scan_result = response.scan_result;
				}
            } catch (error) {
				// Handle errors here
				console.error('API Error:', error);
            } finally {
                // Set the loading state back to false, whether the request succeeds or fails
                this.scanning = false;
            }
		},
		async FetchIp(){
			try {
				// Get the user's IP address
				const ipAddress = await api.getIP();
				this.checkConditions( ipAddress );
            } catch (error) {
				// Handle errors here
				console.error('API Error:', error);
            }
		},
		checkConditions(ipAddress) {
			const localhostArr = ['127.0.0.1', '::1'];
			// Check if the ipAddress is in the localhostArr
			this.isLocalhost = localhostArr.includes(ipAddress);
			this.ipFetched = true;
		},
		showErrors(message) {
			this.$root.$emit("triggerNotification", {
				type: "error",
				message: message,
			});
		}
	},
	computed: {
		language: {
			get() {
				return (
					(this.currentLanguage && this.currentLanguage) ||
					this.$store.state.languages.default
				);
			},
			set(value) {
				this.currentLanguage = value;
			},
		},
		isLoaded() {
			return this.loading && this.ipFetched;
		},
		licenseStatus() {
			return this.info.license.status;
		},
		...mapState("settings", ["info"]),
	},
	async created() {
		try {
			// Fetch IP address
			this.FetchIp();
			// Listen for the custom event 'scanner-connect-clicked' emitted by InitialScan.vue
			this.$root.$on('scanner-connect-clicked', () => {
				// Call the ScannerConnect method when the event is received
				this.ScannerConnect();
			});

			// Listen for the custom event 'abort-scan' emitted by InitialScan.vue
			this.$root.$on('abort-scan-clicked', () => {
				// Call the ScannerConnect method when the event is received
				this.abortScan();	
			});

			// Listen for the custom event 'fetch-scan-status' emitted by InitialScan.vue
			this.$root.$on('fetch-scan-clicked', () => {
				// Call the fetchScanStatus method when the event is received
				this.fetchScanStatus();				
			});
			// Load scan data when page loaded
			await this.checkScanData();
			if (this.scanning) {
				this.fetchScanStatus();
			}
			// Start polling for scan status every 60 seconds
			this.statusInterval = setInterval(() => {
				if (this.scanning) {
					this.fetchDBScanStatus();
				}
			}, 60000); // 60 seconds in milliseconds
			// If database scan status is not completed and scan already completed in cookie scanner update the scan result to database
			if( 'completed' === this.scan_status && 'completed' !== this.db_scan_status && 'aborted' !== this.db_scan_status ){
				this.fetchFinalResult();
			}
			// If database scan status is completed and scan history is not saved to database then update the scan result to database
			if ( 'completed' === this.db_scan_status && (this.db_scan_result === null || this.db_scan_result === '' || Object.keys(this.db_scan_result).length === 0)) {
				this.fetchFinalResult();
			}
		} catch (error) {
			console.error("API Error:", error);
		}
    },
	beforeDestroy() {
		// Clear the polling interval when the component is destroyed to prevent memory leaks
		clearInterval(this.statusInterval);
	},
	
};
</script>
<style lang="scss" scoped>
.wcc-cookie-list-title {
	margin-bottom: 20px;
	.wcc-add-cookie-button {
		margin-left: 10px;
	}
}
.wcc-nav-tab-section-cookies {
	background: transparent;
}

.wcc-app-modal-cookies {
	.wcc-admin-notice-message p {
		font-size: 12px;
	}
}
.wcc-cookies-title {
	display: flex;
	align-items: center;
	padding: 10px 0;
}
.wcc-cookies-title .wcc-button-no-style {
	margin-left: 11px;
}
.wcc-nav-tab-section-header {
	border: none;
}
.wcc-nav-tab-section-cookies {
	padding: 15px 15px;
	.wcc-nav-tab-section-header {
		h5 {
			font-weight: $font--medium;
			// border-bottom: 1px solid;
			padding-bottom: 2px;
			margin: 0;
		}
	}
}
</style>
<style lang="scss">
@include wrap-class() {
	.wcc-table {
		&.wcc-table-cookies {
			margin-top: 15px;
			border: none;
			tbody tr {
				border-top: none;
				td {
					font-size: 13px;
				}
			}
			tbody td,
			th {
				padding: 15px 10px;
			}
		}
	}
	.wcc-cookie-list-title {
		select {
			margin-left: 10px;
			min-width: 150px; // auto
			height: auto;
			width: auto;
		}
	}
	.wcc-nav-tab-manage-cookies {
		&
			> .wcc-nav-tab-content-container
			> .wcc-nav-tab-section
			> .wcc-nav-tab-section-header {
			padding: 15px 0 15px 0;
		}
		.wcc-nav-tab-button {
			padding: 15px 10px;
		}
	}
}

.wcc-app-rtl {
	input,
	.wcc-cookies-title,
	.wcc-category-description,
	.wcc-rich-text-editor * {
		direction: rtl;
		text-align: right;
	}
}

.wcc-input-error-alert {
	color: #dc3545;
	padding: 5px 0px;
}
.wcc-section-cookies {
	.wcc-rich-text-editor-container {
		margin-top: -30px;
	}
}
.wcc-scanner-main-container{
    height: auto;
}
.wcc-scanner-image-container,.wcc-scanner-connect-btn{
    display: flex;
    justify-content: center;
    align-items: center;
}
.wcc-scanner-connect-btn .wcc-icon-base{
    vertical-align: bottom;
}
.wcc-scanner-container-template{
	height: 500px;
	display: flex;
	align-items: center;
	justify-content: center;
}
</style>