import { useMemo, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { getEntity } from '../api/entitiesApi'
import {
  buildTaskPreviewPrompt,
  createTask,
  generateTaskPreview,
  type EmailLookback,
} from '../api/tasksApi'

interface TaskFormState {
  name: string
  prompt: string
  scheduleCron: string
  emailLookback: EmailLookback
}

interface CronParts {
  minute: string
  hour: string
  dayOfMonth: string
  month: string
  dayOfWeek: string
}

interface RegularitySuggestion {
  id: string
  label: string
  description: string
  cronParts: CronParts
}

const DEFAULT_CRON_PARTS: CronParts = {
  minute: '0',
  hour: '9',
  dayOfMonth: '*',
  month: '*',
  dayOfWeek: '1-5',
}

const REGULARITY_SUGGESTIONS: RegularitySuggestion[] = [
  {
    id: 'daily',
    label: 'Daily',
    description: 'Every day at 09:00',
    cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '*' },
  },
  {
    id: 'weekdays',
    label: 'Weekdays',
    description: 'Monday to Friday at 09:00',
    cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '1-5' },
  },
  {
    id: 'weekly',
    label: 'Weekly',
    description: 'Every Monday at 09:00',
    cronParts: { minute: '0', hour: '9', dayOfMonth: '*', month: '*', dayOfWeek: '1' },
  },
  {
    id: 'monthly',
    label: 'Monthly',
    description: 'Day 1 of each month at 09:00',
    cronParts: { minute: '0', hour: '9', dayOfMonth: '1', month: '*', dayOfWeek: '*' },
  },
]

function buildCron(parts: CronParts): string {
  return [parts.minute, parts.hour, parts.dayOfMonth, parts.month, parts.dayOfWeek].join(' ')
}

const DEFAULT_TASK_FORM: TaskFormState = {
  name: '',
  prompt: '',
  scheduleCron: buildCron(DEFAULT_CRON_PARTS),
  emailLookback: 'last_week',
}

export default function CreateTaskPage() {
  const { entityId = '' } = useParams()
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const [cronParts, setCronParts] = useState<CronParts>(DEFAULT_CRON_PARTS)
  const [taskForm, setTaskForm] = useState<TaskFormState>(DEFAULT_TASK_FORM)
  const [preview, setPreview] = useState('')
  const [previewError, setPreviewError] = useState('')

  const { data: entity, isLoading } = useQuery({
    queryKey: ['entity', entityId],
    queryFn: () => getEntity(entityId),
    enabled: Boolean(entityId),
  })

  const createTaskMutation = useMutation({
    mutationFn: createTask,
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['entity-tasks', entityId] })
      navigate(`/entities/${entityId}`)
    },
  })

  const previewMutation = useMutation({
    mutationFn: generateTaskPreview,
    onMutate: () => {
      setPreview('')
      setPreviewError('')
    },
    onSuccess: (value) => setPreview(value),
    onError: (error) => {
      setPreviewError(
        error instanceof Error
          ? error.message
          : 'Unable to generate a test message from the local model.'
      )
    },
  })

  const canSubmit = useMemo(() => {
    const hasFilledCronParts = Object.values(cronParts).every((value) => value.trim().length > 0)
    return Boolean(taskForm.name.trim() && taskForm.prompt.trim() && hasFilledCronParts)
  }, [cronParts, taskForm.name, taskForm.prompt])

  const currentTask = useMemo(
    () => ({
      entityId,
      name: taskForm.name,
      prompt: taskForm.prompt,
      scheduleCron: taskForm.scheduleCron,
      emailLookback: taskForm.emailLookback,
    }),
    [entityId, taskForm.emailLookback, taskForm.name, taskForm.prompt, taskForm.scheduleCron]
  )

  const finalPrompt = useMemo(() => {
    if (!entity) {
      return 'Entity details unavailable.'
    }

    return buildTaskPreviewPrompt(entity, currentTask)
  }, [currentTask, entity])

  const applyCronParts = (nextCronParts: CronParts) => {
    setCronParts(nextCronParts)
    setTaskForm((prev) => ({ ...prev, scheduleCron: buildCron(nextCronParts) }))
  }

  const regularitySummary = useMemo(
    () =>
      `At ${cronParts.hour.padStart(2, '0')}:${cronParts.minute.padStart(2, '0')} - day ${cronParts.dayOfMonth}, month ${cronParts.month}, week day ${cronParts.dayOfWeek}`,
    [cronParts.dayOfMonth, cronParts.dayOfWeek, cronParts.hour, cronParts.minute, cronParts.month]
  )

  if (!entityId) {
    return <div className="p-8 text-sm text-slate-300">Entity identifier is missing.</div>
  }

  if (isLoading) {
    return <div className="p-8 text-sm text-slate-300">Loading...</div>
  }

  return (
    <div className="min-h-screen overflow-y-auto bg-slate-950 py-8">
      <div className="mx-auto max-w-2xl px-4 sm:px-6">
        <nav className="mb-6">
          <Link
            to={`/entities/${entityId}`}
            className="text-sm text-cyan-400 hover:text-cyan-300"
          >
            ← Back to {entity?.name ?? 'Entity'}
          </Link>
        </nav>

        <h1 className="text-2xl font-bold text-slate-100">
          New Task
          {entity && (
            <span className="ml-2 text-base font-normal text-slate-400">— {entity.name}</span>
          )}
        </h1>

        <form
          className="mt-6 space-y-6"
          onSubmit={(event) => {
            event.preventDefault()
            if (!canSubmit) return
            createTaskMutation.mutate({
              entityId,
              name: taskForm.name,
              prompt: taskForm.prompt,
              scheduleCron: taskForm.scheduleCron,
              emailLookback: taskForm.emailLookback,
            })
          }}
        >
          <div>
            <label htmlFor="task-name" className="text-sm font-medium text-slate-200">
              Task Name
            </label>
            <input
              id="task-name"
              value={taskForm.name}
              onChange={(event) => setTaskForm((prev) => ({ ...prev, name: event.target.value }))}
              className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100"
              required
            />
          </div>

          <div>
            <label htmlFor="task-prompt" className="text-sm font-medium text-slate-200">
              Task Prompt
            </label>
            <textarea
              id="task-prompt"
              value={taskForm.prompt}
              onChange={(event) =>
                setTaskForm((prev) => ({ ...prev, prompt: event.target.value }))
              }
              className="mt-1 min-h-36 w-full rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100"
              required
            />
          </div>

          <div>
            <label htmlFor="task-lookback" className="text-sm font-medium text-slate-200">
              Email Period
            </label>
            <select
              id="task-lookback"
              value={taskForm.emailLookback}
              onChange={(event) =>
                setTaskForm((prev) => ({
                  ...prev,
                  emailLookback: event.target.value as EmailLookback,
                }))
              }
              className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100"
            >
              <option value="last_day">Last 24 hours</option>
              <option value="last_week">Last week</option>
              <option value="last_month">Last month</option>
            </select>
          </div>

          <div className="rounded-md border border-slate-800 bg-slate-900/60 p-4">
            <p className="text-sm font-medium text-slate-200">Task Schedule</p>
            <p className="mt-1 text-xs text-slate-400">
              Pick a regularity then fine-tune each cron field. Use <code className="text-slate-300">*</code> for "every".
            </p>
            <div className="mt-3 grid gap-2 sm:grid-cols-2">
              {REGULARITY_SUGGESTIONS.map((suggestion) => (
                <button
                  key={suggestion.id}
                  type="button"
                  className="rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-left text-slate-200 hover:border-cyan-500/70"
                  onClick={() => applyCronParts(suggestion.cronParts)}
                >
                  <span className="block text-sm font-semibold">{suggestion.label}</span>
                  <span className="block text-xs text-slate-400">{suggestion.description}</span>
                </button>
              ))}
            </div>
            <div className="mt-4 grid grid-cols-2 gap-3 sm:grid-cols-5">
              <div>
                <label htmlFor="cron-minute" className="text-xs font-medium text-slate-300">
                  Minute
                </label>
                <input
                  id="cron-minute"
                  type="text"
                  value={cronParts.minute}
                  onChange={(event) =>
                    applyCronParts({ ...cronParts, minute: event.target.value })
                  }
                  className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-2 py-2 text-sm text-slate-100"
                  placeholder="0-59 or *"
                />
              </div>
              <div>
                <label htmlFor="cron-hour" className="text-xs font-medium text-slate-300">
                  Hour
                </label>
                <input
                  id="cron-hour"
                  type="text"
                  value={cronParts.hour}
                  onChange={(event) =>
                    applyCronParts({ ...cronParts, hour: event.target.value })
                  }
                  className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-2 py-2 text-sm text-slate-100"
                  placeholder="0-23 or *"
                />
              </div>
              <div>
                <label htmlFor="cron-day-of-month" className="text-xs font-medium text-slate-300">
                  Day of Month
                </label>
                <input
                  id="cron-day-of-month"
                  type="text"
                  value={cronParts.dayOfMonth}
                  onChange={(event) =>
                    applyCronParts({ ...cronParts, dayOfMonth: event.target.value })
                  }
                  className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-2 py-2 text-sm text-slate-100"
                  placeholder="1-31 or *"
                />
              </div>
              <div>
                <label htmlFor="cron-month" className="text-xs font-medium text-slate-300">
                  Month
                </label>
                <input
                  id="cron-month"
                  type="text"
                  value={cronParts.month}
                  onChange={(event) =>
                    applyCronParts({ ...cronParts, month: event.target.value })
                  }
                  className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-2 py-2 text-sm text-slate-100"
                  placeholder="1-12 or *"
                />
              </div>
              <div>
                <label htmlFor="cron-day-of-week" className="text-xs font-medium text-slate-300">
                  Day of Week
                </label>
                <input
                  id="cron-day-of-week"
                  type="text"
                  value={cronParts.dayOfWeek}
                  onChange={(event) =>
                    applyCronParts({ ...cronParts, dayOfWeek: event.target.value })
                  }
                  className="mt-1 w-full rounded-md border border-slate-700 bg-slate-900 px-2 py-2 text-sm text-slate-100"
                  placeholder="0-7 or *"
                />
              </div>
            </div>
            <p className="mt-3 text-xs text-slate-400">{regularitySummary}</p>
            <p className="mt-1 text-xs text-slate-500">Cron: {taskForm.scheduleCron}</p>
          </div>

          <div className="rounded-md border border-slate-800 bg-slate-900 p-4">
            <button
              type="button"
              onClick={() => {
                if (!canSubmit) return
                if (!entity) return
                previewMutation.mutate({ entity, task: currentTask })
              }}
              disabled={!canSubmit || previewMutation.isPending}
              className="rounded-md border border-cyan-500 px-3 py-2 text-sm font-medium text-cyan-300 hover:bg-cyan-500/10 disabled:opacity-50"
            >
              {previewMutation.isPending ? 'Generating…' : 'Generate Test Message'}
            </button>

            <div className="mt-4">
              <p className="text-xs font-semibold uppercase tracking-wide text-slate-400">
                Final Prompt
              </p>
              <pre className="mt-2 whitespace-pre-wrap rounded-md bg-slate-950 p-4 text-xs text-slate-200">
                {finalPrompt}
              </pre>
            </div>

            {previewError && (
              <p role="alert" className="mt-4 text-sm text-red-300">
                {previewError}
              </p>
            )}

            {preview && (
              <div className="mt-4">
                <p className="text-xs font-semibold uppercase tracking-wide text-slate-400">
                  Generated Message
                </p>
                <pre className="mt-2 whitespace-pre-wrap rounded-md bg-slate-950 p-4 text-xs text-slate-200">
                  {preview}
                </pre>
              </div>
            )}
          </div>

          <div className="flex justify-end gap-3 pb-8">
            <button
              type="button"
              onClick={() => navigate(`/entities/${entityId}`)}
              className="rounded-md border border-slate-700 px-4 py-2 text-sm text-slate-200 hover:border-slate-500"
            >
              Cancel
            </button>
            <button
              type="submit"
              className="rounded-md bg-cyan-500 px-4 py-2 text-sm font-semibold text-slate-950 hover:bg-cyan-400 disabled:opacity-50"
              disabled={!canSubmit || createTaskMutation.isPending}
            >
              {createTaskMutation.isPending ? 'Creating…' : 'Create Task'}
            </button>
          </div>
        </form>
      </div>
    </div>
  )
}
