"use client"

import { useState, useMemo } from "react"
import { 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 {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { usePersistentCompanyFilter } from "@/lib/use-company-filter"
import { Progress } from "@/components/ui/progress"
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import {
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart"
import type { ChartConfig } from "@/components/ui/chart"
import { formatHoursCompact } from "@/lib/utils"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"
import { Button } from "@/components/ui/button"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { DateRangeButton } from "@/components/date-range-button"
import { ReportScheduleDrawer } from "@/components/reports/report-schedule-drawer"

type HoursItem = {
  companyId: string
  name: string
  isAvulso: boolean
  internalMs: number
  externalMs: number
  totalMs: number
  contractedHoursPerMonth?: number | null
}

type MachineHoursItem = {
  machineId: string
  machineHostname: string | null
  companyId: string | null
  companyName: string | null
  internalMs: number
  externalMs: number
  totalMs: number
}

type HoursByMachineResponse = {
  rangeDays: number
  items: MachineHoursItem[]
}

const topClientsChartConfig = {
  internas: {
    label: "Horas internas",
    color: "var(--chart-1)",
  },
  externas: {
    label: "Horas externas",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig

export function HoursReport() {
  const [timeRange, setTimeRange] = useState<"90d" | "30d" | "7d" | "365d" | "all">("90d")
  const [companyId, setCompanyId] = usePersistentCompanyFilter("all")
  const [billingFilter, setBillingFilter] = useState<"all" | "avulso" | "contratado">("all")
  const [schedulerOpen, setSchedulerOpen] = useState(false)
  const [groupBy, setGroupBy] = useState<"company" | "machine">("company")
  const [dateFrom, setDateFrom] = useState<string | null>(null)
  const [dateTo, setDateTo] = useState<string | null>(null)
  const { session, convexUserId, isStaff, isAdmin } = useAuth()
  const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID

  const enabled = Boolean(isStaff && convexUserId)
  const dateRangeFilters = useMemo(() => {
    const filters: { dateFrom?: string; dateTo?: string } = {}
    if (dateFrom) filters.dateFrom = dateFrom
    if (dateTo) filters.dateTo = dateTo
    return filters
  }, [dateFrom, dateTo])
  const data = useQuery(
    api.reports.hoursByClient,
    enabled && groupBy === "company"
      ? {
          tenantId,
          viewerId: convexUserId as Id<"users">,
          range: timeRange === "365d" || timeRange === "all" ? "90d" : timeRange,
          ...dateRangeFilters,
        }
      : "skip"
  ) as { rangeDays: number; items: HoursItem[] } | undefined

  const machinesData = useQuery(
    api.reports.hoursByMachine,
    enabled && groupBy === "machine"
      ? {
          tenantId,
          viewerId: convexUserId as Id<"users">,
          range: timeRange,
          companyId: companyId === "all" ? undefined : (companyId as Id<"companies">),
          ...dateRangeFilters,
        }
      : "skip"
  ) as HoursByMachineResponse | undefined

  const companies = useQuery(
    api.companies.list,
    enabled ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as Array<{ id: Id<"companies">; name: string }> | undefined
  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 filteredCompanies = useMemo(() => {
    let items = data?.items ?? []
    if (companyId !== "all") {
      items = items.filter((it) => String(it.companyId) === companyId)
    }
    if (billingFilter === "avulso") {
      items = items.filter((it) => it.isAvulso)
    } else if (billingFilter === "contratado") {
      items = items.filter((it) => !it.isAvulso)
    }
    return items
  }, [data?.items, companyId, billingFilter])

  const filteredMachines = useMemo(() => {
    let items = machinesData?.items ?? []
    if (companyId !== "all") {
      items = items.filter((it) => String(it.companyId) === companyId)
    }
    if (billingFilter === "avulso") {
      // Para futuro: quando tivermos flag de avulso por máquina; por enquanto, não filtra
      return items
    }
    if (billingFilter === "contratado") {
      return items
    }
    return items
  }, [machinesData?.items, companyId, billingFilter])

  const totals = useMemo(() => {
    const source = groupBy === "machine" ? filteredMachines : filteredCompanies
    return source.reduce(
      (acc, item) => {
        acc.internal += item.internalMs / 3600000
        acc.external += item.externalMs / 3600000
        acc.total += item.totalMs / 3600000
        return acc
      },
      { internal: 0, external: 0, total: 0 }
    )
  }, [filteredCompanies, filteredMachines, groupBy])

  // No number formatter needed; we use formatHoursCompact for hours

  const filteredCompaniesWithComputed = useMemo(
    () =>
      filteredCompanies.map((row) => {
        const internal = row.internalMs / 3600000
        const external = row.externalMs / 3600000
        const total = row.totalMs / 3600000
        const contracted = row.contractedHoursPerMonth ?? null
        const usagePercent =
          contracted && contracted > 0 ? Math.min(100, Math.round((total / contracted) * 100)) : null
        return {
          ...row,
          internal,
          external,
          total,
          contracted,
          usagePercent,
        }
      }),
    [filteredCompanies]
  )
  const topClientsData = useMemo(
    () =>
      filteredCompaniesWithComputed
        .slice()
        .sort((a, b) => b.total - a.total)
        .slice(0, 10)
        .map((row) => ({
          name: row.name,
          internas: row.internal,
          externas: row.external,
        })),
    [filteredCompaniesWithComputed]
  )

  const exportHref = useMemo(() => {
    const params = new URLSearchParams()
    const effectiveRange = timeRange === "365d" || timeRange === "all" ? "90d" : timeRange
    params.set("range", effectiveRange)
    if (companyId !== "all") params.set("companyId", companyId)
    if (dateFrom) params.set("dateFrom", dateFrom)
    if (dateTo) params.set("dateTo", dateTo)
    return `/api/reports/hours-by-client.xlsx?${params.toString()}`
  }, [companyId, dateFrom, dateTo, timeRange])

  return (
    <div className="space-y-6">
      {isAdmin ? (
        <ReportScheduleDrawer
          open={schedulerOpen}
          onOpenChange={setSchedulerOpen}
          defaultReports={["hours"]}
          defaultRange={timeRange}
          defaultCompanyId={companyId === "all" ? null : companyId}
          companyOptions={companyOptions}
        />
      ) : null}
      <div className="flex flex-col gap-4 rounded-3xl border border-border/60 bg-white/95 p-4 shadow-sm">
        <div className="flex flex-wrap gap-3 lg:items-center">
          <div className="flex flex-1 flex-wrap gap-3 lg:flex-nowrap">
            <SearchableCombobox
              value={companyId}
              onValueChange={(value) => setCompanyId(value ?? "all")}
              options={companyOptions}
              placeholder="Todas as empresas"
              triggerClassName="h-10 w-full rounded-2xl border border-border/60 bg-white px-3 text-sm font-semibold text-neutral-800 lg:w-64"
              align="center"
            />
            <DateRangeButton
              from={dateFrom}
              to={dateTo}
              onChange={({ from, to }) => {
                setDateFrom(from)
                setDateTo(to)
              }}
              className="w-full min-w-[200px] lg:w-auto lg:flex-1"
              align="center"
            />
          </div>
          <div className="flex w-full justify-start lg:w-auto lg:justify-end lg:ml-auto">
            <ToggleGroup
              type="single"
              value={billingFilter}
              onValueChange={(value) => value && setBillingFilter(value as typeof billingFilter)}
              className="inline-flex rounded-full border border-border/60 bg-white/80 p-1 shadow-sm"
            >
              <ToggleGroupItem
                value="all"
                className="rounded-full px-6 py-2 text-xs font-semibold whitespace-nowrap transition first:rounded-l-full last:rounded-r-full"
              >
                Todos
              </ToggleGroupItem>
              <ToggleGroupItem
                value="avulso"
                className="rounded-full px-6 py-2 text-xs font-semibold whitespace-nowrap transition first:rounded-l-full last:rounded-r-full"
              >
                Somente avulsos
              </ToggleGroupItem>
              <ToggleGroupItem
                value="contratado"
                className="rounded-full px-6 py-2 text-xs font-semibold whitespace-nowrap transition first:rounded-l-full last:rounded-r-full"
              >
                Somente contratados
              </ToggleGroupItem>
            </ToggleGroup>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-3">
          <ToggleGroup
            type="single"
            value={timeRange}
            onValueChange={(value) => {
              if (!value) return
              setTimeRange(value as typeof timeRange)
              setDateFrom(null)
              setDateTo(null)
            }}
            variant="outline"
            size="lg"
            className="flex flex-wrap rounded-2xl border border-border/60 lg:flex-nowrap lg:min-w-[320px]"
          >
            <ToggleGroupItem value="90d" className="min-w-[80px] justify-center px-4">
              90 dias
            </ToggleGroupItem>
            <ToggleGroupItem value="30d" className="min-w-[80px] justify-center px-4">
              30 dias
            </ToggleGroupItem>
            <ToggleGroupItem value="7d" className="min-w-[80px] justify-center px-4">
              7 dias
            </ToggleGroupItem>
            {groupBy === "machine" ? (
              <>
                <ToggleGroupItem value="365d" className="hidden min-w-[96px] justify-center px-4 lg:inline-flex">
                  12 meses
                </ToggleGroupItem>
                <ToggleGroupItem value="all" className="hidden min-w-[120px] justify-center px-5 lg:inline-flex">
                  Todo histórico
                </ToggleGroupItem>
              </>
            ) : null}
          </ToggleGroup>
          <div className="flex flex-1 min-w-[220px] flex-wrap items-center justify-center gap-2 text-xs font-medium text-neutral-500">
            <span>Agrupar por</span>
            <div className="inline-flex rounded-full border border-slate-200 bg-slate-50 p-1 text-xs">
              <button
                type="button"
                className={`px-3 py-1 rounded-full transition ${
                  groupBy === "company"
                    ? "bg-white text-neutral-900 shadow-sm"
                    : "text-neutral-500 hover:text-neutral-800"
                }`}
                onClick={() => setGroupBy("company")}
              >
                Empresa
              </button>
              <button
                type="button"
                className={`px-3 py-1 rounded-full transition ${
                  groupBy === "machine"
                    ? "bg-white text-neutral-900 shadow-sm"
                    : "text-neutral-500 hover:text-neutral-800"
                }`}
                onClick={() => setGroupBy("machine")}
              >
                Máquina
              </button>
            </div>
          </div>
          <div className="ml-auto flex flex-wrap items-center justify-end gap-2 lg:flex-nowrap">
            {isAdmin ? (
              <Button variant="outline" size="sm" onClick={() => setSchedulerOpen(true)}>
                Agendar exportação
              </Button>
            ) : null}
            <Button asChild size="sm" variant="outline">
              <a href={exportHref}>Exportar XLSX</a>
            </Button>
          </div>
        </div>
      </div>
      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle>
            {groupBy === "company" ? "Top clientes por horas" : "Top máquinas por horas"}
          </CardTitle>
          <CardDescription>
            {groupBy === "company"
              ? "Comparativo empilhado de horas internas x externas (top 10 empresas)."
              : "Comparativo empilhado de horas internas x externas (top 10 máquinas)."}
          </CardDescription>
        </CardHeader>
        <CardContent>
          {groupBy === "company" ? (
            !filteredCompaniesWithComputed || filteredCompaniesWithComputed.length === 0 ? (
              <p className="rounded-lg border border-dashed border-slate-200 p-6 text-sm text-neutral-500">
                Sem dados para o período.
              </p>
            ) : (
              <ChartContainer config={topClientsChartConfig} className="aspect-auto h-[320px] w-full">
                <BarChart
                  data={topClientsData}
                  layout="vertical"
                  margin={{ top: 16, right: 24, bottom: 16, left: 0 }}
                  barCategoryGap={12}
                >
                  <CartesianGrid horizontal vertical={false} />
                  <XAxis
                    type="number"
                    tickLine={false}
                    axisLine={false}
                    tickFormatter={(value) => formatHoursCompact(Number(value))}
                  />
                  <YAxis dataKey="name" type="category" tickLine={false} axisLine={false} width={180} />
                  <ChartTooltip
                    content={
                      <ChartTooltipContent
                        className="w-[220px]"
                        labelFormatter={(value) => (
                          <span className="font-semibold text-foreground">{String(value)}</span>
                        )}
                        formatter={(value, name) => (
                          <>
                            <span className="text-muted-foreground">
                              {name === "internas" ? "Horas internas" : "Horas externas"}
                            </span>
                            <span className="text-foreground font-mono font-medium tabular-nums">
                              {formatHoursCompact(Number(value))}
                            </span>
                          </>
                        )}
                      />
                    }
                  />
                  <ChartLegend content={<ChartLegendContent />} />
                  <Bar dataKey="internas" stackId="hours" fill="var(--color-internas)" radius={[8, 0, 0, 8]} barSize={18} />
                  <Bar dataKey="externas" stackId="hours" fill="var(--color-externas)" radius={[0, 8, 8, 0]} barSize={18} />
                </BarChart>
              </ChartContainer>
            )
          ) : (
            <>
              {!filteredMachines || filteredMachines.length === 0 ? (
                <p className="rounded-lg border border-dashed border-slate-200 p-6 text-sm text-neutral-500">
                  Nenhuma máquina encontrada para o filtro selecionado.
                </p>
              ) : (
                <ChartContainer config={topClientsChartConfig} className="aspect-auto h-[320px] w-full">
                  <BarChart
                    data={filteredMachines
                      .slice()
                      .sort((a, b) => b.totalMs - a.totalMs)
                      .slice(0, 10)
                      .map((row) => ({
                        name: row.machineHostname ?? row.machineId,
                        internas: row.internalMs / 3600000,
                        externas: row.externalMs / 3600000,
                      }))}
                    layout="vertical"
                    margin={{ top: 16, right: 24, bottom: 16, left: 0 }}
                    barCategoryGap={12}
                  >
                    <CartesianGrid horizontal vertical={false} />
                    <XAxis
                      type="number"
                      tickLine={false}
                      axisLine={false}
                      tickFormatter={(value) => formatHoursCompact(Number(value))}
                    />
                    <YAxis dataKey="name" type="category" tickLine={false} axisLine={false} width={200} />
                    <ChartTooltip
                      content={
                        <ChartTooltipContent
                          className="w-[220px]"
                          labelFormatter={(value) => (
                            <span className="font-semibold text-foreground">{String(value)}</span>
                          )}
                          formatter={(value, name) => (
                            <>
                              <span className="text-muted-foreground">
                                {name === "internas" ? "Horas internas" : "Horas externas"}
                              </span>
                              <span className="text-foreground font-mono font-medium tabular-nums">
                                {formatHoursCompact(Number(value))}
                              </span>
                            </>
                          )}
                        />
                      }
                    />
                    <ChartLegend content={<ChartLegendContent />} />
                    <Bar dataKey="internas" stackId="hours" fill="var(--color-internas)" radius={[8, 0, 0, 8]} barSize={18} />
                    <Bar dataKey="externas" stackId="hours" fill="var(--color-externas)" radius={[0, 8, 8, 0]} barSize={18} />
                  </BarChart>
                </ChartContainer>
              )}
            </>
          )}
        </CardContent>
      </Card>

      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle>Horas</CardTitle>
          <CardDescription>
            {groupBy === "company"
              ? "Visualize o esforço interno e externo por empresa e acompanhe o consumo contratado."
              : "Visualize o esforço interno e externo por máquina dentro dos filtros selecionados."}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-3">
            {[
              { key: "internal", label: "Horas internas", value: formatHoursCompact(totals.internal) },
              { key: "external", label: "Horas externas", value: formatHoursCompact(totals.external) },
              { key: "total", label: "Total acumulado", value: formatHoursCompact(totals.total) },
            ].map((item) => (
              <div key={item.key} className="rounded-xl border border-slate-200 bg-slate-50/80 p-4 shadow-sm">
                <p className="text-xs uppercase tracking-wide text-neutral-500">{item.label}</p>
                <p className="mt-2 text-2xl font-semibold text-neutral-900">{item.value}</p>
              </div>
            ))}
          </div>

          {groupBy === "company" ? (
            !filteredCompaniesWithComputed.length ? (
              <div className="mt-6 rounded-2xl border border-dashed border-slate-200 bg-slate-50/80 p-8 text-center text-sm text-muted-foreground">
                Nenhuma empresa encontrada para o filtro selecionado.
              </div>
            ) : (
              <div className="mt-6 grid gap-4 lg:grid-cols-2">
                {filteredCompaniesWithComputed.map((row) => (
                  <div
                    key={row.companyId}
                    className="flex flex-col justify-between rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition hover:border-slate-300"
                  >
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div>
                        <h3 className="text-base font-semibold text-neutral-900">{row.name}</h3>
                        <p className="text-xs text-neutral-500">ID {row.companyId}</p>
                      </div>
                      <Badge
                        variant={row.isAvulso ? "secondary" : "outline"}
                        className="rounded-full px-3 py-1 text-xs font-medium"
                      >
                        {row.isAvulso ? "Cliente avulso" : "Recorrente"}
                      </Badge>
                    </div>
                    <div className="mt-4 grid gap-3 rounded-xl border border-slate-100 bg-slate-50/70 p-4 text-sm text-neutral-700">
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Horas internas</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(row.internal)}
                        </span>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Horas externas</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(row.external)}
                        </span>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Total</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(row.total)}
                        </span>
                      </div>
                    </div>
                    <div className="mt-4 space-y-2">
                      <div className="flex items-center justify-between text-xs text-neutral-500">
                        <span>Contratadas/mês</span>
                        <span className="font-medium text-neutral-800">
                          {row.contracted ? formatHoursCompact(row.contracted) : "—"}
                        </span>
                      </div>
                      <div className="space-y-1">
                        <div className="flex items-center justify-between text-xs text-neutral-500">
                          <span>Uso</span>
                          <span className="font-semibold text-neutral-800">
                            {row.usagePercent !== null ? `${row.usagePercent}%` : "—"}
                          </span>
                        </div>
                        {row.usagePercent !== null ? (
                          <Progress value={row.usagePercent} className="h-2" />
                        ) : (
                          <div className="rounded-full border border-dashed border-slate-200 py-1 text-center text-[11px] text-neutral-500">
                            Defina horas contratadas para acompanhar o uso
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )
          ) : !filteredMachines.length ? (
            <div className="mt-6 rounded-2xl border border-dashed border-slate-200 bg-slate-50/80 p-8 text-center text-sm text-muted-foreground">
              Nenhuma máquina encontrada para o filtro selecionado.
            </div>
          ) : (
            <div className="mt-6 grid gap-4 lg:grid-cols-2">
              {filteredMachines.map((row) => {
                const internal = row.internalMs / 3_600_000
                const external = row.externalMs / 3_600_000
                const total = row.totalMs / 3_600_000
                return (
                  <div
                    key={row.machineId}
                    className="flex flex-col justify-between rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition hover:border-slate-300"
                  >
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div>
                        <h3 className="text-base font-semibold text-neutral-900">
                          {row.machineHostname ?? row.machineId}
                        </h3>
                        <p className="text-xs text-neutral-500">
                          {row.companyName ?? "Sem empresa"}
                        </p>
                      </div>
                    </div>
                    <div className="mt-4 grid gap-3 rounded-xl border border-slate-100 bg-slate-50/70 p-4 text-sm text-neutral-700">
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Horas internas</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(internal)}
                        </span>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Horas externas</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(external)}
                        </span>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-xs uppercase text-neutral-500">Total</span>
                        <span className="font-semibold text-neutral-900">
                          {formatHoursCompact(total)}
                        </span>
                      </div>
                    </div>
                  </div>
                )
              })}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  )
}
