"use client"

import * as React from "react"
import { CalendarClock, Play, RefreshCw } from "lucide-react"
import { toast } from "sonner"

import { ListPageCard } from "@/app/dashboard/_components"
import { fetchCronSchedule } from "@/components/settings/cron-schedule/api/cron-schedule.api"
import {
  formatScheduleDescription,
  groupCronRowsByCategory,
} from "@/components/settings/cron-schedule/utils"
import type { CronScheduleResult } from "@/components/settings/cron-schedule/types"
import { SETTINGS_SELECT_TRIGGER_CLASS } from "@/components/settings/constants"
import { ErrorBanner } from "@/components/shared/error-banner"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { cn } from "@/lib/utils"

const ALL_CATEGORIES_VALUE = "__all__"

function toCategorySelectValue(category: string) {
  return category || ALL_CATEGORIES_VALUE
}

function fromCategorySelectValue(value: string) {
  return value === ALL_CATEGORIES_VALUE ? "" : value
}

type CronSchedulePageProps = {
  initialData: CronScheduleResult
  initialErrorMessage?: string | null
}

export function CronSchedulePage({
  initialData,
  initialErrorMessage = null,
}: CronSchedulePageProps) {
  const [data, setData] = React.useState(initialData)
  const [errorMessage, setErrorMessage] = React.useState(initialErrorMessage)
  const [isRefreshing, setIsRefreshing] = React.useState(false)
  const [timezone, setTimezone] = React.useState(initialData.timezone || "Asia/Dubai")
  const [category, setCategory] = React.useState(initialData.category || "")
  const [runDates, setRunDates] = React.useState<Record<string, string>>({})

  const groupedRows = React.useMemo(() => groupCronRowsByCategory(data.rows), [data.rows])

  const loadSchedule = React.useCallback(
    async (filters: { timezone: string; category: string }, showToast = false) => {
      setIsRefreshing(true)
      try {
        const result = await fetchCronSchedule(filters)
        setData(result)
        setErrorMessage(null)
        if (showToast) toast.success("Cron schedule refreshed")
      } catch (error) {
        const message =
          error instanceof Error ? error.message : "Failed to load cron schedule"
        setErrorMessage(message)
        toast.error(message)
      } finally {
        setIsRefreshing(false)
      }
    },
    []
  )

  const handleApply = () => {
    void loadSchedule({ timezone, category }, true)
  }

  const handleRefresh = () => {
    void loadSchedule({ timezone: data.timezone, category: data.category }, true)
  }

  const handleRun = (jobKey: string, jobName: string) => {
    toast.message(`Run queued for "${jobName}"`, {
      description: `Job key: ${jobKey}. Backend run endpoint is not wired yet.`,
    })
  }

  const handleRunAtDate = (jobKey: string, jobName: string) => {
    const runDate = runDates[jobKey]
    if (!runDate) {
      toast.error("Select a date before running this job")
      return
    }

    toast.message(`Run at date queued for "${jobName}"`, {
      description: `${runDate}. Backend run endpoint is not wired yet.`,
    })
  }

  return (
    <ListPageCard
      icon={CalendarClock}
      title="Cron Schedule"
      description="Monitor scheduled jobs and trigger manual runs. Entries are configured in UTC; local times follow the selected display timezone."
      breadcrumb={[
        { label: "Settings", href: "/dashboard/settings/common" },
        { label: "Cron Schedule" },
        { label: "View" },
      ]}
      actions={
        <Button
          type="button"
          size="sm"
          className="bg-emerald-600 text-white hover:bg-emerald-700"
          onClick={handleRefresh}
          disabled={isRefreshing}
        >
          <RefreshCw className={cn("mr-1.5 size-4", isRefreshing && "animate-spin")} />
          Refresh
        </Button>
      }
    >
      <ErrorBanner message={errorMessage} className="mb-4" />

      <div className="mb-4 flex flex-wrap gap-2">
        <Badge variant="secondary" className="rounded-md px-2.5 py-1 font-normal">
          Server cron timezone: {data.sourceTimezone}
        </Badge>
        <Badge className="rounded-md border-sky-200 bg-sky-50 px-2.5 py-1 font-normal text-sky-900 hover:bg-sky-50">
          Now (UTC): {data.nowUtc || "—"}
        </Badge>
        <Badge className="rounded-md border-emerald-200 bg-emerald-50 px-2.5 py-1 font-normal text-emerald-900 hover:bg-emerald-50">
          Now (selected): {data.nowLocal || "—"}
        </Badge>
      </div>

      <div className="mb-4 flex flex-col gap-3 rounded-lg border bg-muted/20 p-4 sm:flex-row sm:items-end">
        <div className="grid flex-1 gap-3 sm:grid-cols-2">
          <div className="space-y-1.5">
            <Label htmlFor="cron-timezone">Display timezone</Label>
            <Select value={timezone} onValueChange={setTimezone}>
              <SelectTrigger id="cron-timezone" className={SETTINGS_SELECT_TRIGGER_CLASS}>
                <SelectValue placeholder="Select timezone" />
              </SelectTrigger>
              <SelectContent className="max-h-72">
                {Object.entries(data.timezoneOptions).map(([value, label]) => (
                  <SelectItem key={value} value={value}>
                    {label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="cron-category">Category</Label>
            <Select
              value={toCategorySelectValue(category)}
              onValueChange={(value) => setCategory(fromCategorySelectValue(value))}
            >
              <SelectTrigger id="cron-category" className={SETTINGS_SELECT_TRIGGER_CLASS}>
                <SelectValue placeholder="All categories" />
              </SelectTrigger>
              <SelectContent>
                {Object.entries(data.categoryOptions).map(([value, label]) => (
                  <SelectItem
                    key={value || ALL_CATEGORIES_VALUE}
                    value={toCategorySelectValue(value)}
                  >
                    {label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        <Button type="button" onClick={handleApply} disabled={isRefreshing}>
          Apply
        </Button>
      </div>

      <p className="mb-4 text-sm text-muted-foreground">
        Entries are configured in UTC. The Run button executes the job immediately in the
        background.
      </p>

      <div className="overflow-x-auto rounded-lg border">
        <Table>
          <TableHeader>
            <TableRow className="bg-muted/50 hover:bg-muted/50">
              <TableHead className="min-w-[110px]">Category</TableHead>
              <TableHead className="min-w-[160px]">Job</TableHead>
              <TableHead className="min-w-[220px]">Description</TableHead>
              <TableHead className="min-w-[140px]">UTC schedule</TableHead>
              <TableHead className="min-w-[140px]">Local schedule</TableHead>
              <TableHead className="min-w-[160px]">Human readable</TableHead>
              <TableHead className="min-w-[180px]">Next runs</TableHead>
              <TableHead className="min-w-[260px]">Crontab line</TableHead>
              <TableHead className="min-w-[140px]">Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {groupedRows.length === 0 ? (
              <TableRow>
                <TableCell colSpan={9} className="h-24 text-center text-muted-foreground">
                  No cron jobs found.
                </TableCell>
              </TableRow>
            ) : (
              groupedRows.map((group) =>
                group.rows.map((row, rowIndex) => {
                  const humanReadable = formatScheduleDescription(
                    row.scheduleDescription,
                    row.schedule
                  )
                  const localReadable = formatScheduleDescription(
                    row.scheduleLocalText,
                    row.scheduleLocal
                  )
                  const supportsRunAtDate = row.category === "Bank API"

                  return (
                    <TableRow key={row.key}>
                      {rowIndex === 0 ? (
                        <TableCell
                          rowSpan={group.rows.length}
                          className="align-top font-medium"
                        >
                          {group.category}
                        </TableCell>
                      ) : null}
                      <TableCell className="font-medium">{row.name}</TableCell>
                      <TableCell className="text-muted-foreground">{row.description}</TableCell>
                      <TableCell>
                        <div className="font-mono text-xs">{row.schedule}</div>
                        <div className="mt-1 text-xs text-muted-foreground">{humanReadable}</div>
                      </TableCell>
                      <TableCell>
                        <div className="font-mono text-xs text-rose-600">{row.scheduleLocal}</div>
                        <div className="mt-1 text-xs text-rose-600/80">{localReadable}</div>
                      </TableCell>
                      <TableCell>{humanReadable}</TableCell>
                      <TableCell>
                        <ul className="space-y-1 text-xs text-muted-foreground">
                          {row.nextRunsLocal.map((runAt) => (
                            <li key={`${row.key}-${runAt}`}>• {runAt}</li>
                          ))}
                        </ul>
                      </TableCell>
                      <TableCell>
                        <code className="block whitespace-pre-wrap break-all font-mono text-xs text-rose-600">
                          {row.cronLine}
                        </code>
                      </TableCell>
                      <TableCell className="align-top">
                        <div className="flex flex-col gap-2">
                          {row.runnable ? (
                            <Button
                              type="button"
                              size="sm"
                              className="h-8 bg-emerald-600 text-white hover:bg-emerald-700"
                              onClick={() => handleRun(row.key, row.name)}
                            >
                              <Play className="mr-1 size-3.5" />
                              Run
                            </Button>
                          ) : null}
                          {supportsRunAtDate ? (
                            <>
                              <Input
                                type="date"
                                value={runDates[row.key] ?? ""}
                                onChange={(event) =>
                                  setRunDates((prev) => ({
                                    ...prev,
                                    [row.key]: event.target.value,
                                  }))
                                }
                                className="h-8"
                              />
                              <Button
                                type="button"
                                size="sm"
                                variant="outline"
                                className="h-8 border-amber-300 bg-amber-50 text-amber-900 hover:bg-amber-100"
                                onClick={() => handleRunAtDate(row.key, row.name)}
                              >
                                Run at Date
                              </Button>
                            </>
                          ) : null}
                        </div>
                      </TableCell>
                    </TableRow>
                  )
                })
              )
            )}
          </TableBody>
        </Table>
      </div>
    </ListPageCard>
  )
}
