/**
 * Pinia store for entity export functionality.
 *
 * Manages per-entity CSV export and full ZIP bundle export.
 *
 * Part of Issues #148, #149.
 */
import { defineStore } from 'pinia'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'

export const useExportStore = defineStore('export', {
	state: () => ({
		/** @type {Array<{key: string, label: string}>} Available entity types */
		entityTypes: [],
		/** @type {string} Selected entity type key */
		selectedType: '',
		/** @type {boolean} Loading state */
		loading: false,
		/** @type {string|null} Error message */
		error: null,
		/** @type {boolean} Show sensitive data warning dialog */
		showSensitiveWarning: false,
		/** @type {boolean} Bundle export loading state */
		bundleLoading: false,
	}),

	actions: {
		/**
		 * Fetch available entity types from backend.
		 */
		async fetchEntityTypes() {
			if (this.entityTypes.length > 0) {
				return
			}
			this.loading = true
			this.error = null
			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/export/entity-types')
				const response = await axios.get(url)
				this.entityTypes = response.data || []
				if (this.entityTypes.length > 0 && !this.selectedType) {
					this.selectedType = this.entityTypes[0].key
				}
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Laden der Export-Typen'
				console.error('Failed to fetch entity types:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Download CSV for the selected entity type.
		 */
		async downloadEntity() {
			if (!this.selectedType) {
				return
			}
			this.loading = true
			this.error = null
			try {
				const url = generateUrl(`/apps/mitgliederverwaltung/api/v1/export/entity/${this.selectedType}`)
				const response = await axios.get(url, { responseType: 'blob' })

				// Extract filename from Content-Disposition or use default
				const disposition = response.headers['content-disposition']
				let filename = `${this.selectedType}.csv`
				if (disposition) {
					const match = disposition.match(/filename[^;=\n]*=["']?([^"';\n]*)/)
					if (match?.[1]) {
						filename = match[1]
					}
				}

				// Trigger browser download
				const blob = new Blob([response.data], { type: 'text/csv; charset=utf-8' })
				const link = document.createElement('a')
				link.href = URL.createObjectURL(blob)
				link.download = filename
				link.click()
				URL.revokeObjectURL(link.href)
			} catch (err) {
				this.error = err.response?.data?.error || 'Export fehlgeschlagen'
				console.error('Failed to download entity CSV:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Download full ZIP bundle without sensitive data.
		 */
		async downloadBundle() {
			this.bundleLoading = true
			this.error = null
			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/export/bundle')
				const response = await axios.get(url, { responseType: 'blob' })
				this._triggerDownload(response, 'Vollstaendiger_Export.zip')
			} catch (err) {
				this.error = err.response?.data?.error || 'Vollstaendiger Export fehlgeschlagen'
				console.error('Failed to download bundle:', err)
			} finally {
				this.bundleLoading = false
			}
		},

		/**
		 * Download full ZIP bundle with sensitive data (requires confirmation).
		 */
		async downloadBundleSensitive() {
			this.bundleLoading = true
			this.error = null
			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/export/bundle/sensitive')
				const response = await axios.post(url, { confirm: true }, { responseType: 'blob' })
				this._triggerDownload(response, 'Vollstaendiger_Export_sensibel.zip')
			} catch (err) {
				this.error = err.response?.data?.error || 'Sensibler Export fehlgeschlagen'
				console.error('Failed to download sensitive bundle:', err)
			} finally {
				this.bundleLoading = false
				this.showSensitiveWarning = false
			}
		},

		/**
		 * Helper to trigger browser file download from response blob.
		 */
		_triggerDownload(response, fallbackName) {
			const disposition = response.headers['content-disposition']
			let filename = fallbackName
			if (disposition) {
				const match = disposition.match(/filename[^;=\n]*=["']?([^"';\n]*)/)
				if (match?.[1]) {
					filename = match[1]
				}
			}
			const blob = new Blob([response.data], { type: response.headers['content-type'] || 'application/zip' })
			const link = document.createElement('a')
			link.href = URL.createObjectURL(blob)
			link.download = filename
			link.click()
			URL.revokeObjectURL(link.href)
		},

		clearError() {
			this.error = null
		},
	},
})
