"use client"

import { useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useMutation, useQuery } from "convex/react"
import { formatDistanceToNow } from "date-fns"
import { ptBR } from "date-fns/locale"
import { LayoutTemplate, MonitorPlay, Plus, Share2, Sparkles, Trash2 } from "lucide-react"
import type { Id } from "@/convex/_generated/dataModel"

import { api } from "@/convex/_generated/api"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { useAuth } from "@/lib/auth-client"
import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Skeleton } from "@/components/ui/skeleton"
import { Badge } from "@/components/ui/badge"
import { toast } from "sonner"

type DashboardSummary = {
  id: Id<"dashboards">
  tenantId: string
  name: string
  description: string | null
  aspectRatio: string
  theme: string
  filters: Record<string, unknown>
  layout: Array<{ i: string; x: number; y: number; w: number; h: number }>
  sections: Array<{
    id: string
    title?: string
    description?: string
    widgetKeys: string[]
    durationSeconds?: number
  }>
  tvIntervalSeconds: number
  readySelector: string | null
  createdBy: Id<"users">
  updatedBy: Id<"users"> | null
  createdAt: number
  updatedAt: number
  isArchived: boolean
  widgetsCount: number
}

type CreateDashboardDialogProps = {
  onCreate: (name: string, description: string | null) => Promise<void>
  isLoading: boolean
}

function CreateDashboardDialog({ onCreate, isLoading }: CreateDashboardDialogProps) {
  const [open, setOpen] = useState(false)
  const [name, setName] = useState("")
  const [description, setDescription] = useState("")

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    const trimmedName = name.trim()
    if (!trimmedName) {
      toast.error("Informe um nome para o dashboard.")
      return
    }
    await onCreate(trimmedName, description.trim() ? description.trim() : null)
    setOpen(false)
    setName("")
    setDescription("")
  }

  return (
    <>
      <Button onClick={() => setOpen(true)} className="gap-2">
        <Plus className="size-4" />
        Novo dashboard
      </Button>
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Criar dashboard</DialogTitle>
          </DialogHeader>
          <form onSubmit={handleSubmit} className="space-y-4">
            <div className="space-y-2">
              <label htmlFor="dashboard-name" className="text-sm font-medium">
                Nome
              </label>
              <Input
                id="dashboard-name"
                value={name}
                onChange={(event) => setName(event.target.value)}
                placeholder="Ex.: Operações - Visão Geral"
                required
              />
            </div>
            <div className="space-y-2">
              <label htmlFor="dashboard-description" className="text-sm font-medium">
                Descrição <span className="text-muted-foreground text-xs">(opcional)</span>
              </label>
              <Input
                id="dashboard-description"
                value={description}
                onChange={(event) => setDescription(event.target.value)}
                placeholder="Contextualize para a equipe"
              />
            </div>
            <DialogFooter className="sm:justify-between">
              <Button type="button" variant="outline" onClick={() => setOpen(false)}>
                Cancelar
              </Button>
              <Button type="submit" disabled={isLoading}>
                {isLoading ? "Criando..." : "Criar dashboard"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  )
}

export function DashboardListView() {
  const router = useRouter()
  const { session, convexUserId, isStaff } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const createDashboard = useMutation(api.dashboards.create)
  const archiveDashboard = useMutation(api.dashboards.archive)
  const [isCreating, setIsCreating] = useState(false)
  const [dashboardToDelete, setDashboardToDelete] = useState<DashboardSummary | null>(null)
  const [isDeleting, setIsDeleting] = useState(false)

  const dashboards = useQuery(
    api.dashboards.list,
    isStaff && convexUserId
      ? ({
          tenantId,
          viewerId: convexUserId as Id<"users">,
        } as const)
      : "skip"
  ) as DashboardSummary[] | undefined

  async function handleCreate(name: string, description: string | null) {
    if (!convexUserId) return
    setIsCreating(true)
    try {
      const result = await createDashboard({
        tenantId,
        actorId: convexUserId as Id<"users">,
        name,
        description: description ?? undefined,
      })
      toast.success("Dashboard criado com sucesso!")
      router.push(`/dashboards/${result.id}`)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar o dashboard.")
    } finally {
      setIsCreating(false)
    }
  }

  async function handleConfirmDelete() {
    if (!dashboardToDelete || !convexUserId) return
    setIsDeleting(true)
    try {
      await archiveDashboard({
        tenantId,
        actorId: convexUserId as Id<"users">,
        dashboardId: dashboardToDelete.id,
        archived: true,
      })
      toast.success("Dashboard removido.")
      setDashboardToDelete(null)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível remover o dashboard.")
    } finally {
      setIsDeleting(false)
    }
  }

  if (!isStaff) {
    return (
      <Card className="border-dashed border-primary/40 bg-primary/5 text-primary">
        <CardHeader>
          <CardTitle>Acesso restrito</CardTitle>
          <CardDescription>Somente a equipe interna pode visualizar e montar dashboards.</CardDescription>
        </CardHeader>
      </Card>
    )
  }

  if (!dashboards) {
    return (
      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
        {Array.from({ length: 3 }).map((_, index) => (
          <Card key={index} className="border-muted/60 bg-muted/20">
            <CardHeader className="space-y-2">
              <Skeleton className="h-4 w-32" />
              <Skeleton className="h-6 w-48" />
            </CardHeader>
            <CardContent className="space-y-2">
              <Skeleton className="h-3 w-full" />
              <Skeleton className="h-3 w-3/4" />
              <Skeleton className="h-3 w-1/2" />
            </CardContent>
            <CardFooter>
              <Skeleton className="h-9 w-full" />
            </CardFooter>
          </Card>
        ))}
      </div>
    )
  }

  const activeDashboards = dashboards.filter((dashboard) => !dashboard.isArchived)

  const renderCreateButton = () => (
    <CreateDashboardDialog onCreate={handleCreate} isLoading={isCreating} />
  )

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex flex-col gap-1">
          <h2 className="text-lg font-semibold">Painéis customizados</h2>
          <p className="text-sm text-muted-foreground">
            Combine KPIs, gráficos, tabelas e texto em painéis dinâmicos com filtros globais.
          </p>
        </div>
        {activeDashboards.length > 0 ? renderCreateButton() : null}
      </div>

      {activeDashboards.length === 0 ? (
        <Card className="overflow-hidden border-dashed border-slate-200 bg-gradient-to-br from-white via-white to-slate-50 shadow-sm">
          <CardContent className="flex flex-col gap-6 p-6 lg:flex-row lg:items-center lg:justify-between">
            <div className="space-y-4">
              <div className="flex items-center gap-3">
                <div className="inline-flex size-12 items-center justify-center rounded-full bg-sky-50 text-sky-700">
                  <Sparkles className="size-5" />
                </div>
                <div>
                  <h3 className="text-xl font-semibold text-neutral-900">Nenhum painel ainda</h3>
                  <p className="text-sm text-muted-foreground">Use KPIs, filas e texto para contar a história da operação.</p>
                </div>
              </div>
              <ul className="space-y-2 text-sm text-neutral-600">
                <li className="flex items-start gap-2">
                  <LayoutTemplate className="mt-0.5 size-4 text-slate-500" />
                  <span>Escolha widgets arrastando no canvas e organize por seções.</span>
                </li>
                <li className="flex items-start gap-2">
                  <Share2 className="mt-0.5 size-4 text-slate-500" />
                  <span>Compartilhe com a equipe, salve filtros padrão e gere PDFs/PNGs.</span>
                </li>
                <li className="flex items-start gap-2">
                  <MonitorPlay className="mt-0.5 size-4 text-slate-500" />
                  <span>Entre no modo apresentação/TV para um loop automático em tela cheia.</span>
                </li>
              </ul>
            </div>
            <div className="flex w-full flex-col gap-3 rounded-2xl border border-slate-200 bg-white/90 p-4 lg:w-auto lg:min-w-[220px]">
              {renderCreateButton()}
              <Button variant="outline" className="gap-2" asChild>
                <Link href="/reports/sla">
                  <LayoutTemplate className="size-4" />
                  Ver exemplos
                </Link>
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : (
        <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
          {activeDashboards.map((dashboard) => {
            const updatedAt = formatDistanceToNow(dashboard.updatedAt, {
              addSuffix: true,
              locale: ptBR,
            })
            return (
              <Card key={dashboard.id} className="group border-muted/70 transition hover:border-primary/60 hover:shadow-lg">
                <CardHeader>
                  <CardTitle className="flex items-center justify-between gap-4 text-base">
                    <span className="truncate">{dashboard.name}</span>
                    <Badge variant="outline" className="shrink-0">
                      {dashboard.widgetsCount} widget{dashboard.widgetsCount === 1 ? "" : "s"}
                    </Badge>
                  </CardTitle>
                  {dashboard.description ? (
                    <CardDescription className="line-clamp-2 text-sm">{dashboard.description}</CardDescription>
                  ) : null}
                </CardHeader>
                <CardContent className="space-y-3 text-sm text-muted-foreground">
                  <div className="flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1.5 text-sm font-medium text-neutral-700">
                    <span className="inline-flex size-2 rounded-full bg-emerald-500" />
                    Atualizado {updatedAt}
                  </div>
                  <div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
                    <Badge variant="outline" className="inline-flex items-center gap-2 rounded-full border-slate-200 bg-white px-3 py-1.5 text-sm font-semibold text-neutral-700">
                      <span className="h-2 w-2 rounded-full bg-neutral-400" />
                      Formato {dashboard.aspectRatio}
                    </Badge>
                    {dashboard.theme && dashboard.theme.toLowerCase() !== "system" ? (
                      <Badge variant="outline" className="inline-flex items-center gap-2 rounded-full border-slate-200 bg-white px-3 py-1.5 text-sm font-semibold text-neutral-700">
                        <span className="h-2 w-2 rounded-full bg-neutral-400" />
                        Tema {dashboard.theme}
                      </Badge>
                    ) : null}
                  </div>
                </CardContent>
                <CardFooter className="flex gap-2">
                  <Button asChild className="flex-1">
                    <Link href={`/dashboards/${dashboard.id}`}>Abrir painel</Link>
                  </Button>
                  <Button
                    variant="outline"
                    size="icon"
                    className="shrink-0 size-9 rounded-lg border border-rose-300 bg-white text-rose-600 transition hover:bg-rose-50 hover:!text-rose-600 focus-visible:ring-rose-200 [&>svg]:transition [&>svg]:text-rose-600 hover:[&>svg]:!text-rose-600"
                    onClick={() => setDashboardToDelete(dashboard)}
                    aria-label={`Excluir ${dashboard.name}`}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </CardFooter>
              </Card>
            )
          })}
        </div>
      )}
      <Dialog
        open={Boolean(dashboardToDelete)}
        onOpenChange={(open) => {
          if (!open && !isDeleting) {
            setDashboardToDelete(null)
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Excluir painel</DialogTitle>
            <DialogDescription>
              Essa ação remove o painel para toda a equipe. Confirme para continuar.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="sm:justify-between">
            <Button
              variant="outline"
              onClick={() => {
                if (!isDeleting) setDashboardToDelete(null)
              }}
              disabled={isDeleting}
            >
              Cancelar
            </Button>
            <Button variant="destructive" onClick={handleConfirmDelete} disabled={isDeleting}>
              {isDeleting ? "Removendo..." : "Excluir painel"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
