/**
 * Pinia store for import wizard state management.
 *
 * Supports two modes:
 * - Legacy member import (original flow from Issue #58)
 * - Per-entity import with auto-detection (Issue #150)
 *
 * Part of Issues #58, #150.
 */
import { defineStore } from 'pinia'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'

export const useImportStore = defineStore('import', {
	state: () => ({
		/** @type {number} Current wizard step (1-5) */
		step: 1,
		/** @type {string|null} Base64 file content */
		fileContent: null,
		/** @type {string} File name */
		fileName: '',
		/** @type {string} CSV delimiter */
		delimiter: ';',
		/** @type {string} File encoding */
		encoding: 'UTF-8',
		/** @type {Array} Source column headers from CSV */
		columns: [],
		/** @type {Array} Preview rows from upload step */
		previewRows: [],
		/** @type {number} Total rows in file */
		totalRows: 0,
		/** @type {Array} Target fields metadata */
		targetFields: [],
		/** @type {Object} Column mapping: { sourceIndex: targetFieldKey } */
		mapping: {},
		/** @type {Object|null} Preview/dry-run results */
		previewResult: null,
		/** @type {Object|null} Execution results */
		executeResult: null,
		/** @type {boolean} Loading state */
		loading: false,
		/** @type {string|null} Error message */
		error: null,

		// ── Per-entity import fields (Issue #150) ──
		/** @type {string} Selected entity type key */
		entityType: '',
		/** @type {Object|null} Auto-detection result */
		detection: null,
		/** @type {Array} FK resolution warnings from dry-run */
		fkWarnings: [],
		/** @type {Array} Resolved conflict merge data from ConflictResolver */
		conflictResolutions: [],
		/** @type {Object|null} Merge result after conflict resolution */
		mergeResult: null,
		/** @type {boolean} Migration mode (content-based matching) */
		migrationMode: false,
		/** @type {Array} Ambiguous match warnings from migration mode */
		ambiguousWarnings: [],
		/** @type {Object} User corrections for error rows: { rowIndex: { fieldKey: value } } */
		corrections: {},

		// ── Bundle import fields (Issue #151) ──
		/** @type {boolean} Whether importing a ZIP bundle */
		isBundleImport: false,
		/** @type {Object|null} Bundle analysis result */
		bundleAnalysis: null,
		/** @type {Object|null} Bundle preview result */
		bundlePreviewResult: null,
		/** @type {Object|null} Bundle execution result */
		bundleExecuteResult: null,
		/** @type {Object} Per-entity corrections for bundle errors: { entityType: { rowIndex: { fieldKey: value } } } */
		bundleCorrections: {},
	}),

	getters: {
		/**
		 * Check if all required fields are mapped.
		 */
		allRequiredMapped: (state) => {
			const requiredKeys = state.targetFields
				.filter(f => f.required)
				.map(f => f.key)
			const mappedTargets = Object.values(state.mapping).filter(v => v !== '')
			return requiredKeys.every(k => mappedTargets.includes(k))
		},
	},

	actions: {
		/**
		 * Upload and parse a CSV file with entity auto-detection.
		 *
		 * @param {File} file - The file object from input
		 */
		async uploadFile(file) {
			this.loading = true
			this.error = null
			this.fileName = file.name

			try {
				const content = await this.readFileAsBase64(file)
				this.fileContent = content

				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/entity/upload')
				const response = await axios.post(url, {
					content,
					delimiter: this.delimiter,
					encoding: this.encoding,
					entityType: this.entityType || undefined,
				})

				this.columns = response.data.columns || []
				this.previewRows = response.data.rows || []
				this.totalRows = response.data.totalRows || 0
				this.detection = response.data.detection || null
				this.targetFields = response.data.targetFields || []

				// Use detected type if none explicitly selected
				if (!this.entityType && response.data.entityType) {
					this.entityType = response.data.entityType
				}

				// Use auto-mapping from backend
				if (response.data.mapping) {
					this.mapping = {}
					for (const [idx, key] of Object.entries(response.data.mapping)) {
						this.mapping[idx] = key
					}
				} else {
					this.mapping = {}
					this.columns.forEach((col, idx) => {
						this.mapping[idx] = ''
					})
				}

				this.step = 2
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Hochladen der Datei'
				console.error('Failed to upload file:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Re-fetch schema and mapping when entity type changes.
		 */
		async changeEntityType(newType) {
			if (!newType || !this.fileContent) return
			this.entityType = newType
			this.loading = true
			this.error = null

			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/entity/upload')
				const response = await axios.post(url, {
					content: this.fileContent,
					delimiter: this.delimiter,
					encoding: this.encoding,
					entityType: newType,
				})

				this.targetFields = response.data.targetFields || []
				if (response.data.mapping) {
					this.mapping = {}
					for (const [idx, key] of Object.entries(response.data.mapping)) {
						this.mapping[idx] = key
					}
				}
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Laden des Schemas'
				console.error('Failed to change entity type:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Run dry-run preview with current mapping.
		 */
		async runPreview() {
			this.loading = true
			this.error = null

			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/entity/preview')
				const response = await axios.post(url, {
					content: this.fileContent,
					entityType: this.entityType,
					mapping: this.mapping,
					delimiter: this.delimiter,
					encoding: this.encoding,
					migrationMode: this.migrationMode,
					corrections: this.corrections,
				})

				this.previewResult = response.data
				this.fkWarnings = response.data.fkWarnings || []
				this.ambiguousWarnings = response.data.ambiguous || []
				this.step = 4
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler bei der Vorschau'
				console.error('Failed to preview:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Execute the import.
		 */
		async executeImport() {
			this.loading = true
			this.error = null

			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/entity/execute')
				const response = await axios.post(url, {
					content: this.fileContent,
					entityType: this.entityType,
					mapping: this.mapping,
					delimiter: this.delimiter,
					encoding: this.encoding,
					migrationMode: this.migrationMode,
					corrections: this.corrections,
				})

				this.executeResult = response.data
				this.step = 5
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Import'
				console.error('Failed to execute import:', err)
			} finally {
				this.loading = false
			}
		},

		// ── Conflict resolution (Issue #152) ──

		/**
		 * Execute merge for resolved conflicts.
		 */
		async executeMerge() {
			if (!this.conflictResolutions.length) return
			this.loading = true
			this.error = null

			try {
				// Filter to only resolutions that have merged fields
				const toMerge = this.conflictResolutions.filter(
					r => Object.keys(r.mergedFields).length > 0,
				)

				if (toMerge.length === 0) return

				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/entity/merge')
				const response = await axios.post(url, {
					entityType: this.entityType,
					resolutions: toMerge,
				})

				this.mergeResult = response.data
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Zusammenfuehren'
				console.error('Failed to merge conflicts:', err)
			} finally {
				this.loading = false
			}
		},

		// ── Bundle import actions (Issue #151) ──

		/**
		 * Upload and analyze a ZIP bundle.
		 */
		async uploadBundle(file) {
			this.loading = true
			this.error = null
			this.fileName = file.name
			this.isBundleImport = true

			try {
				const content = await this.readFileAsBase64(file)
				this.fileContent = content

				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/bundle/upload')
				const response = await axios.post(url, { content })

				this.bundleAnalysis = response.data
				this.step = 2 // Show analysis
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Analysieren des ZIP-Archivs'
				console.error('Failed to analyze bundle:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Run bundle preview (dry-run for all entities).
		 */
		async runBundlePreview() {
			this.loading = true
			this.error = null

			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/bundle/preview')
				const response = await axios.post(url, {
					content: this.fileContent,
					corrections: this.bundleCorrections,
				})

				this.bundlePreviewResult = response.data
				this.step = 4
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler bei der Bundle-Vorschau'
				console.error('Failed to preview bundle:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Execute bundle import.
		 */
		async executeBundleImport() {
			this.loading = true
			this.error = null

			try {
				const url = generateUrl('/apps/mitgliederverwaltung/api/v1/import/bundle/execute')
				const response = await axios.post(url, {
					content: this.fileContent,
					corrections: this.bundleCorrections,
				})

				this.bundleExecuteResult = response.data
				this.step = 5
			} catch (err) {
				this.error = err.response?.data?.error || 'Fehler beim Bundle-Import'
				console.error('Failed to execute bundle import:', err)
			} finally {
				this.loading = false
			}
		},

		/**
		 * Reset the wizard to initial state.
		 */
		reset() {
			this.step = 1
			this.fileContent = null
			this.fileName = ''
			this.columns = []
			this.previewRows = []
			this.totalRows = 0
			this.mapping = {}
			this.previewResult = null
			this.executeResult = null
			this.error = null
			this.entityType = ''
			this.detection = null
			this.fkWarnings = []
			this.conflictResolutions = []
			this.mergeResult = null
			this.migrationMode = false
			this.ambiguousWarnings = []
			this.corrections = {}
			this.isBundleImport = false
			this.bundleAnalysis = null
			this.bundlePreviewResult = null
			this.bundleExecuteResult = null
			this.bundleCorrections = {}
		},

		/**
		 * Read a file as Base64 string.
		 */
		readFileAsBase64(file) {
			return new Promise((resolve, reject) => {
				const reader = new FileReader()
				reader.onload = () => {
					const base64 = reader.result.split(',')[1]
					resolve(base64)
				}
				reader.onerror = reject
				reader.readAsDataURL(file)
			})
		},

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