import * as React from 'react'

import {
	useContext,
	useState,
	createContext,
} from '@wordpress/element'

import {
	Button,
	FormFileUpload,
} from '@wordpress/components'

import {
	useDispatch,
} from '@wordpress/data'

import {
	store as noticesStore,
} from '@wordpress/notices'

import {
	download,
	upload,
	cloudDownload,
	cloudUpload,
} from '@wordpress/icons'

import {
	CAN_EXPORT_DEMO,
	CAN_IMPORT_DEMO,
	IMPORT_DEMO,
	IS_SETTINGS_PAGE,
} from '@ska/utils'

import ExportModal from './ExportModal'
import DemoExportModal from './DemoExportModal'
import ImportModal from './ImportModal'
import DemoImportModal from './DemoImportModal'

import {
	SLUG,
} from './util'

import './style.scss'

export interface ImportExportStrings {
	exportLabel: string
	importLabel: string
	importDemoLabel: string
	importedLabel: string
	importAllLabel: string
	importExportLoadingLabel: string
	downloadLabel: string
	currentValueLabel: string
	importedValueLabel: string
	invalidImportFileContentsMessage: string
	nothingToImportMessage: string
	createLabel: string
	createdLabel: string
	overwriteLabel: string,
	createCopyLabel: string,
	titleLabel: string
	noTitleLabel: string
	exportInstructions: string
	importInstructions: string
	isSameText: string
	labelDefault: string
	labelModified: string
	labelCustom: string
	labelFrontPage: string
	labelBlogPage: string
	createMissingEntitiesLabel: string
	createMissingEntitiesDescription: string
	summaryLabel: string
}

export const IMPORT_EXPORT_STRINGS = {
	exportLabel: 'Export',
	importLabel: 'Import',
	importDemoLabel: 'Import demo',
	importedLabel: 'Imported',
	importAllLabel: 'Import all',
	importExportLoadingLabel: 'Loading…',
	downloadLabel: 'Download',
	currentValueLabel: 'Current value',
	importedValueLabel: 'Imported value',
	invalidImportFileContentsMessage: 'Invalid import file contents',
	nothingToImportMessage: 'Nothing to import.',
	createLabel: 'Create',
	createdLabel: 'Created',
	overwriteLabel: 'Overwrite current',
	createCopyLabel: 'Create a copy',
	titleLabel: 'Title',
	noTitleLabel: '(No title)',
	exportInstructions: `Select all the content you wish to export and then press "Download" all the way at the bottom.`,
	importInstructions: `Import the desired content, then close this modal and save changes.`,
	isSameText: `Imported value is identical to current value.`,
	labelDefault: `Default`,
	labelModified: `Modified`,
	labelCustom: `Custom`,
	labelFrontPage: `Front page`,
	labelBlogPage: `Blog page`,
	createMissingEntitiesLabel: `Create missing entities`,
	createMissingEntitiesDescription: `Create posts, pages and other entities included in this import. Uncheck to only update option values and overwrite existing templates, but not create any new posts, pages or templates.`,
	summaryLabel: `The following resources will be imported:`,
}

export const ImportExportStringsContext = createContext<ImportExportStrings>(IMPORT_EXPORT_STRINGS)

const ImportExport: React.FC = () => {

	const {
		exportLabel,
		importLabel,
		importDemoLabel,
		invalidImportFileContentsMessage,
	} = useContext(ImportExportStringsContext)

	const {
		createErrorNotice,
	} = useDispatch(noticesStore)

	const [isExportModalOpen, setIsExportModalOpen] = useState(false)
	const [isDemoExportModalOpen, setIsDemoExportModalOpen] = useState(false)
	const [isImportModalOpen, setIsImportModalOpen] = useState(false)
	const [isDemoImportModalOpen, setIsDemoImportModalOpen] = useState(IMPORT_DEMO)
	const [importValue, setImportValue] = useState({})

	const parseImportedFile = (value: string) => {

		let data

		try {
			data = JSON.parse(value)
		} catch(e) {
			createErrorNotice(invalidImportFileContentsMessage, {type: 'snackbar'})
		}

		const {
			__file,
		} = data

		if(__file !== SLUG) {
			createErrorNotice(invalidImportFileContentsMessage, {type: 'snackbar'})
			return
		}

		setImportValue(data)
		setIsImportModalOpen(true)
	}

	return <>
		<Button
			variant='primary'
			size='small'
			{...(IS_SETTINGS_PAGE && {
				icon: upload,
				iconSize: 16,
			})}
			// disabled={value === null}
			children={exportLabel}
			onClick={() => setIsExportModalOpen(true)}
		/>
		{CAN_EXPORT_DEMO && (
			<Button
				variant='primary'
				size='small'
				{...(IS_SETTINGS_PAGE && {
					icon: cloudUpload,
					iconSize: 16,
				})}
				children={'Export demo'}
				onClick={() => setIsDemoExportModalOpen(true)}
			/>
		)}
		<FormFileUpload
			// Trigger onChange when importing same file twice
			key={`content-import-btn-${isImportModalOpen ? '1' : '2'}`}
			// @ts-ignore
			variant='primary'
			size='small'
			{...(IS_SETTINGS_PAGE && {
				icon: download,
				iconSize: 16,
			})}
			// disabled={value === null}
			children={importLabel}
			accept='.json'
			onChange={e => {
				const files = e.currentTarget.files
				if(!files || !files?.length) {
					return
				}
				files[0].text().then(parseImportedFile)
			}}
		/>
		{CAN_IMPORT_DEMO && (
			<Button
				variant='primary'
				size='small'
				{...(IS_SETTINGS_PAGE && {
					icon: cloudDownload,
					iconSize: 16,
				})}
				children={importDemoLabel}
				onClick={() => setIsDemoImportModalOpen(true)}
			/>
		)}
		{isExportModalOpen && <ExportModal onRequestClose={() => setIsExportModalOpen(false)} />}
		{isDemoExportModalOpen && <DemoExportModal onRequestClose={() => setIsDemoExportModalOpen(false)} />}
		{isImportModalOpen && (
			<ImportModal
				valueToImport={importValue}
				onRequestClose={() => setIsImportModalOpen(false)}
			/>
		)}
		{isDemoImportModalOpen && <DemoImportModal onRequestClose={() => setIsDemoImportModalOpen(false)} />}
	</>
}

export default ImportExport
