import type { ActionArgs } from '@remix-run/node'
import { json, redirect } from '@remix-run/node'
import { Form, useActionData } from '@remix-run/react'
import * as React from 'react'
import z from 'zod'

import { createTimeEntry } from '~/models/timeEntry.server'
import { requireUserId } from '~/session.server'

export async function action({ request }: ActionArgs) {
  const userId = await requireUserId(request)

  const formData = await request.formData()
  const description = formData.get('description')
  const projectId = formData.get('projectId')
  let startTime = formData.get('startTime')
  let endTime = formData.get('endTime')

  if (typeof description !== 'string' || description.length === 0) {
    return json({ errors: { description: 'Description is required' } }, { status: 400 })
  }
  if (typeof projectId !== 'string' || projectId.length === 0) {
    return json({ errors: { projectId: 'projectId is required' } }, { status: 400 })
  }
  if (typeof startTime !== 'string' || startTime.length === 0) {
    return json({ errors: { startTime: 'startTime is required' } }, { status: 400 })
  }

  if (startTime && typeof startTime === 'string' && Number.isNaN(Date.parse(startTime))) {
    return json({ errors: { startTime: 'startTime is invalid' } }, { status: 422 })
  }
  if (endTime && typeof endTime === 'string' && Number.isNaN(Date.parse(endTime))) {
    return json({ errors: { endTime: 'endTime is invalid' } }, { status: 422 })
  }
  if (
    startTime &&
    endTime &&
    typeof startTime === 'string' &&
    typeof endTime === 'string' &&
    new Date(startTime) > new Date(endTime)
  ) {
    return json({ errors: { endTime: 'startTime must be before endTime' } }, { status: 422 })
  }

  const timeEntry = await createTimeEntry({
    description,
    startTime: new Date(startTime),
    endTime: typeof endTime === 'string' ? new Date(endTime) : null,
    userId,
    projectId
  })

  return redirect(`/time-entries/${timeEntry.id}`)
}

export default function NewNotePage() {
  const actionData = useActionData<typeof action>()
  const titleRef = React.useRef<HTMLInputElement>(null)
  const bodyRef = React.useRef<HTMLTextAreaElement>(null)

  React.useEffect(() => {
    if (actionData?.errors?.title) {
      titleRef.current?.focus()
    } else if (actionData?.errors?.body) {
      bodyRef.current?.focus()
    }
  }, [actionData])

  return (
    <Form
      method="post"
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: 8,
        width: '100%'
      }}
    >
      <div>
        <label className="flex w-full flex-col gap-1">
          <span>Title: </span>
          <input
            ref={titleRef}
            name="title"
            className="flex-1 rounded-md border-2 border-blue-500 px-3 text-lg leading-loose"
            aria-invalid={actionData?.errors?.title ? true : undefined}
            aria-errormessage={actionData?.errors?.title ? 'title-error' : undefined}
          />
        </label>
        {actionData?.errors?.title && (
          <div className="pt-1 text-red-700" id="title-error">
            {actionData.errors.title}
          </div>
        )}
      </div>

      <div>
        <label className="flex w-full flex-col gap-1">
          <span>Body: </span>
          <textarea
            ref={bodyRef}
            name="body"
            rows={8}
            className="w-full flex-1 rounded-md border-2 border-blue-500 py-2 px-3 text-lg leading-6"
            aria-invalid={actionData?.errors?.body ? true : undefined}
            aria-errormessage={actionData?.errors?.body ? 'body-error' : undefined}
          />
        </label>
        {actionData?.errors?.body && (
          <div className="pt-1 text-red-700" id="body-error">
            {actionData.errors.body}
          </div>
        )}
      </div>

      <div className="text-right">
        <button type="submit" className="rounded bg-blue-500  py-2 px-4 text-white hover:bg-blue-600 focus:bg-blue-400">
          Save
        </button>
      </div>
    </Form>
  )
}
