import FieldError from '@/components/common/FieldError'
import PostImportStatusBadge from '@/components/posts/import/PostImportStatusBadge'
import ThumbnailPreview from '@/components/posts/import/ThumbnailPreview'
import { Button } from '@/components/ui/button'
import { Dialog,
	 DialogContent,
	 DialogDescription,
	 DialogFooter,
	 DialogHeader,
	 DialogTitle } from '@/components/ui/dialog'
import { inputClass } from '@/lib/utils'

import type { FC } from 'react'
import { useEffect, useState } from 'react'

import type { PostImportOrigin,
	      PostImportRow } from '@/lib/postImportSession'

type Draft = {
    url:                   string
    title:                 string
    thumbnailBase:         string
    originalCreatedFrom:   string
    originalCreatedBefore: string
    duration:              string
    tags:                  string
    parentPostIds:         string }

type Props = {
    open:         boolean
    row:          PostImportRow | null
    saving:       boolean
    onOpenChange: (open: boolean) => void
    onSave:       (draft: Draft) => Promise<boolean> }

const originOf = (
    row:   PostImportRow,
    field: string,
): PostImportOrigin =>
    row.provenance[field] ?? 'automatic'

const buildDraft = (row: PostImportRow): Draft => ({
    url: row.url,
    title: String (row.attributes.title ?? ''),
    thumbnailBase: String (row.attributes.thumbnailBase ?? ''),
    originalCreatedFrom: String (row.attributes.originalCreatedFrom ?? ''),
    originalCreatedBefore: String (row.attributes.originalCreatedBefore ?? ''),
    duration: String (row.attributes.duration ?? ''),
    tags: String (row.attributes.tags ?? ''),
    parentPostIds: String (row.attributes.parentPostIds ?? '') })


const PostImportRowDialog: FC<Props> = (
    { open, row, saving, onOpenChange, onSave },
) => {
    const [draft, setDraft] = useState<Draft | null> (null)

    useEffect (() => {
	if (open && row)
	  setDraft (buildDraft (row))
    }, [open, row])

    if (!(row) || !(draft))
      return null

    const update = <Key extends keyof Draft,> (
	key:   Key,
	value: Draft[Key],
    ) => {
	setDraft (current =>
	    current ? { ...current, [key]: value } : current)
    }

    const save = async () => {
	if (await onSave (draft))
	  onOpenChange (false)
    }

    return (
	<Dialog open={open} onOpenChange={onOpenChange}>
	  <DialogContent className="max-w-3xl px-6 pb-6 pt-7">
	    <DialogHeader className="pl-8">
	      <DialogTitle>投稿 {row.sourceRow} を編集</DialogTitle>
	      <DialogDescription>
		自動取得結果を確認し、必要な項目だけ修正してください．
	      </DialogDescription>
	    </DialogHeader>

	    <div className="grid gap-6 md:grid-cols-[7rem_minmax(0,1fr)]">
	      <div className="space-y-3">
		<ThumbnailPreview
		    url={draft.thumbnailBase}
		    className="h-28 w-28"/>
		<div className="flex flex-wrap gap-2">
		  <PostImportStatusBadge value={row.status}/>
		  <PostImportStatusBadge value={row.importStatus ?? 'pending'}/>
		</div>
	      </div>

	      <div className="space-y-4">
		<DialogField
		    label="URL"
		    value={draft.url}
		    origin={originOf (row, 'url')}
		    onChange={value => update ('url', value)}/>
		<DialogField
		    label="タイトル"
		    value={draft.title}
		    origin={originOf (row, 'title')}
		    onChange={value => update ('title', value)}/>
		<DialogField
		    label="サムネール基底 URL"
		    value={draft.thumbnailBase}
		    origin={originOf (row, 'thumbnailBase')}
		    onChange={value => update ('thumbnailBase', value)}/>
		<div className="grid gap-4 md:grid-cols-2">
		  <DialogField
		      label="作成日時 From"
		      value={draft.originalCreatedFrom}
		      origin={originOf (row, 'originalCreatedFrom')}
		      onChange={value => update ('originalCreatedFrom', value)}/>
		  <DialogField
		      label="作成日時 Before"
		      value={draft.originalCreatedBefore}
		      origin={originOf (row, 'originalCreatedBefore')}
		      onChange={value => update ('originalCreatedBefore', value)}/>
		</div>
		<DialogField
		    label="動画時間"
		    value={draft.duration}
		    origin={originOf (row, 'duration')}
		    onChange={value => update ('duration', value)}/>
		<DialogArea
		    label="タグ"
		    value={draft.tags}
		    origin={originOf (row, 'tags')}
		    onChange={value => update ('tags', value)}/>
		<DialogField
		    label="親投稿"
		    value={draft.parentPostIds}
		    origin={originOf (row, 'parentPostIds')}
		    onChange={value => update ('parentPostIds', value)}/>
		<FieldError messages={Object.values (row.validationErrors ?? { }).flat ()}/>
		<FieldError messages={Object.values (row.importErrors ?? { }).flat ()}/>
	      </div>
	    </div>

	    <DialogFooter>
	      <Button
		  type="button"
		  variant="outline"
		  onClick={() => onOpenChange (false)}>
		取消し
	      </Button>
	      <Button
		  type="button"
		  onClick={save}
		  disabled={saving}>
		保存
	      </Button>
	    </DialogFooter>
	  </DialogContent>
	</Dialog>)
}

const DialogField = (
    { label, value, origin, onChange }: {
	label:    string
	value:    string
	origin:   PostImportOrigin
	onChange: (value: string) => void },
) => (
    <label className="block space-y-1">
      <span className="flex items-center gap-2 text-sm font-medium">
	{label}
	<PostImportStatusBadge value={origin}/>
      </span>
      <input
	  value={value}
	  onChange={ev => onChange (ev.target.value)}
	  className={inputClass (false)}/>
    </label>)

const DialogArea = (
    { label, value, origin, onChange }: {
	label:    string
	value:    string
	origin:   PostImportOrigin
	onChange: (value: string) => void },
) => (
    <label className="block space-y-1">
      <span className="flex items-center gap-2 text-sm font-medium">
	{label}
	<PostImportStatusBadge value={origin}/>
      </span>
      <textarea
	  value={value}
	  rows={4}
	  onChange={ev => onChange (ev.target.value)}
	  className={inputClass (false)}/>
    </label>)

export default PostImportRowDialog
