'use client'

import { useState } from 'react'
import Link from 'next/link'
import { usePathname, useSearchParams } from 'next/navigation'
import { createEntry } from './actions'
import type { TeamMemberOption } from '@/lib/teams'

type Props = {
  /** Same shape + behavior as EditRow's three datalists. */
  operatorNames: string[]
  clientNames: string[]
  projectNames: string[]
  /** Lowercase client-name → list of operators it appears under. */
  clientNameToOperators: Record<string, string[]>
  /** Lowercase project-name → list of (operator, client) pairs. */
  projectNameToParents: Record<string, { operator: string; client: string }[]>
  /** Lowercase operator-name → clients under it (strict narrow when op picked). */
  clientsByOperator: Record<string, string[]>
  /** Lowercase `${op}|${cl}` → projects under that pair (strict narrow). */
  projectsByClientPair: Record<string, string[]>
  /** Team-member options for the "Team member" picker. */
  teamMembers: TeamMemberOption[]
  /** Default email/name to pre-fill — the current user's. Used to
   * auto-select the matching team_member in the dropdown. */
  defaultEmail: string
  defaultName: string
  /** colSpan for the wrapping <tr><td>. Matches the table width. */
  colSpan: number
}

/**
 * Inline "new entry" form rendered as a single row at the top of the
 * /entries table when `?new=1` is in the URL. Same cascading combobox
 * behavior as EditRow: type or pick from the dropdown; client/project
 * changes auto-fill the parent fields; operator change clears children.
 *
 * Defaults: date = today (server-rendered would be more accurate, but
 * for now we let the user pick); start time = 00:00:00; source email
 * = current user; billable = true.
 */
export function NewEntryRow({
  operatorNames,
  clientNames,
  projectNames,
  clientNameToOperators,
  projectNameToParents,
  clientsByOperator,
  projectsByClientPair,
  teamMembers,
  defaultEmail,
  defaultName,
  colSpan,
}: Props) {
  const pathname = usePathname()
  const params = useSearchParams()

  // Build the return URL: drop the `new` param so the form doesn't
  // re-render after redirect.
  const returnUrl = (() => {
    const p = new URLSearchParams(params.toString())
    p.delete('new')
    return `${pathname}?${p.toString()}`
  })()

  // Today as YYYY-MM-DD in the user's local tz.
  const today = (() => {
    const d = new Date()
    const y = d.getFullYear()
    const m = (d.getMonth() + 1).toString().padStart(2, '0')
    const dd = d.getDate().toString().padStart(2, '0')
    return `${y}-${m}-${dd}`
  })()

  const [date, setDate] = useState(today)
  const [startTime, setStartTime] = useState('')
  const [duration, setDuration] = useState('')
  const [operatorVal, setOperatorVal] = useState('')
  const [clientVal, setClientVal] = useState('')

  // Datalist sources, narrowed by the currently-picked parent (same
  // pattern as EditRow). Without this, picking a client surfaces
  // duplicate-named projects from other clients in the project
  // dropdown — the bug rian reported on 2026-05-27.
  const opKey = operatorVal.trim().toLowerCase()
  const clKey = clientVal.trim().toLowerCase()
  const filteredClientNames = opKey
    ? (clientsByOperator[opKey] ?? [])
    : clientNames
  const filteredProjectNames =
    opKey && clKey
      ? (projectsByClientPair[`${opKey}|${clKey}`] ?? [])
      : projectNames
  const [projectVal, setProjectVal] = useState('')
  const [description, setDescription] = useState('')
  // Default the team_member picker to the current user's row, if any.
  // The server action stamps source_user_email + source_user_name from
  // the picked member, so we no longer need separate inputs for them.
  const defaultTeamMemberId =
    teamMembers.find(
      (m) => m.email.toLowerCase() === defaultEmail.toLowerCase(),
    )?.id ?? ''
  const [teamMemberId, setTeamMemberId] = useState(defaultTeamMemberId)
  // `defaultName` arrives via props but is unused now — kept in the
  // signature for back-compat with callers; the picked team_member
  // determines the source identity.
  void defaultName

  function onOperatorBlur() {
    // Any change to operator clears child fields.
    if (operatorVal === '') return
    // Heuristic: if the operator differs from the LAST committed-known
    // operator the user had cascading-filled, we don't want to clear
    // unprompted. But for new-entry the form starts empty, so any
    // operator change to a known-or-unknown value is intentional. We
    // only clear if there was a non-empty client/project set before.
    // Simpler: do nothing on operator-blur for new-entry — the user
    // is filling top-down so cascading-clear isn't needed here. The
    // edit-mode behavior matters more there.
  }

  function onClientBlur() {
    if (clientVal === '') return
    const matches =
      clientNameToOperators[clientVal.toLowerCase()] ?? []
    if (matches.length === 1) setOperatorVal(matches[0])
  }

  function onProjectBlur() {
    if (projectVal === '') return
    const matches =
      projectNameToParents[projectVal.toLowerCase()] ?? []
    if (matches.length === 1) {
      setOperatorVal(matches[0].operator)
      setClientVal(matches[0].client)
    }
  }

  const opListId = 'new-op-list'
  const clListId = 'new-cl-list'
  const prListId = 'new-pr-list'

  const labelStyle: React.CSSProperties = { fontSize: '0.78rem', gap: '0.2rem' }
  const inputStyle: React.CSSProperties = {
    padding: '0.35rem 0.5rem',
    fontSize: '0.85rem',
  }

  return (
    <tr style={{ background: '#e0f2fe' }}>
      <td colSpan={colSpan} style={{ padding: '0.6rem 0.75rem' }}>
        <form action={createEntry}>
          <input type="hidden" name="_return_url" value={returnUrl} />
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(4, minmax(0, 1fr))',
              gap: '0.4rem 0.75rem',
              marginBottom: '0.5rem',
            }}
          >
            <label style={labelStyle}>
              Date
              <input
                name="date"
                type="date"
                value={date}
                onChange={(e) => setDate(e.target.value)}
                required
                style={inputStyle}
              />
            </label>
            <label style={labelStyle}>
              Start time <span className="muted">(optional)</span>
              <input
                name="start_time"
                type="time"
                step="1"
                value={startTime}
                onChange={(e) => setStartTime(e.target.value)}
                placeholder="00:00:00"
                style={inputStyle}
              />
            </label>
            <label style={labelStyle}>
              Duration{' '}
              <span className="muted">(HH:MM:SS or decimal hours)</span>
              <input
                name="duration"
                type="text"
                value={duration}
                onChange={(e) => setDuration(e.target.value)}
                placeholder="1:30:00"
                required
                style={inputStyle}
              />
            </label>
            <label style={labelStyle}>
              Description
              <input
                name="description"
                type="text"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                required
                style={inputStyle}
              />
            </label>

            <label style={labelStyle}>
              Operator
              <input
                name="operator"
                type="text"
                list={opListId}
                autoComplete="off"
                value={operatorVal}
                onChange={(e) => setOperatorVal(e.target.value)}
                onBlur={onOperatorBlur}
                style={inputStyle}
              />
              <datalist id={opListId}>
                {operatorNames.map((n) => (
                  <option key={n} value={n} />
                ))}
              </datalist>
            </label>
            <label style={labelStyle}>
              Client <span className="muted">(auto-fills operator)</span>
              <input
                name="client"
                type="text"
                list={clListId}
                autoComplete="off"
                value={clientVal}
                onChange={(e) => setClientVal(e.target.value)}
                onBlur={onClientBlur}
                style={inputStyle}
              />
              <datalist id={clListId}>
                {filteredClientNames.map((n) => (
                  <option key={n} value={n} />
                ))}
              </datalist>
            </label>
            <label style={labelStyle}>
              Project <span className="muted">(auto-fills both)</span>
              <input
                name="project"
                type="text"
                list={prListId}
                autoComplete="off"
                value={projectVal}
                onChange={(e) => setProjectVal(e.target.value)}
                onBlur={onProjectBlur}
                style={inputStyle}
              />
              <datalist id={prListId}>
                {filteredProjectNames.map((n) => (
                  <option key={n} value={n} />
                ))}
              </datalist>
            </label>
            <label style={labelStyle}>
              Team member{' '}
              <span className="muted">(picks the cost / billout rate)</span>
              <select
                name="team_member_id"
                value={teamMemberId}
                onChange={(e) => setTeamMemberId(e.target.value)}
                style={inputStyle}
              >
                <option value="">— pick one —</option>
                {Object.entries(
                  teamMembers.reduce<Record<string, TeamMemberOption[]>>(
                    (acc, m) => {
                      const key = m.team_name ?? '(unnamed team)'
                      ;(acc[key] ??= []).push(m)
                      return acc
                    },
                    {},
                  ),
                ).map(([teamName, members]) => (
                  <optgroup key={teamName} label={teamName}>
                    {members.map((m) => (
                      <option key={m.id} value={m.id}>
                        {m.display_name}
                        {m.consolidate_as ? ` → ${m.consolidate_as}` : ''}
                        {m.is_active ? '' : ' (inactive)'}
                        {' · '}
                        {m.email}
                      </option>
                    ))}
                  </optgroup>
                ))}
              </select>
            </label>
          </div>

          <div
            className="flex-row"
            style={{ gap: '0.5rem', alignItems: 'center' }}
          >
            <button type="submit">Create entry</button>
            <Link
              href={returnUrl}
              className="button-link-secondary"
              scroll={false}
            >
              Cancel
            </Link>
            <span className="muted" style={{ fontSize: '0.85em', marginLeft: '0.25rem' }}>
              Lands in your <em>Manual entries</em> batch. Cost + billout
              are computed from the picked team member&apos;s rates.
            </span>
          </div>
        </form>
      </td>
    </tr>
  )
}
