"use client"

import { type ReactNode } from "react"
import Link from "next/link"
import { useQuery } from "convex/react"
import { IconClockHour4, IconTrendingDown, IconTrendingUp } from "@tabler/icons-react"
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
import { formatDistanceToNow } from "date-fns"
import { ptBR } from "date-fns/locale"

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 { cn, formatDateDM, formatDateDMY, formatMinutesHuman } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
import { Skeleton } from "@/components/ui/skeleton"

type DashboardOverview = {
  newTickets?: { last24h: number; previous24h: number; trendPercentage: number | null }
  inProgress?: { current: number; previousSnapshot: number; trendPercentage: number | null }
  firstResponse?: { averageMinutes: number | null; deltaMinutes: number | null; responsesCount: number }
  awaitingAction?: { total: number; atRisk: number }
  resolution?: { resolvedLast7d: number; previousResolved: number; rate: number | null; deltaPercentage: number | null }
}

type QueueTrendResponse = {
  rangeDays: number
  queues: Array<{
    id: string
    name: string
    openedTotal: number
    resolvedTotal: number
    series: Array<{ date: string; opened: number; resolved: number }>
  }>
}

const queueSparkConfig = {
  opened: { label: "Novos", color: "var(--chart-1)" },
  resolved: { label: "Resolvidos", color: "var(--chart-2)" },
}

const metricBadgeClass =
  "gap-1 rounded-full border-border/60 px-2.5 py-0.5 text-[11px] sm:px-3 sm:py-1 sm:text-xs"

export function DashboardHero() {
  const { session, convexUserId, isStaff } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const dashboardEnabled = Boolean(isStaff && convexUserId)
  const overview = useQuery(
    api.reports.dashboardOverview,
    dashboardEnabled ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as DashboardOverview | undefined
  const newTicketsTrend = overview?.newTickets
    ? {
        delta: overview.newTickets.trendPercentage,
        label:
          overview.newTickets.trendPercentage === null
            ? "Sem comparativo"
            : `${overview.newTickets.trendPercentage >= 0 ? "+" : ""}${overview.newTickets.trendPercentage.toFixed(1)}% vs. 24h anteriores`,
      }
    : null

  const inProgressTrend = overview?.inProgress
    ? {
        delta: overview.inProgress.trendPercentage,
        label:
          overview.inProgress.trendPercentage === null
            ? "Sem histórico"
            : `${overview.inProgress.trendPercentage >= 0 ? "+" : ""}${overview.inProgress.trendPercentage.toFixed(1)}% vs. última medição`,
      }
    : null

  const responseDelta = overview?.firstResponse
    ? (() => {
        const delta = overview.firstResponse.deltaMinutes
        if (delta === null) return { delta, label: "Sem comparação" }
        return { delta, label: `${delta > 0 ? "+" : ""}${delta.toFixed(1)} min` }
      })()
    : null

  const resolutionInfo = overview?.resolution
    ? {
        delta: overview.resolution.deltaPercentage ?? null,
        label:
          overview.resolution.deltaPercentage === null
            ? "Sem histórico"
            : `${overview.resolution.deltaPercentage >= 0 ? "+" : ""}${overview.resolution.deltaPercentage.toFixed(1)}%`,
        rateLabel:
          overview.resolution.rate !== null
            ? `${overview.resolution.rate.toFixed(1)}% dos tickets resolvidos`
            : "Taxa indisponível",
      }
    : { delta: null, label: "Sem histórico", rateLabel: "Taxa indisponível" }

  const newTicketsFooter = (() => {
    if (!newTicketsTrend) return "Aguardando dados"
    if (newTicketsTrend.delta === null) return "Sem comparativo recente"
    return newTicketsTrend.delta >= 0 ? "Acima das 24h anteriores" : "Abaixo das 24h anteriores"
  })()

  const inProgressFooter = (() => {
    if (!inProgressTrend) return "Monitoramento aguardando histórico"
    if (inProgressTrend.delta === null) return "Sem histórico recente"
    return inProgressTrend.delta >= 0 ? "Acima da última medição" : "Abaixo da última medição"
  })()

  const responseFooter = (() => {
    if (!responseDelta) return "Sem dados suficientes para comparação"
    if (responseDelta.delta === null) return "Sem comparação recente"
    return responseDelta.delta <= 0 ? "Melhor que a última medição" : "Pior que a última medição"
  })()

  const resolutionFooter = resolutionInfo?.rateLabel ?? "Taxa indisponível no momento."

  return (
    <div className="space-y-6 px-4 lg:px-6">
      <div className="grid gap-4">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
          <Card className="@container/card rounded-3xl border border-border/60 bg-gradient-to-br from-white via-white to-primary/5 p-5 shadow-sm">
            <CardHeader className="gap-3 px-0">
              <CardDescription>Novos tickets (24h)</CardDescription>
              <CardTitle className="text-3xl font-semibold text-neutral-900 tabular-nums">
                {overview?.newTickets ? overview.newTickets.last24h : <Skeleton className="h-8 w-20" />}
              </CardTitle>
              {newTicketsTrend ? (
                <CardAction className="px-0">
                  <Badge
                    variant="outline"
                    className={cn(
                      metricBadgeClass,
                      "font-semibold",
                      newTicketsTrend.delta === null
                        ? "text-neutral-500"
                        : newTicketsTrend.delta < 0
                          ? "text-emerald-600"
                          : "text-amber-600"
                    )}
                  >
                    {newTicketsTrend.delta !== null && newTicketsTrend.delta < 0 ? (
                      <IconTrendingDown className="size-3.5" />
                    ) : (
                      <IconTrendingUp className="size-3.5" />
                    )}
                    {newTicketsTrend.label}
                  </Badge>
                </CardAction>
              ) : null}
            </CardHeader>
            <CardFooter className="flex-col items-start gap-1 px-0 text-sm text-neutral-500">
              <span>{newTicketsFooter}</span>
              <span className="text-xs text-neutral-400">Base: entradas registradas nas últimas 24h.</span>
            </CardFooter>
          </Card>

          <Card className="@container/card rounded-3xl border border-border/60 bg-gradient-to-br from-white via-white to-primary/5 p-5 shadow-sm">
            <CardHeader className="gap-3 px-0">
              <CardDescription>Em atendimento</CardDescription>
              <CardTitle className="text-3xl font-semibold text-neutral-900 tabular-nums">
                {overview?.inProgress ? overview.inProgress.current : <Skeleton className="h-8 w-14" />}
              </CardTitle>
              {inProgressTrend ? (
                <CardAction className="px-0">
                  <Badge
                    variant="outline"
                    className={cn(
                      metricBadgeClass,
                      "font-semibold",
                      inProgressTrend.delta === null
                        ? "text-neutral-500"
                        : inProgressTrend.delta > 0
                          ? "text-amber-600"
                          : "text-emerald-600"
                    )}
                  >
                    {inProgressTrend.delta !== null && inProgressTrend.delta > 0 ? (
                      <IconTrendingUp className="size-3.5" />
                    ) : (
                      <IconTrendingDown className="size-3.5" />
                    )}
                    {inProgressTrend.label}
                  </Badge>
                </CardAction>
              ) : null}
            </CardHeader>
            <CardFooter className="flex-col items-start gap-1 px-0 text-sm text-neutral-500">
              <span>{inProgressFooter}</span>
              <span className="text-xs text-neutral-400">Base: tickets ativos em SLA.</span>
            </CardFooter>
          </Card>

          <Card className="@container/card rounded-3xl border border-border/60 bg-gradient-to-br from-white via-white to-primary/5 p-5 shadow-sm">
            <CardHeader className="gap-3 px-0">
              <CardDescription>Tempo médio (1ª resposta)</CardDescription>
              <CardTitle className="text-3xl font-semibold text-neutral-900 tabular-nums">
                {overview?.firstResponse ? (
                  overview.firstResponse.averageMinutes !== null ? (
                    formatMinutesHuman(overview.firstResponse.averageMinutes)
                  ) : (
                    "—"
                  )
                ) : (
                  <Skeleton className="h-8 w-28" />
                )}
              </CardTitle>
              {responseDelta ? (
                <CardAction className="px-0">
                  <Badge
                    variant="outline"
                    className={cn(
                      metricBadgeClass,
                      "font-semibold",
                      responseDelta.delta === null
                        ? "text-neutral-500"
                        : responseDelta.delta > 0
                          ? "text-amber-600"
                          : "text-emerald-600"
                    )}
                  >
                    {responseDelta.delta !== null && responseDelta.delta > 0 ? (
                      <IconTrendingUp className="size-3.5" />
                    ) : (
                      <IconTrendingDown className="size-3.5" />
                    )}
                    {responseDelta.label}
                  </Badge>
                </CardAction>
              ) : null}
            </CardHeader>
            <CardFooter className="flex-col items-start gap-1 px-0 text-sm text-neutral-500">
              <span>{responseFooter}</span>
              <span className="text-xs text-neutral-400">Média móvel dos últimos 7 dias.</span>
            </CardFooter>
          </Card>

          <Card className="@container/card rounded-3xl border border-border/60 bg-gradient-to-br from-white via-white to-primary/5 p-5 shadow-sm">
            <CardHeader className="gap-3 px-0">
              <CardDescription>Resolvidos (7 dias)</CardDescription>
              <CardTitle className="text-3xl font-semibold text-neutral-900 tabular-nums">
                {overview?.resolution ? overview.resolution.resolvedLast7d : <Skeleton className="h-8 w-12" />}
              </CardTitle>
              <CardAction className="px-0">
                <Badge
                  variant="outline"
                  className={cn(
                    metricBadgeClass,
                    "font-semibold",
                    resolutionInfo?.delta === null
                      ? "text-neutral-500"
                      : resolutionInfo?.delta !== null && resolutionInfo.delta < 0
                        ? "text-amber-600"
                        : "text-emerald-600"
                  )}
                >
                  {resolutionInfo?.delta !== null && resolutionInfo.delta < 0 ? (
                    <IconTrendingDown className="size-3.5" />
                  ) : (
                    <IconTrendingUp className="size-3.5" />
                  )}
                  {resolutionInfo?.label}
                </Badge>
              </CardAction>
            </CardHeader>
            <CardFooter className="flex-col items-start gap-1 px-0 text-sm text-neutral-500">
              <span>{resolutionFooter}</span>
              <span className="text-xs text-neutral-400">Comparação com os 7 dias anteriores.</span>
            </CardFooter>
          </Card>
        </div>
      </div>
    </div>
  )
}

export function DashboardQueueInsights() {
  const { session, convexUserId, isStaff } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID
  const dashboardEnabled = Boolean(isStaff && convexUserId)
  const overview = useQuery(
    api.reports.dashboardOverview,
    dashboardEnabled ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as DashboardOverview | undefined
  const queueTrend = useQuery(
    api.reports.queueLoadTrend,
    dashboardEnabled ? { tenantId, viewerId: convexUserId as Id<"users">, range: "30d", limit: 3 } : "skip"
  ) as QueueTrendResponse | undefined

  return (
    <div className="grid gap-6 px-4 lg:grid-cols-2 lg:px-6">
      <QueueSparklineRow
        data={queueTrend?.queues}
        isLoading={dashboardEnabled && queueTrend === undefined}
      />
    </div>
  )
}

function QueueSparklineRow({
  data,
  isLoading,
}: {
  data?: QueueTrendResponse["queues"]
  isLoading: boolean
}) {
  return (
    <Card className="h-full rounded-3xl border border-border/60 bg-white/90 shadow-sm">
      <CardHeader className="flex flex-row items-center justify-between gap-4">
        <div>
          <CardTitle className="text-base font-semibold">Filas com maior volume</CardTitle>
          <CardDescription>Comparativo diário de entradas x resolvidos</CardDescription>
        </div>
        <Link
          href="/queues/overview"
          className="text-sm font-semibold text-[#006879] underline-offset-4 transition-colors hover:text-[#004d5a] hover:underline"
        >
          Abrir painel de filas
        </Link>
      </CardHeader>
      <CardContent>
        {isLoading ? (
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-2">
            {Array.from({ length: 3 }).map((_, index) => (
              <Skeleton key={`queue-sparkline-${index}`} className="h-56 w-full rounded-2xl" />
            ))}
          </div>
        ) : !data || data.length === 0 ? (
          <div className="rounded-2xl border border-dashed border-border/60 bg-muted/40 p-6 text-center text-sm text-muted-foreground">
            Ainda não há dados suficientes para exibir a tendência. Continue alimentando as filas ou reduza o período.
          </div>
        ) : (
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-2">
            {data.map((queue) => (
              <QueueSparklineCard key={queue.id} queue={queue} />
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  )
}

function QueueSparklineCard({
  queue,
}: {
  queue: Required<QueueTrendResponse>["queues"][number]
}) {
  const sanitizedId = queue.id.replace(/[^a-zA-Z0-9_-]/g, "")
  const latest = queue.series.length > 0 ? queue.series[queue.series.length - 1] : null
  const net = queue.openedTotal - queue.resolvedTotal
  const netLabel =
    net === 0 ? "Estável" : `${net > 0 ? "+" : ""}${net} no período`
  const lastUpdated = latest
    ? formatDistanceToNow(new Date(latest.date), { addSuffix: true, locale: ptBR })
    : null

  return (
    <Card className="rounded-2xl border border-border/60 bg-gradient-to-br from-white via-white to-primary/5 p-4 shadow-sm">
      <div className="flex flex-col gap-3">
        <div className="flex items-center justify-between gap-2">
          <div>
            <p className="text-sm font-semibold text-neutral-900">{queue.name}</p>
            <p className="text-xs text-neutral-500">
              Última movimentação {lastUpdated ?? "—"}
            </p>
          </div>
          <Badge
            variant="outline"
            className={cn(
              metricBadgeClass,
              "font-medium",
              net > 0 ? "text-amber-600" : net < 0 ? "text-emerald-600" : "text-neutral-500"
            )}
          >
            {netLabel}
          </Badge>
        </div>
        <div className="flex items-center gap-4 text-sm">
          <div>
            <p className="text-xs uppercase text-neutral-500">Entraram</p>
            <p className="text-lg font-semibold text-neutral-900">{queue.openedTotal}</p>
          </div>
          <div>
            <p className="text-xs uppercase text-neutral-500">Resolvidos</p>
            <p className="text-lg font-semibold text-neutral-900">{queue.resolvedTotal}</p>
          </div>
        </div>
        <ChartContainer config={queueSparkConfig} className="h-32 w-full">
          <AreaChart data={queue.series}>
            <defs>
              <linearGradient id={`opened-${sanitizedId}`} x1="0" x2="0" y1="0" y2="1">
                <stop offset="5%" stopColor="var(--color-opened)" stopOpacity={0.3} />
                <stop offset="95%" stopColor="var(--color-opened)" stopOpacity={0.05} />
              </linearGradient>
              <linearGradient id={`resolved-${sanitizedId}`} x1="0" x2="0" y1="0" y2="1">
                <stop offset="5%" stopColor="var(--color-resolved)" stopOpacity={0.3} />
                <stop offset="95%" stopColor="var(--color-resolved)" stopOpacity={0.05} />
              </linearGradient>
            </defs>
            <CartesianGrid vertical={false} strokeDasharray="3 3" opacity={0.2} />
            <XAxis dataKey="date" tickFormatter={(value) => formatDateDM(new Date(value))} tickLine={false} axisLine={false} tickMargin={8} minTickGap={32} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  labelFormatter={(value) => formatDateDMY(new Date(value as string))}
                  valueFormatter={(value) =>
                    typeof value === "number" ? value.toLocaleString("pt-BR") : String(value ?? "")
                  }
                />
              }
            />
            <Area
              type="monotone"
              dataKey="opened"
              stroke="var(--color-opened)"
              fill={`url(#opened-${sanitizedId})`}
              strokeWidth={2}
            />
            <Area
              type="monotone"
              dataKey="resolved"
              stroke="var(--color-resolved)"
              fill={`url(#resolved-${sanitizedId})`}
              strokeWidth={2}
            />
          </AreaChart>
        </ChartContainer>
      </div>
    </Card>
  )
}

export function SlaAtRiskCard({
  data,
  isLoading,
}: {
  data?: { total: number; atRisk: number }
  isLoading: boolean
}) {
  return (
    <Card className="h-full rounded-3xl border border-border/60 bg-white/90 shadow-sm">
      <CardHeader>
        <CardTitle className="text-base font-semibold">SLA em risco</CardTitle>
        <CardDescription>Tickets com solução prevista nas próximas horas</CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex flex-wrap items-center gap-4">
          <div className="rounded-2xl bg-gradient-to-br from-amber-50 to-amber-100/60 p-3 shadow-inner">
            <IconClockHour4 className="size-8 text-amber-600" />
          </div>
          <div>
            <p className="text-3xl font-semibold text-neutral-900">
              {isLoading ? <Skeleton className="h-7 w-16" /> : data?.atRisk ?? 0}
            </p>
            <p className="text-sm text-neutral-500">
              de {isLoading ? "—" : data?.total ?? 0} tickets ativos
            </p>
          </div>
        </div>
        <div className="rounded-2xl border border-dashed border-border/60 bg-amber-50/70 p-3 text-sm text-amber-900">
          Foque nesses atendimentos para preservar o SLA. Utilize o filtro “em risco” na lista.
        </div>
        <ButtonLink href="/tickets?status=AWAITING_ATTENDANCE&priority=URGENT">
          Priorizar agora
        </ButtonLink>
      </CardContent>
    </Card>
  )
}

function ButtonLink({ href, children }: { href: string; children: ReactNode }) {
  return (
    <Link
      href={href}
      className="inline-flex items-center justify-center rounded-2xl border border-neutral-900 bg-neutral-900 px-4 py-2 text-sm font-semibold text-white transition hover:bg-neutral-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900/30"
    >
      {children}
    </Link>
  )
}
