import { Button, Flex, Modal, Spinner, TextareaControl } from '@wordpress/components'
import { __ } from '@wordpress/i18n'
import { isAxiosError } from 'axios'
import React, { useRef, useState } from 'react'
import { useGenerativeAPI } from '../../../hooks/useGenerativeAPI'
import { getSnippetType } from '../../../utils/snippets/snippets'
import { useSnippetForm } from '../../../hooks/useSnippetForm'
import { GenerateIcon } from '../../common/icons/GenerateIcon'
import type { Snippet } from '../../../types/Snippet'
import type { Dispatch, FormEventHandler, SetStateAction } from 'react'

interface PromptFormProps {
	snippet: Snippet
	prompt: string
	setPrompt: Dispatch<SetStateAction<string>>
	isWaiting: boolean
	errorMessage: string | undefined
	onGenerate: FormEventHandler
}

const PromptForm: React.FC<PromptFormProps> = ({
	snippet,
	prompt,
	setPrompt,
	isWaiting,
	errorMessage,
	onGenerate
}) => {
	const formRef = useRef<HTMLFormElement>(null)

	return (
		<form ref={formRef} onSubmit={onGenerate}>
			<TextareaControl
				rows={2}
				help={__('Code generated by AI may be inaccurate.', 'code-snippets')}
				label={__('What would you like to do?', 'code-snippets')}
				value={prompt}
				disabled={isWaiting}
				onChange={value => setPrompt(value)}
				autoFocus
				onKeyDown={event => {
					if (formRef.current && !event.shiftKey && 'Enter' === event.key) {
						event.preventDefault()
						formRef.current.requestSubmit()
					}
				}}
			/>

			{'string' === typeof errorMessage
				? <div className="notice notice-error">
					<p>{`${__('An error occurred attempting to contact the API.')} ${errorMessage}`}</p>
				</div> : null}

			{snippet.name || snippet.code || snippet.tags.length || snippet.desc
				? <p><strong>{__('This action will overwrite the current snippet, including the title and description.')}</strong></p>
				: null}

			<Flex direction="row" justify="flex-end">
				{isWaiting ? <Spinner /> : ''}
				<Button variant="primary" type="submit" disabled={isWaiting}>
					{isWaiting ? __('Generating…', 'code-snippets') : __('Generate', 'code-snippets')}
				</Button>
			</Flex>
		</form>
	)
}

export interface GenerateCodeModalProps {
	show: boolean
	onClose: VoidFunction
}

export const GenerateCodeModal: React.FC<GenerateCodeModalProps> = ({ show, onClose }) => {
	const { snippet, updateSnippet } = useSnippetForm()
	const { generateSnippet } = useGenerativeAPI()
	const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)
	const [isWaiting, setIsWaiting] = useState(false)
	const [prompt, setPrompt] = useState('')

	const onGenerate: FormEventHandler = event => {
		event.preventDefault()
		setIsWaiting(true)
		setErrorMessage(undefined)

		generateSnippet(prompt, getSnippetType(snippet))
			.then(generated => {
				updateSnippet(previous => ({ ...previous, ...generated }))
				setIsWaiting(false)
				onClose()
			})
			.catch((error: unknown) => {
				setIsWaiting(false)
				setErrorMessage(isAxiosError(error) ? error.message : '')
			})
	}

	return show
		? <Modal
			icon={<GenerateIcon />}
			title={__('Generate with Cloud AI', 'code-snippets')}
			onRequestClose={() => onClose()}
			className="cloud-create-modal"
		>
			<PromptForm
				snippet={snippet}
				prompt={prompt}
				setPrompt={setPrompt}
				isWaiting={isWaiting}
				errorMessage={errorMessage}
				onGenerate={onGenerate}
			/>
		</Modal>
		: null
}
