"use client"

import { useMemo, useState } from "react"
import { useQuery } from "convex/react"
import type { Id } from "@/convex/_generated/dataModel"
import { api } from "@/convex/_generated/api"
import { toast } from "sonner"

import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"

type QuickCreateUserDialogProps = {
  open: boolean
  onOpenChange(open: boolean): void
  tenantId: string
  viewerId: string | null
  onSuccess?(payload: { email: string }): void
}

type PortalRole = "MANAGER" | "COLLABORATOR"

const ROLE_OPTIONS: ReadonlyArray<{ value: PortalRole; label: string }> = [
  { value: "MANAGER", label: "Gestor" },
  { value: "COLLABORATOR", label: "Colaborador" },
]

const ROLE_TO_PAYLOAD: Record<PortalRole, "manager" | "collaborator"> = {
  MANAGER: "manager",
  COLLABORATOR: "collaborator",
}

const NO_COMPANY_VALUE = "__none__"
const NO_MANAGER_VALUE = "__no_manager__"

type QuickUserFormState = {
  name: string
  email: string
  jobTitle: string
  role: PortalRole
  companyId: string
  managerId: string
}

function defaultForm(): QuickUserFormState {
  return {
    name: "",
    email: "",
    jobTitle: "",
    role: "COLLABORATOR",
    companyId: NO_COMPANY_VALUE,
    managerId: NO_MANAGER_VALUE,
  }
}

export function QuickCreateUserDialog({ open, onOpenChange, tenantId, viewerId, onSuccess }: QuickCreateUserDialogProps) {
  const [form, setForm] = useState<QuickUserFormState>(defaultForm)
  const [isSubmitting, setIsSubmitting] = useState(false)

  const canQuery = open && Boolean(viewerId)
  const companies = useQuery(
    api.companies.list,
    canQuery ? { tenantId, viewerId: viewerId as Id<"users"> } : "skip"
  ) as Array<{ id: string; name: string; slug?: string }> | undefined
  const customers = useQuery(
    api.users.listCustomers,
    canQuery ? { tenantId, viewerId: viewerId as Id<"users"> } : "skip"
  ) as Array<{ id: string; name: string; email: string; role: string }> | undefined

  const companyOptions = useMemo<SearchableComboboxOption[]>(() => {
    const base: SearchableComboboxOption[] = [{ value: NO_COMPANY_VALUE, label: "Sem empresa vinculada" }]
    if (!companies) return base
    const sorted = [...companies].sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
    return [
      ...base,
      ...sorted.map((company) => ({
        value: company.id,
        label: company.name,
      })),
    ]
  }, [companies])

  const managerOptions = useMemo<SearchableComboboxOption[]>(() => {
    const base: SearchableComboboxOption[] = [{ value: NO_MANAGER_VALUE, label: "Sem gestor" }]
    if (!customers) return base
    const managers = customers.filter((user) => user.role === "MANAGER")
    return [
      ...base,
      ...managers.map((manager) => ({
        value: manager.id,
        label: manager.name,
        description: manager.email,
      })),
    ]
  }, [customers])

  const resetForm = () => {
    setForm(defaultForm)
  }

  const handleClose = () => {
    if (isSubmitting) return
    resetForm()
    onOpenChange(false)
  }

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    if (!viewerId) {
      toast.error("Não foi possível identificar o usuário atual.")
      return
    }
    const name = form.name.trim()
    const email = form.email.trim().toLowerCase()
    if (!name) {
      toast.error("Informe o nome do usuário.")
      return
    }
    if (!email || !email.includes("@")) {
      toast.error("Informe um e-mail válido.")
      return
    }
    const jobTitle = form.jobTitle.trim()
    const managerId = form.managerId !== NO_MANAGER_VALUE ? form.managerId : null
    const companyId = form.companyId !== NO_COMPANY_VALUE ? form.companyId : null

    const payload = {
      name,
      email,
      role: ROLE_TO_PAYLOAD[form.role],
      tenantId,
      jobTitle: jobTitle || null,
      managerId,
    }

    setIsSubmitting(true)
    try {
      const response = await fetch("/api/admin/users", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(payload),
      })
      if (!response.ok) {
        const data = await response.json().catch(() => null)
        throw new Error(data?.error ?? "Não foi possível criar o usuário.")
      }
      const data = (await response.json()) as { user: { email: string }; temporaryPassword?: string }

      if (companyId) {
        const assignResponse = await fetch("/api/admin/users/assign-company", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          credentials: "include",
          body: JSON.stringify({ email, companyId }),
        })
        if (!assignResponse.ok) {
          const assignData = await assignResponse.json().catch(() => null)
          toast.error(assignData?.error ?? "Usuário criado, mas não foi possível vinculá-lo à empresa.")
        }
      }

      resetForm()
      onOpenChange(false)
      onSuccess?.({ email })
      toast.success("Usuário criado com sucesso.", {
        description: data.temporaryPassword ? `Senha temporária: ${data.temporaryPassword}` : undefined,
        action: data.temporaryPassword
          ? {
              label: "Copiar",
              onClick: async () => {
                try {
                  await navigator.clipboard?.writeText?.(data.temporaryPassword ?? "")
                  toast.success("Senha copiada para a área de transferência.")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Não foi possível copiar a senha."
                  toast.error(message)
                }
              },
            }
          : undefined,
      })
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao criar usuário."
      toast.error(message)
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={(next) => (next ? onOpenChange(next) : handleClose())}>
      <DialogContent className="max-w-lg space-y-6">
        <DialogHeader>
          <DialogTitle>Novo usuário</DialogTitle>
          <DialogDescription>Crie acessos para gestores ou colaboradores sem sair da página atual.</DialogDescription>
        </DialogHeader>
        <form className="space-y-5" onSubmit={handleSubmit}>
          <div className="grid gap-2">
            <Label htmlFor="quick-user-name">Nome</Label>
            <Input
              id="quick-user-name"
              value={form.name}
              onChange={(event) => setForm((prev) => ({ ...prev, name: event.target.value }))}
              placeholder="Nome completo"
              disabled={isSubmitting}
              required
            />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="quick-user-email">E-mail</Label>
            <Input
              id="quick-user-email"
              type="email"
              value={form.email}
              onChange={(event) => setForm((prev) => ({ ...prev, email: event.target.value }))}
              placeholder="usuario@empresa.com"
              disabled={isSubmitting}
              required
            />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="quick-user-job-title">Cargo</Label>
            <Input
              id="quick-user-job-title"
              value={form.jobTitle}
              onChange={(event) => setForm((prev) => ({ ...prev, jobTitle: event.target.value }))}
              placeholder="Ex.: Analista de Suporte"
              disabled={isSubmitting}
            />
          </div>
          <div className="grid gap-2">
            <Label>Papel</Label>
            <Select
              value={form.role}
              onValueChange={(value) => setForm((prev) => ({ ...prev, role: value as PortalRole }))}
              disabled={isSubmitting}
            >
              <SelectTrigger>
                <SelectValue placeholder="Selecione" />
              </SelectTrigger>
              <SelectContent>
                {ROLE_OPTIONS.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="grid gap-2">
            <Label>Gestor direto</Label>
            <SearchableCombobox
              value={form.managerId}
              onValueChange={(value) =>
                setForm((prev) => ({
                  ...prev,
                  managerId: value === null ? NO_MANAGER_VALUE : value,
                }))
              }
              options={managerOptions}
              placeholder="Sem gestor definido"
              searchPlaceholder="Buscar gestor..."
              disabled={isSubmitting || !customers}
              allowClear
              clearLabel="Remover gestor"
            />
          </div>
          <div className="grid gap-2">
            <Label>Empresa vinculada</Label>
            <SearchableCombobox
              value={form.companyId}
              onValueChange={(value) =>
                setForm((prev) => ({
                  ...prev,
                  companyId: value === null ? NO_COMPANY_VALUE : value,
                }))
              }
              options={companyOptions}
              placeholder="Sem empresa vinculada"
              searchPlaceholder="Buscar empresa..."
              disabled={isSubmitting || !companies}
            />
          </div>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button type="button" variant="ghost" onClick={handleClose} disabled={isSubmitting}>
              Cancelar
            </Button>
            <Button type="submit" disabled={isSubmitting}>
              {isSubmitting ? "Criando..." : "Criar usuário"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}
