import { useMutation } from '@tanstack/react-query'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import type {
  BumperTemplateDto,
  Daypart,
  GroupSummaryDto,
  JunctionAmountMode,
  JunctionConditions,
  JunctionElementDto,
  JunctionElementKind,
} from '@/shared/api/types'
import { Button } from '@/shared/ui/button'
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/shared/ui/dialog'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { removeJunctionElement, updateJunctionElement, type JunctionElementBody } from '../api'

const KINDS: JunctionElementKind[] = ['Ad', 'Promo', 'Bumper', 'Filler']
const AMOUNT_MODES: JunctionAmountMode[] = ['Count', 'Duration']
const DAYPARTS: Daypart[] = ['Morning', 'Day', 'Prime', 'Night']

const DEFAULT_CONDITIONS: JunctionConditions = {
  onlyOnElementChange: false,
  minMinutesBetween: 0,
  dayparts: null,
  timeWindow: null,
  chance: 100,
  nearHourMinutes: 0,
}

function toBody(element: JunctionElementDto): JunctionElementBody {
  return {
    kind: element.kind,
    groupId: element.groupId,
    bumperTemplateId: element.bumperTemplateId,
    bumperVariantId: element.bumperVariantId,
    amountMode: element.amountMode,
    amountValue: element.amountValue,
    isRequired: element.isRequired,
    choiceKey: element.choiceKey,
    choiceWeight: element.choiceWeight,
    conditions: element.conditions ?? DEFAULT_CONDITIONS,
  }
}

/** Параметры одной врезки: тип, источник, сколько её и при каких условиях ставить. */
export function JunctionElementDialog({
  junctionId,
  element,
  groups,
  bumpers,
  onClose,
  onChanged,
  onError,
}: Readonly<{
  junctionId: string
  element: JunctionElementDto
  groups: GroupSummaryDto[] | undefined
  bumpers: BumperTemplateDto[] | undefined
  onClose: () => void
  onChanged: () => void
  onError: (error: unknown) => void
}>) {
  const { t } = useTranslation()
  const [body, setBody] = useState<JunctionElementBody>(() => toBody(element))

  const patch = (part: Partial<JunctionElementBody>) => setBody((prev) => ({ ...prev, ...part }))
  const conditions = body.conditions ?? DEFAULT_CONDITIONS
  const setConditions = (part: Partial<JunctionConditions>) =>
    patch({ conditions: { ...conditions, ...part } })

  const save = useMutation({
    mutationFn: () => updateJunctionElement(junctionId, element.id, body),
    onSuccess: () => {
      onChanged()
      onClose()
    },
    onError,
  })
  const remove = useMutation({
    mutationFn: () => removeJunctionElement(junctionId, element.id),
    onSuccess: () => {
      onChanged()
      onClose()
    },
    onError,
  })

  const isBumper = body.kind === 'Bumper'
  const template = bumpers?.find((b) => b.id === body.bumperTemplateId)
  const window = conditions.timeWindow

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="flex max-h-[90vh] w-[calc(100%-2rem)] max-w-3xl flex-col">
        <DialogHeader>
          <DialogTitle>{t('admin.junctions.element')}</DialogTitle>
        </DialogHeader>

        {/* Две колонки: слева что играет, справа когда. Их читают вместе — «заставка при смене шоу
            в шести случаях из десяти» — и в одну колонку это разъезжалось на два экрана прокрутки. */}
        <div className="grid flex-1 grid-cols-1 items-start gap-x-6 gap-y-3 overflow-y-auto text-sm sm:grid-cols-2">
          <div className="flex flex-col gap-3">
            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.junctions.kind')}</Label>
              <select
                className="h-9 rounded-md border border-border bg-transparent px-2"
                value={body.kind}
                onChange={(e) => patch({ kind: e.target.value as JunctionElementKind })}
              >
                {KINDS.map((kind) => (
                  <option key={kind} value={kind}>
                    {t(`admin.junctions.kinds.${kind}`)}
                  </option>
                ))}
              </select>
            </div>

            {isBumper ? (
              <>
                <div className="flex flex-col gap-1.5">
                  <Label>{t('admin.junctions.bumperTemplate')}</Label>
                  <select
                    className="h-9 rounded-md border border-border bg-transparent px-2"
                    value={body.bumperTemplateId ?? ''}
                    onChange={(e) =>
                      patch({ bumperTemplateId: e.target.value || null, bumperVariantId: null })
                    }
                  >
                    <option value="">{t('admin.junctions.pickBumper')}</option>
                    {(bumpers ?? []).map((bumper) => (
                      <option key={bumper.id} value={bumper.id}>
                        {bumper.name}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>{t('admin.junctions.bumperVariant')}</Label>
                  <select
                    className="h-9 rounded-md border border-border bg-transparent px-2"
                    value={body.bumperVariantId ?? ''}
                    onChange={(e) => patch({ bumperVariantId: e.target.value || null })}
                  >
                    <option value="">{t('admin.junctions.bumperVariantAuto')}</option>
                    {(template?.variants ?? []).map((variant) => (
                      <option key={variant.id} value={variant.id}>
                        {variant.name}
                      </option>
                    ))}
                  </select>
                  <p className="text-xs text-muted-foreground">
                    {t('admin.junctions.bumperVariantHint')}
                  </p>
                </div>
              </>
            ) : (
              <div className="flex flex-col gap-1.5">
                <Label>{t('admin.junctions.group')}</Label>
                <select
                  className="h-9 rounded-md border border-border bg-transparent px-2"
                  value={body.groupId ?? ''}
                  onChange={(e) => patch({ groupId: e.target.value || null })}
                >
                  <option value="">{t('admin.junctions.pickGroup')}</option>
                  {(groups ?? []).map((group) => (
                    <option key={group.id} value={group.id}>
                      {group.name} · {group.itemCount}
                    </option>
                  ))}
                </select>
              </div>
            )}

            {!isBumper && (
              <>
                <div className="grid grid-cols-2 gap-2">
                  <div className="flex flex-col gap-1.5">
                    <Label>{t('admin.junctions.amountMode')}</Label>
                    <select
                      className="h-9 rounded-md border border-border bg-transparent px-2"
                      value={body.amountMode}
                      onChange={(e) => patch({ amountMode: e.target.value as JunctionAmountMode })}
                    >
                      {AMOUNT_MODES.map((mode) => (
                        <option key={mode} value={mode}>
                          {t(`admin.junctions.amountModes.${mode}`)}
                        </option>
                      ))}
                    </select>
                  </div>
                  <div className="flex flex-col gap-1.5">
                    <Label>
                      {body.amountMode === 'Count'
                        ? t('admin.junctions.count')
                        : t('admin.junctions.minutes')}
                    </Label>
                    <Input
                      type="number"
                      min={1}
                      value={body.amountValue}
                      onChange={(e) => patch({ amountValue: Number(e.target.value) })}
                    />
                  </div>
                </div>
                <p className="text-xs text-muted-foreground">{t('admin.junctions.amountHint')}</p>
              </>
            )}

            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={body.isRequired}
                onChange={(e) => patch({ isRequired: e.target.checked })}
              />
              {t('admin.junctions.required')}
            </label>
            <p className="-mt-2 text-xs text-muted-foreground">
              {t('admin.junctions.requiredHint')}
            </p>

            {/* Вес внутри развилки виден только когда врезка в развилке — иначе это лишнее поле. */}
            {body.choiceKey && (
              <div className="flex flex-col gap-1.5">
                <Label>{t('admin.junctions.choiceWeight')}</Label>
                <Input
                  type="number"
                  min={0}
                  max={1000}
                  className="w-32"
                  value={body.choiceWeight}
                  onChange={(e) =>
                    patch({ choiceWeight: Math.max(0, Math.round(Number(e.target.value)) || 0) })
                  }
                />
                <p className="text-xs text-muted-foreground">
                  {t('admin.junctions.choiceWeightHint')}
                </p>
              </div>
            )}
          </div>

          <div className="flex flex-col gap-3">
            <div className="border-t border-border pt-3 text-xs uppercase tracking-wide text-muted-foreground">
              {t('admin.junctions.conditions')}
            </div>

            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={conditions.onlyOnElementChange}
                onChange={(e) => setConditions({ onlyOnElementChange: e.target.checked })}
              />
              {t('admin.junctions.onlyOnChange')}
            </label>

            <div className="grid grid-cols-2 gap-2">
              <div className="flex flex-col gap-1.5">
                <Label>{t('admin.junctions.chance')}</Label>
                <Input
                  type="number"
                  min={0}
                  max={100}
                  value={conditions.chance}
                  onChange={(e) =>
                    setConditions({
                      chance: Math.min(100, Math.max(0, Math.round(Number(e.target.value)) || 0)),
                    })
                  }
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label>{t('admin.junctions.minInterval')}</Label>
                <Input
                  type="number"
                  min={0}
                  value={conditions.minMinutesBetween}
                  onChange={(e) => setConditions({ minMinutesBetween: Number(e.target.value) })}
                />
              </div>
            </div>
            <p className="-mt-1 text-xs text-muted-foreground">{t('admin.junctions.chanceHint')}</p>

            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.junctions.nearHour')}</Label>
              <div className="flex items-center gap-2">
                <Input
                  type="number"
                  className="w-32"
                  min={0}
                  max={30}
                  value={conditions.nearHourMinutes}
                  onChange={(e) =>
                    setConditions({
                      nearHourMinutes: Math.min(
                        30,
                        Math.max(0, Math.round(Number(e.target.value)) || 0),
                      ),
                    })
                  }
                />
                <span className="text-xs text-muted-foreground">
                  {t('admin.junctions.nearHourUnit')}
                </span>
              </div>
              <p className="text-xs text-muted-foreground">{t('admin.junctions.nearHourHint')}</p>
            </div>

            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.junctions.dayparts')}</Label>
              <div className="flex flex-wrap gap-2">
                {DAYPARTS.map((daypart) => {
                  const active = conditions.dayparts?.includes(daypart) ?? false
                  return (
                    <button
                      key={daypart}
                      type="button"
                      onClick={() => {
                        const current = conditions.dayparts ?? []
                        const next = active
                          ? current.filter((d) => d !== daypart)
                          : [...current, daypart]
                        setConditions({ dayparts: next.length === 0 ? null : next })
                      }}
                      className={`rounded border px-2 py-1 text-xs ${
                        active
                          ? 'border-primary text-primary'
                          : 'border-border text-muted-foreground'
                      }`}
                    >
                      {t(`admin.channels.dayparts.${daypart}`)}
                    </button>
                  )
                })}
              </div>
              <p className="text-xs text-muted-foreground">{t('admin.junctions.daypartsHint')}</p>
            </div>

            <div className="flex flex-col gap-1.5">
              <Label>{t('admin.junctions.timeWindow')}</Label>
              <div className="flex items-center gap-2">
                <Input
                  type="time"
                  className="w-32"
                  value={window?.from.slice(0, 5) ?? ''}
                  onChange={(e) =>
                    setConditions({
                      timeWindow: e.target.value
                        ? { from: e.target.value, to: window?.to ?? '23:59' }
                        : null,
                    })
                  }
                />
                <span className="text-muted-foreground">—</span>
                <Input
                  type="time"
                  className="w-32"
                  value={window?.to.slice(0, 5) ?? ''}
                  onChange={(e) =>
                    setConditions({
                      timeWindow: e.target.value
                        ? { from: window?.from ?? '00:00', to: e.target.value }
                        : null,
                    })
                  }
                />
                {window && (
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => setConditions({ timeWindow: null })}
                  >
                    {t('admin.junctions.clearWindow')}
                  </Button>
                )}
              </div>
              <p className="text-xs text-muted-foreground">{t('admin.junctions.timeWindowHint')}</p>
            </div>
          </div>
        </div>

        <DialogFooter>
          <Button size="sm" variant="destructive" onClick={() => remove.mutate()}>
            {t('common.delete')}
          </Button>
          <Button size="sm" disabled={save.isPending} onClick={() => save.mutate()}>
            {t('common.save')}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
