import React, { useLayoutEffect, useRef, useState } from "react"
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Spinner } from "@/components/ui/spinner"
import { ReactSelect } from "@/components/ui/react-select"
import {
  SubStage,
  CreateSubStageDto,
  UpdateSubStageDto,
} from "@/api/rtk/pipelines-api"
import {
  useCreateSubStageMutation,
  useUpdateSubStageMutation,
} from "@/api/rtk/pipelines-api"
import { useGetPipelineStageNamesQuery } from "@/api/rtk/pipeline-stage-names-api"
import { useAuthToken } from "@/hooks/use-auth-token"
import { filterForbiddenStageNames } from "@/lib/stage-name-filter"

interface SubStageModalProps {
  isOpen: boolean
  onClose: () => void
  stageNameId: string
  subStage?: SubStage
  onSuccess: () => void
}

const toTrimmedString = (value: unknown): string => {
  if (typeof value === "string") {
    return value.trim()
  }
  return ""
}

interface SubStageModalBodyProps {
  stageNameId: string
  subStage?: SubStage
  onClose: () => void
  onSuccess: () => void
  isBusyRef: React.MutableRefObject<boolean>
}

/**
 * Remounted via `key` when opening add vs edit or changing stage so form state
 * resets without a sync `setState` inside `useEffect`.
 */
function SubStageModalBody({
  stageNameId,
  subStage,
  onClose,
  onSuccess,
  isBusyRef,
}: SubStageModalBodyProps) {
  const { token } = useAuthToken()
  const [formData, setFormData] = useState({
    name: subStage?.name || "",
    stageNameId: subStage?.stageNameId || stageNameId || "",
    color: subStage?.color || "#6C63FF",
    prob: subStage?.prob?.toString() || "",
  })

  const { data: pipelineStageNamesResponse, isLoading: isLoadingStageNames } =
    useGetPipelineStageNamesQuery({ limit: 1000 }, {
      skip: !token,
    })
  const stageNames = React.useMemo(
    () => filterForbiddenStageNames(pipelineStageNamesResponse?.data ?? []),
    [pipelineStageNamesResponse],
  )

  const [createSubStage, { isLoading: isCreating }] = useCreateSubStageMutation()
  const [updateSubStage, { isLoading: isUpdating }] = useUpdateSubStageMutation()

  const isLoading = isCreating || isUpdating || isLoadingStageNames

  useLayoutEffect(() => {
    isBusyRef.current = isLoading
  }, [isBusyRef, isLoading])

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()

    const currentStageNameId = toTrimmedString(formData.stageNameId)
    const name = toTrimmedString(formData.name)
    const color = toTrimmedString(formData.color)
    const parsedProb = toTrimmedString(formData.prob)
    const prob = parsedProb ? parseInt(parsedProb, 10) : undefined

    if (!currentStageNameId) {
      alert("Please select a stage name")
      return
    }

    try {
      const submitData: CreateSubStageDto | UpdateSubStageDto = {
        name: name || undefined,
        stageNameId: currentStageNameId,
        color: color || undefined,
        prob: Number.isFinite(prob) ? prob : undefined,
      }

      if (subStage) {
        await updateSubStage({ id: subStage.id, body: submitData }).unwrap()
      } else {
        await createSubStage(submitData as CreateSubStageDto).unwrap()
      }

      onSuccess()
      onClose()
    } catch (error) {
      console.error(
        "Failed to save sub-stage:",
        error instanceof Error ? error.message : String(error),
      )
    }
  }

  const handleClose = () => {
    if (!isLoading) {
      onClose()
    }
  }

  return (
    <>
      <DialogHeader>
        <DialogTitle>
          {subStage ? "Edit Sub-Stage" : "Add Sub-Stage"}
        </DialogTitle>
      </DialogHeader>
      <form onSubmit={handleSubmit} className="space-y-4">
        <div className="space-y-2">
          <Label htmlFor="stageNameId">Name (Stage Name) *</Label>
          <ReactSelect
            id="stageNameId"
            value={formData.stageNameId}
            onValueChange={(value) => {
              const selected = stageNames.find((sn) => sn.id === value)
              setFormData((prev) => ({
                ...prev,
                stageNameId: typeof value === "string" ? value : "",
                name:
                  typeof selected?.name === "string"
                    ? selected.name
                    : prev.name,
              }))
            }}
            disabled={isLoading}
            options={stageNames.map((sn) => ({
              value: sn.id,
              label: sn.name,
            }))}
            placeholder="Select a stage name"
            aria-label="Stage name"
          />
        </div>

        <div className="space-y-2">
          <Label htmlFor="name">Custom Display Name (Optional)</Label>
          <Input
            id="name"
            value={formData.name}
            onChange={(e) =>
              setFormData((prev) => ({ ...prev, name: e.target.value }))
            }
            placeholder="Override display name"
            disabled={isLoading}
          />
        </div>

        <div className="space-y-2">
          <Label htmlFor="color">Color</Label>
          <div className="flex gap-2">
            <Input
              id="color"
              type="color"
              value={formData.color}
              onChange={(e) =>
                setFormData((prev) => ({ ...prev, color: e.target.value }))
              }
              className="w-20 h-10"
              disabled={isLoading}
            />
            <Input
              value={formData.color}
              onChange={(e) =>
                setFormData((prev) => ({ ...prev, color: e.target.value }))
              }
              placeholder="#6C63FF"
              disabled={isLoading}
            />
          </div>
        </div>

        <div className="space-y-2">
          <Label htmlFor="prob">Probability (%)</Label>
          <Input
            id="prob"
            type="number"
            min="0"
            max="100"
            value={formData.prob}
            onChange={(e) =>
              setFormData((prev) => ({ ...prev, prob: e.target.value }))
            }
            placeholder="0-100"
            disabled={isLoading}
          />
        </div>

        <div className="flex justify-end gap-2 pt-4">
          <Button
            type="button"
            variant="outline"
            onClick={handleClose}
            disabled={isLoading}
          >
            Cancel
          </Button>
          <Button type="submit" disabled={isLoading}>
            {isLoading ? (
              <>
                <Spinner className="mr-2 h-4 w-4" />
                {subStage ? "Updating..." : "Creating..."}
              </>
            ) : subStage ? (
              "Update Sub-Stage"
            ) : (
              "Create Sub-Stage"
            )}
          </Button>
        </div>
      </form>
    </>
  )
}

export function SubStageModal({
  isOpen,
  onClose,
  stageNameId,
  subStage,
  onSuccess,
}: SubStageModalProps) {
  const isBusyRef = useRef(false)
  const resetKey = `${subStage?.id ?? "new"}:${stageNameId}`

  const handleOpenChange = (open: boolean) => {
    if (!open && !isBusyRef.current) {
      onClose()
    }
  }

  return (
    <Dialog open={isOpen} onOpenChange={handleOpenChange}>
      <DialogContent
        className="sm:max-w-[425px]"
        onPointerDownOutside={(e) => {
          if (isBusyRef.current) e.preventDefault()
        }}
        onEscapeKeyDown={(e) => {
          if (isBusyRef.current) e.preventDefault()
        }}
      >
        {isOpen ? (
          <SubStageModalBody
            key={resetKey}
            stageNameId={stageNameId}
            subStage={subStage}
            onClose={onClose}
            onSuccess={onSuccess}
            isBusyRef={isBusyRef}
          />
        ) : null}
      </DialogContent>
    </Dialog>
  )
}
