'use client'

import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useTransition } from 'react'
import type { DatePreset, StatusFilter } from '@/lib/filters'

export type FilterValue = {
  date?: DatePreset
  start?: string
  end?: string
  status?: StatusFilter
  batch?: string
  q?: string
}

export type FilterOptions = {
  operators?: string[] | null
  clients?: string[] | null
  projects?: string[] | null
  users?: string[] | null
  source_emails?: string[] | null
}

type Props = {
  showStatus?: boolean
  showBatch?: boolean
  showQuery?: boolean
  showPivots?: boolean
  /**
   * When `showPivots` is true, hide the Project pivot specifically.
   * Used by `/` (Summary) where rows are already grouped by project, so
   * filtering by project would just hide rows.
   */
  hideProjectPivot?: boolean
  /**
   * When `showPivots` is true, also hide the Date select. Useful for
   * pages with their own date controls (e.g. `/` uses a month picker).
   */
  hideDate?: boolean
  batches?: { id: string; label: string }[]
  options?: FilterOptions
  /** Shown in the date select when no `?date=` param is in the URL. */
  defaultDate?: DatePreset
  /** Shown in the status select when no `?status=` param is in the URL. */
  defaultStatus?: StatusFilter
  /** Renders a "Clear filters" button that resets all filter params. */
  showClear?: boolean
  /** If provided (non-null), renders an "Imported by" select. */
  importers?: { id: string; label: string }[] | null
}

export function FilterBar({
  showStatus = false,
  showBatch = false,
  showQuery = false,
  showPivots = false,
  hideProjectPivot = false,
  hideDate = false,
  batches = [],
  options = {},
  defaultDate = 'this-month',
  defaultStatus = 'all',
  showClear = false,
  importers = null,
}: Props) {
  const router = useRouter()
  const pathname = usePathname()
  const params = useSearchParams()
  const [, startTransition] = useTransition()

  const date = (params.get('date') ?? defaultDate) as FilterValue['date']
  const start = params.get('start') ?? ''
  const end = params.get('end') ?? ''
  const status = (params.get('status') ?? defaultStatus) as FilterValue['status']
  const batch = params.get('batch') ?? 'all'
  const q = params.get('q') ?? ''
  const operator = params.get('operator') ?? ''
  const client = params.get('client') ?? ''
  const project = params.get('project') ?? ''
  const user = params.get('user') ?? ''
  const sourceEmail = params.get('source_email') ?? ''
  const importedBy = params.get('imported_by') ?? ''

  function update(patch: Partial<Record<string, string | undefined>>) {
    const next = new URLSearchParams(params)
    for (const [k, v] of Object.entries(patch)) {
      if (v == null || v === '') {
        next.delete(k)
      } else {
        next.set(k, v)
      }
    }
    next.delete('page')
    startTransition(() => {
      router.push(`${pathname}?${next.toString()}`)
    })
  }

  function pivotSelect(
    label: string,
    paramKey: string,
    currentValue: string,
    optionList: string[] | null | undefined,
  ) {
    // If the option list is provided (even empty), render a select; otherwise
    // fall back to a free-text input for the dimension.
    if (optionList === undefined) {
      return (
        <label key={paramKey}>
          {label}
          <input
            type="search"
            placeholder="contains…"
            defaultValue={currentValue}
            onChange={(e) => update({ [paramKey]: e.target.value })}
          />
        </label>
      )
    }
    const list = optionList ?? []
    // If the current value isn't in the list (e.g. filter is narrowing it),
    // still include it so the user can see what's selected.
    const allValues = currentValue && !list.includes(currentValue)
      ? [currentValue, ...list]
      : list
    return (
      <label key={paramKey}>
        {label}
        <select
          value={currentValue}
          onChange={(e) => update({ [paramKey]: e.target.value })}
        >
          <option value="">All</option>
          {allValues.map((v) => (
            <option key={v} value={v}>
              {v}
            </option>
          ))}
        </select>
      </label>
    )
  }

  return (
    <div className="toolbar">
      {!hideDate && (
        <label>
          Dates
          <select
            value={date}
            onChange={(e) => update({ date: e.target.value, start: '', end: '' })}
          >
            <option value="this-month">This month</option>
            <option value="last-month">Last month</option>
            <option value="custom">Custom range</option>
            <option value="all">All dates</option>
          </select>
        </label>
      )}

      {!hideDate && date === 'custom' && (
        <>
          <label>
            From
            <input
              type="date"
              value={start}
              onChange={(e) => update({ start: e.target.value })}
            />
          </label>
          <label>
            To
            <input
              type="date"
              value={end}
              onChange={(e) => update({ end: e.target.value })}
            />
          </label>
        </>
      )}

      {showStatus && (
        <label>
          Status
          <select
            value={status}
            onChange={(e) => update({ status: e.target.value })}
          >
            <option value="all">All statuses</option>
            <option value="pending">Pending</option>
            <option value="transferred">Applied to invoice</option>
            <option value="blocked">Blocked</option>
          </select>
        </label>
      )}

      {showBatch && batches.length > 0 && (
        <label>
          Batch
          <select
            value={batch}
            onChange={(e) => update({ batch: e.target.value })}
          >
            <option value="all">All batches</option>
            {batches.map((b) => (
              <option key={b.id} value={b.id}>
                {b.label}
              </option>
            ))}
          </select>
        </label>
      )}

      {importers && importers.length > 0 && (
        <label>
          Imported by
          <select
            value={importedBy}
            onChange={(e) => update({ imported_by: e.target.value })}
          >
            <option value="">All importers</option>
            {importers.map((i) => (
              <option key={i.id} value={i.id}>
                {i.label}
              </option>
            ))}
          </select>
        </label>
      )}

      {showPivots && (
        <>
          {pivotSelect('Operator', 'operator', operator, options.operators)}
          {pivotSelect('Client', 'client', client, options.clients)}
          {!hideProjectPivot &&
            pivotSelect('Project', 'project', project, options.projects)}
          {pivotSelect('User', 'user', user, options.users)}
          {pivotSelect(
            'Source email',
            'source_email',
            sourceEmail,
            options.source_emails,
          )}
        </>
      )}

      {showQuery && (
        <label>
          Search
          <input
            type="search"
            placeholder="project / desc / email / client"
            defaultValue={q}
            onChange={(e) => update({ q: e.target.value })}
          />
        </label>
      )}

      {showClear && (
        <button
          type="button"
          onClick={() => {
            startTransition(() => {
              router.push(pathname)
            })
          }}
          className="secondary"
          style={{ alignSelf: 'end', padding: '0.4rem 0.85rem' }}
        >
          Clear filters
        </button>
      )}
    </div>
  )
}
