"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { useMutation, useQuery } from "convex/react"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"

import { useAuth } from "@/lib/auth-client"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { DEVICE_INVENTORY_COLUMN_METADATA, type DeviceInventoryColumnConfig } from "@/lib/device-inventory-columns"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Badge } from "@/components/ui/badge"
import { Checkbox } from "@/components/ui/checkbox"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"
import { Skeleton } from "@/components/ui/skeleton"
import { cn } from "@/lib/utils"
import { toast } from "sonner"

type DeviceExportTemplateListItem = {
  id: string
  slug: string
  name: string
  description?: string
  columns: DeviceInventoryColumnConfig[]
  filters?: unknown | null
  companyId: string | null
  isDefault: boolean
  isActive: boolean
  createdAt: number
  updatedAt: number
  createdBy?: string | null
  updatedBy?: string | null
}

type DeviceFieldDef = {
  id: string
  key: string
  label: string
}

type ReportTemplatesManagerProps = {
  tenantId?: string | null
}

const DEFAULT_COLUMN_KEYS = DEVICE_INVENTORY_COLUMN_METADATA.filter((meta) => meta.default !== false).map((meta) => meta.key)

export function ReportTemplatesManager({ tenantId: tenantIdProp }: ReportTemplatesManagerProps) {
  const { convexUserId, session, isAdmin } = useAuth()
  const tenantId = tenantIdProp ?? session?.user.tenantId ?? DEFAULT_TENANT_ID

  const [filterCompanyId, setFilterCompanyId] = useState<string>("all")
  const [editingTemplateId, setEditingTemplateId] = useState<string | null>(null)
  const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false)

  const canLoad = Boolean(convexUserId && isAdmin)

  const templates = useQuery(
    api.deviceExportTemplates.list,
    canLoad
      ? ({
          tenantId,
          viewerId: convexUserId as Id<"users">,
          companyId: filterCompanyId !== "all" ? (filterCompanyId as Id<"companies">) : undefined,
          includeInactive: true,
        } as const)
      : "skip"
  ) as DeviceExportTemplateListItem[] | undefined

  const deviceFields = useQuery(
    api.deviceFields.listForTenant,
    canLoad
      ? ({
          tenantId,
          viewerId: convexUserId as Id<"users">,
        } as const)
      : "skip"
  ) as DeviceFieldDef[] | undefined

  const companies = useQuery(
    api.companies.list,
    canLoad
      ? ({
          tenantId,
          viewerId: convexUserId as Id<"users">,
        } as const)
      : "skip"
  ) as Array<{ id: Id<"companies">; name: string }> | undefined

  const createTemplate = useMutation(api.deviceExportTemplates.create)
  const updateTemplate = useMutation(api.deviceExportTemplates.update)
  const removeTemplate = useMutation(api.deviceExportTemplates.remove)

  const companyOptions = useMemo<SearchableComboboxOption[]>(() => {
    const base: SearchableComboboxOption[] = [{ value: "all", label: "Todas as empresas" }]
    if (!companies || companies.length === 0) return base
    const sorted = [...companies].sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
    return [
      base[0],
      ...sorted.map((company) => ({
        value: company.id,
        label: company.name,
      })),
    ]
  }, [companies])

  const availableColumns = useMemo(
    () => {
      const base = DEVICE_INVENTORY_COLUMN_METADATA.map((meta) => ({
        key: meta.key,
        label: meta.label,
        group: "base" as const,
      }))
      const custom: { key: string; label: string; group: "custom" }[] =
        (deviceFields ?? []).map((field) => ({
          key: `custom:${field.key}`,
          label: field.label,
          group: "custom" as const,
        }))
      return [...base, ...custom].sort((a, b) => a.label.localeCompare(b.label, "pt-BR"))
    },
    [deviceFields]
  )

  const templateOptions = useMemo(
    () => (templates ?? []).slice().sort((a, b) => a.name.localeCompare(b.name, "pt-BR")),
    [templates]
  )

  const [name, setName] = useState("")
  const [description, setDescription] = useState("")
  const [targetCompanyId, setTargetCompanyId] = useState<string | "all">("all")
  const [isDefault, setIsDefault] = useState(false)
  const [isActive, setIsActive] = useState(true)
  const [selectedColumns, setSelectedColumns] = useState<string[]>([])
  const [isSaving, setIsSaving] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  const editingTemplate = useMemo(
    () => templateOptions.find((tpl) => tpl.id === editingTemplateId) ?? null,
    [templateOptions, editingTemplateId]
  )

  const resetForm = useCallback(() => {
    setName("")
    setDescription("")
    setTargetCompanyId("all")
    setIsDefault(false)
    setIsActive(true)
    setSelectedColumns([...DEFAULT_COLUMN_KEYS])
  }, [])

  useEffect(() => {
    if (!isTemplateDialogOpen) return
    if (!editingTemplateId) {
      resetForm()
      return
    }
    const tpl = templateOptions.find((t) => t.id === editingTemplateId)
    if (!tpl) {
      setEditingTemplateId(null)
      resetForm()
      return
    }
    setName(tpl.name)
    setDescription(tpl.description ?? "")
    setTargetCompanyId(tpl.companyId ?? "all")
    setIsDefault(Boolean(tpl.isDefault))
    setIsActive(tpl.isActive !== false)
    const columnKeys = (tpl.columns ?? []).map((col) => col.key)
    setSelectedColumns(columnKeys.length > 0 ? columnKeys : [...DEFAULT_COLUMN_KEYS])
  }, [editingTemplateId, isTemplateDialogOpen, resetForm, templateOptions])

  const handleToggleColumn = (key: string, checked: boolean) => {
    setSelectedColumns((prev) => {
      const set = new Set(prev)
      if (checked) {
        set.add(key)
      } else {
        set.delete(key)
      }
      return Array.from(set)
    })
  }

  const handleSelectAll = () => {
    setSelectedColumns(availableColumns.map((col) => col.key))
  }

  const handleClearColumns = () => {
    setSelectedColumns([])
  }

  const handleSave = async () => {
    if (!convexUserId) {
      toast.error("Sincronize a sessão antes de salvar templates.")
      return
    }
    const trimmedName = name.trim()
    if (trimmedName.length < 3) {
      toast.error("Informe um nome para o template (mínimo 3 caracteres).")
      return
    }
    if (selectedColumns.length === 0) {
      toast.error("Selecione ao menos uma coluna para o template.")
      return
    }
    const columnsPayload: DeviceInventoryColumnConfig[] = selectedColumns.map((key) => {
      const meta = availableColumns.find((col) => col.key === key)
      return { key, label: meta?.label }
    })
    const companyIdValue =
      targetCompanyId !== "all" ? (targetCompanyId as unknown as Id<"companies">) : undefined

    try {
      setIsSaving(true)
      if (!editingTemplate) {
        await createTemplate({
          tenantId,
          actorId: convexUserId as Id<"users">,
          name: trimmedName,
          description: description.trim() || undefined,
          columns: columnsPayload,
          filters: undefined,
          companyId: companyIdValue,
          isDefault,
          isActive,
        })
      } else {
        await updateTemplate({
          tenantId,
          actorId: convexUserId as Id<"users">,
          templateId: editingTemplate.id as Id<"deviceExportTemplates">,
          name: trimmedName,
          description: description.trim() || undefined,
          columns: columnsPayload,
          filters: editingTemplate.filters ?? undefined,
          companyId: companyIdValue,
          isDefault,
          isActive,
        })
      }
      toast.success("Template salvo com sucesso.")
      setIsTemplateDialogOpen(false)
      setEditingTemplateId(null)
      resetForm()
    } catch (error) {
      console.error("[report-templates] Failed to save template", error)
      toast.error("Não foi possível salvar o template.")
    } finally {
      setIsSaving(false)
    }
  }

  const handleDelete = async () => {
    if (!convexUserId || !editingTemplate) return
    try {
      setIsDeleting(true)
      await removeTemplate({
        tenantId,
        actorId: convexUserId as Id<"users">,
        templateId: editingTemplate.id as Id<"deviceExportTemplates">,
      })
      toast.success("Template removido com sucesso.")
      setIsTemplateDialogOpen(false)
      setEditingTemplateId(null)
      resetForm()
    } catch (error) {
      console.error("[report-templates] Failed to delete template", error)
      toast.error("Não foi possível remover o template.")
    } finally {
      setIsDeleting(false)
    }
  }

  const handleTemplateDialogOpenChange = useCallback(
    (open: boolean) => {
      if (!open) {
        if (isSaving || isDeleting) return
        setIsTemplateDialogOpen(false)
        setEditingTemplateId(null)
        resetForm()
        return
      }
      setIsTemplateDialogOpen(true)
    },
    [isDeleting, isSaving, resetForm]
  )

  const handleOpenCreateDialog = useCallback(() => {
    setEditingTemplateId(null)
    setIsTemplateDialogOpen(true)
  }, [])

  const handleTemplateRowClick = useCallback((templateId: string) => {
    setEditingTemplateId(templateId)
    setIsTemplateDialogOpen(true)
  }, [])

  if (!canLoad) {
    return (
      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle className="text-lg font-semibold text-neutral-900">Templates de relatórios</CardTitle>
          <CardDescription className="text-neutral-600">
            Apenas administradores podem gerenciar templates de exportação.
          </CardDescription>
        </CardHeader>
      </Card>
    )
  }

  if (!templates || !companies) {
    return (
      <div className="space-y-4">
        <Skeleton className="h-12 w-full rounded-xl" />
        <Skeleton className="h-64 w-full rounded-xl" />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <Card className="border-slate-200 rounded-2xl shadow-sm">
        <CardHeader>
          <CardTitle className="text-lg font-semibold text-neutral-900">Templates existentes</CardTitle>
          <CardDescription className="text-neutral-600">
            Configure templates globais ou por empresa para exportar inventário de dispositivos.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex flex-wrap items-center gap-3">
            <SearchableCombobox
              value={filterCompanyId}
              onValueChange={(value) => setFilterCompanyId(value ?? "all")}
              options={companyOptions}
              placeholder="Todas as empresas"
              triggerClassName="h-9 w-full min-w-56 rounded-full border border-slate-300 bg-white px-3 text-sm font-medium text-neutral-800 md:w-64"
            />
            <Button size="sm" className="gap-2" onClick={handleOpenCreateDialog}>
              Novo template
            </Button>
          </div>
          {templateOptions.length === 0 ? (
            <p className="rounded-lg border border-dashed border-slate-200 p-4 text-sm text-neutral-500">
              Nenhum template cadastrado ainda. Clique em &quot;Novo template&quot; para criar o primeiro modelo de exportação.
            </p>
          ) : (
            <div className="space-y-2">
              {templateOptions.map((tpl) => {
                const isActiveTemplate = isTemplateDialogOpen && editingTemplateId === tpl.id
                const columnCount = tpl.columns?.length ?? 0
                return (
                  <button
                    key={tpl.id}
                    type="button"
                    onClick={() => handleTemplateRowClick(tpl.id)}
                    className={cn(
                      "group flex w-full flex-col gap-2 rounded-xl border px-4 py-3 text-left text-sm transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-500 focus-visible:ring-offset-2",
                      isActiveTemplate
                        ? "border-neutral-900 bg-neutral-950 text-white shadow-[0_10px_25px_rgba(15,23,42,0.35)] hover:bg-neutral-900"
                        : "border-slate-200 bg-white text-neutral-900 hover:border-slate-300 hover:bg-slate-50"
                    )}
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="flex flex-col">
                        <span className={cn("font-semibold", isActiveTemplate ? "text-white" : "text-neutral-900")}>{tpl.name}</span>
                        <span className={cn("text-xs", isActiveTemplate ? "text-white/70" : "text-neutral-500")}>
                          {tpl.companyId ? "Template específico por empresa" : "Template global"} · {columnCount}{" "}
                          {columnCount === 1 ? "coluna" : "colunas"}
                        </span>
                      </div>
                      <div className="flex items-center gap-2">
                        {tpl.isDefault ? (
                          <Badge
                            variant="outline"
                            className={cn(
                              "text-[10px] uppercase",
                              isActiveTemplate ? "border-white/40 text-white hover:bg-white/5" : "border-slate-200 bg-slate-50 text-slate-700"
                            )}
                          >
                            Padrão
                          </Badge>
                        ) : null}
                        {tpl.isActive === false ? (
                          <Badge
                            variant="outline"
                            className={cn(
                              "text-[10px] uppercase",
                              isActiveTemplate ? "border-white/40 text-amber-100" : "border-amber-200 bg-amber-50 text-amber-800"
                            )}
                          >
                            Inativo
                          </Badge>
                        ) : null}
                      </div>
                    </div>
                    {tpl.description ? (
                      <p className={cn("text-xs leading-relaxed", isActiveTemplate ? "text-white/80" : "text-neutral-500")}>{tpl.description}</p>
                    ) : null}
                  </button>
                )
              })}
            </div>
          )}
        </CardContent>
      </Card>

      <Dialog open={isTemplateDialogOpen} onOpenChange={handleTemplateDialogOpenChange}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>{editingTemplate ? "Editar template" : "Novo template"}</DialogTitle>
            <DialogDescription>
              Defina o conjunto de colunas e, opcionalmente, vincule o template a uma empresa específica.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-6">
            <div className="space-y-3">
              <label className="text-sm font-medium text-neutral-800">
                Nome do template <span className="text-destructive">*</span>
              </label>
              <Input
                value={name}
                onChange={(event) => setName(event.target.value)}
                placeholder="Ex.: Inventário padrão, Inventário reduzido..."
                className="h-9 rounded-lg border-slate-300 text-sm"
              />
            </div>
            <div className="space-y-3">
              <label className="text-sm font-medium text-neutral-800">Descrição</label>
              <Textarea
                value={description}
                onChange={(event) => setDescription(event.target.value)}
                placeholder="Contexto de uso, filtros sugeridos, etc."
                rows={3}
                className="rounded-lg border-slate-300 text-sm"
              />
            </div>
            <div className="grid gap-3 md:grid-cols-2">
              <div className="space-y-2">
                <label className="text-sm font-medium text-neutral-800">Escopo do template</label>
                <div className="rounded-xl border border-slate-200 bg-slate-50 px-3 py-2">
                  <SearchableCombobox
                    value={targetCompanyId}
                    onValueChange={(value) => setTargetCompanyId(value ?? "all")}
                    options={companyOptions}
                    placeholder="Todas as empresas"
                    triggerClassName="h-9 w-full rounded-full border border-slate-300 bg-white px-3 text-sm font-medium text-neutral-800"
                  />
                  <p className="mt-2 text-xs text-neutral-500">
                    Defina se este template será global ou específico para uma empresa.
                  </p>
                </div>
              </div>
              <div className="space-y-2">
                <label className="text-sm font-medium text-neutral-800">Opções</label>
                <div className="space-y-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2">
                  <label className="flex items-center gap-2 text-xs text-neutral-700">
                    <Checkbox checked={isDefault} onCheckedChange={(v) => setIsDefault(Boolean(v))} />
                    <span>Usar como padrão para este escopo</span>
                  </label>
                  <label className="flex items-center gap-2 text-xs text-neutral-700">
                    <Checkbox checked={isActive} onCheckedChange={(v) => setIsActive(Boolean(v))} />
                    <span>Template ativo</span>
                  </label>
                </div>
              </div>
            </div>

            <div className="space-y-3">
              <div className="flex flex-wrap items-center justify-between gap-2">
                <span className="text-sm font-medium text-neutral-800">Colunas incluídas</span>
                <div className="flex items-center gap-2">
                  <Button type="button" size="sm" variant="outline" onClick={handleClearColumns} disabled={isSaving || isDeleting}>
                    Limpar
                  </Button>
                  <Button type="button" size="sm" variant="outline" onClick={handleSelectAll} disabled={isSaving || isDeleting}>
                    Selecionar todas
                  </Button>
                </div>
              </div>
              <div className="max-h-72 space-y-1 overflow-y-auto rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-sm">
                {availableColumns.length === 0 ? (
                  <p className="py-2 text-xs text-neutral-500">
                    Nenhuma coluna disponível. Verifique o inventário de dispositivos e os campos personalizados.
                  </p>
                ) : (
                  availableColumns.map((col) => {
                    const checked = selectedColumns.includes(col.key)
                    const isCustom = col.group === "custom"
                    return (
                      <label
                        key={col.key}
                        className="flex cursor-pointer items-center gap-2 rounded-md bg-white px-2 py-1.5 text-xs text-neutral-800 shadow-[0_0_0_1px_rgba(148,163,184,0.3)] hover:bg-slate-50"
                      >
                        <Checkbox
                          checked={checked}
                          onCheckedChange={(v) => handleToggleColumn(col.key, Boolean(v))}
                          className="size-4"
                          disabled={isSaving || isDeleting}
                        />
                        <span className="flex-1 truncate">
                          {col.label}
                          {isCustom ? " (campo personalizado)" : ""}
                        </span>
                      </label>
                    )
                  })
                )}
              </div>
              <p className="text-xs text-neutral-500">{selectedColumns.length} coluna{selectedColumns.length === 1 ? "" : "s"} selecionada{selectedColumns.length === 1 ? "" : "s"}.</p>
            </div>
          </div>
          <DialogFooter className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
            {editingTemplate ? (
              <Button
                type="button"
                variant="outline"
                onClick={handleDelete}
                disabled={isDeleting || isSaving}
                className="text-destructive"
              >
                {isDeleting ? "Removendo..." : "Remover template"}
              </Button>
            ) : (
              <span className="text-xs text-neutral-500">Após salvar, o template ficará visível na lista.</span>
            )}
            <div className="flex flex-col gap-2 sm:flex-row">
              <Button type="button" variant="outline" onClick={() => handleTemplateDialogOpenChange(false)} disabled={isSaving || isDeleting}>
                Cancelar
              </Button>
              <Button type="button" onClick={handleSave} disabled={isSaving || isDeleting}>
                {isSaving ? "Salvando..." : editingTemplate ? "Salvar mudanças" : "Criar template"}
              </Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
