"use client"

import * as React from "react"
import {
  Plus,
  Pencil,
  Trash2,
  RefreshCw,
  Search,
  LayoutGrid,
  List,
  Layers,
  Users,
  Crown,
  Calendar,
  Clock,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog"
import { DeleteDialog } from "@/components/ui/delete-dialog"
import { NoDataFound } from "@/components/ui/no-data-found"
import { UserAvatar } from "@/components/ui/user-avatar"
import { toast } from "sonner"
import { format, formatDistanceToNow } from "date-fns"
import {
  useGetDivisionsPaginatedQuery,
  useCreateDivisionMutation,
  useUpdateDivisionMutation,
  useDeleteDivisionMutation,
  type Division,
} from "@/api/rtk/deal-meta-api"
import { Card, CardHeader } from "@/components/settings/ui"
import { Can } from "@/components/providers/ability-provider"
import { ReactSelect } from "@/components/ui/react-select"
import { useGetAllUsersQuery } from "@/api/rtk/teams-api"
import { useAuthToken } from "@/hooks/use-auth-token"
import { useUrlPagination } from "@/hooks/use-url-pagination"
import { cn } from "@/lib/utils"

const DIVISION_PAGE_SIZE = 10

function getErrorMessage(error: unknown, fallback: string) {
  if (
    typeof error === "object" &&
    error !== null &&
    "data" in error &&
    typeof error.data === "object" &&
    error.data !== null &&
    "message" in error.data &&
    typeof error.data.message === "string"
  ) {
    return error.data.message
  }

  if (error instanceof Error && error.message) {
    return error.message
  }

  return fallback
}

type ViewMode = "table" | "cards"

type DivisionsManagerProps = {
  layout?: "settings" | "standalone"
  onTotalChange?: (total: number) => void
}

function shellClass(standalone: boolean) {
  return standalone
    ? "rounded-2xl border border-white/40 bg-white/50 backdrop-blur-[15px] shadow-[0px_2px_20px_0px_rgba(0,0,0,0.06)]"
    : "rounded-2xl border border-gray-100 bg-white"
}

function DivisionActions({
  item,
  onEdit,
  onDelete,
  className,
}: {
  item: Division
  onEdit: (item: Division) => void
  onDelete: (item: Division) => void
  className?: string
}) {
  return (
    <div className={cn("flex items-center gap-1", className)}>
      <Can action="update" subject="division">
        <Button
          variant="ghost"
          size="icon"
          className="h-8 w-8 text-gray-400 hover:text-[#6C63FF] hover:bg-[#6C63FF]/10 rounded-lg"
          onClick={(e) => {
            e.stopPropagation()
            onEdit(item)
          }}
          aria-label={`Edit ${item.name}`}
        >
          <Pencil size={14} />
        </Button>
      </Can>
      <Can action="update" subject="division">
        <Button
          variant="ghost"
          size="icon"
          className="h-8 w-8 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-lg"
          onClick={(e) => {
            e.stopPropagation()
            onDelete(item)
          }}
          aria-label={`Delete ${item.name}`}
        >
          <Trash2 size={14} />
        </Button>
      </Can>
    </div>
  )
}

function DivisionCard({
  item,
  onEdit,
  onDelete,
}: {
  item: Division
  onEdit: (item: Division) => void
  onDelete: (item: Division) => void
}) {
  const headName = item.divisionHead?.user?.name ?? "Unassigned"
  const headEmail = item.divisionHead?.user?.email

  return (
    <article
      className={cn(
        "group relative flex flex-col rounded-2xl border border-white/60 bg-white/70 backdrop-blur-md",
        "shadow-[0px_2px_16px_0px_rgba(0,0,0,0.04)] transition-all duration-200",
        "hover:border-[#6C63FF]/30 hover:shadow-[0px_8px_24px_0px_rgba(108,99,255,0.12)] hover:-translate-y-0.5",
      )}
    >
      <div className="flex items-start justify-between gap-3 p-4 pb-3">
        <div className="flex items-start gap-3 min-w-0">
          <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[#6C63FF]/10 text-[#6C63FF]">
            <Layers size={18} />
          </div>
          <div className="min-w-0">
            <h3 className="text-[15px] font-bold text-gray-900 font-['Lexend'] truncate">
              {item.name}
            </h3>
            <p className="text-[11px] text-gray-400 font-['Lexend_Deca'] mt-0.5 uppercase tracking-wider">
              {item.teamCount ?? 0} team{(item.teamCount ?? 0) === 1 ? "" : "s"}
            </p>
          </div>
        </div>
        <DivisionActions
          item={item}
          onEdit={onEdit}
          onDelete={onDelete}
          className="opacity-80 group-hover:opacity-100"
        />
      </div>

      <div className="mx-4 h-px bg-gradient-to-r from-transparent via-gray-200/80 to-transparent" />

      <div className="p-4 pt-3 space-y-3 flex-1">
        <div className="flex items-center gap-3 rounded-xl bg-gray-50/80 px-3 py-2.5">
          <UserAvatar
            avatar={item.divisionHead?.user?.avatar ?? null}
            name={headName}
            size="sm"
            className="ring-2 ring-white shadow-sm"
          />
          <div className="min-w-0 flex-1">
            <div className="flex items-center gap-1.5 text-[10px] font-bold uppercase tracking-widest text-gray-400">
              <Crown size={10} className="text-amber-500" />
              Division head
            </div>
            <p className="text-[13px] font-semibold text-gray-800 truncate">{headName}</p>
            {headEmail ? (
              <p className="text-[11px] text-gray-400 truncate">{headEmail}</p>
            ) : null}
          </div>
        </div>

        <div className="grid grid-cols-2 gap-2">
          <div className="rounded-xl border border-gray-100 bg-white/80 px-3 py-2">
            <div className="flex items-center gap-1 text-[10px] font-bold uppercase tracking-wider text-gray-400">
              <Users size={10} />
              Teams
            </div>
            <p className="text-[18px] font-extrabold text-[#6C63FF] font-['Lexend'] leading-tight mt-0.5">
              {item.teamCount ?? 0}
            </p>
          </div>
          <div className="rounded-xl border border-gray-100 bg-white/80 px-3 py-2">
            <div className="flex items-center gap-1 text-[10px] font-bold uppercase tracking-wider text-gray-400">
              <Clock size={10} />
              Updated
            </div>
            <p className="text-[12px] font-semibold text-gray-700 mt-1 leading-snug">
              {item.updatedAt
                ? `${formatDistanceToNow(new Date(item.updatedAt))} ago`
                : "—"}
            </p>
          </div>
        </div>
      </div>

      <div className="flex items-center justify-between gap-2 border-t border-gray-100/80 px-4 py-2.5 text-[10px] text-gray-400 font-['Lexend_Deca']">
        <span className="inline-flex items-center gap-1">
          <Calendar size={10} />
          {item.createdAt ? format(new Date(item.createdAt), "MMM d, yyyy") : "—"}
        </span>
        <span>ID · {item.id.slice(0, 8)}</span>
      </div>
    </article>
  )
}

export function DivisionsManager({
  layout = "settings",
  onTotalChange,
}: DivisionsManagerProps) {
  const standalone = layout === "standalone"
  const { token } = useAuthToken()
  const urlPagination = useUrlPagination(DIVISION_PAGE_SIZE)
  const [settingsPage, setSettingsPage] = React.useState(1)
  const page = standalone ? urlPagination.page : settingsPage
  const setPage = standalone ? urlPagination.setPage : setSettingsPage
  const pageSize = standalone ? urlPagination.limit : DIVISION_PAGE_SIZE
  const [searchInput, setSearchInput] = React.useState("")
  const [search, setSearch] = React.useState("")
  const {
    data: paginatedResponse,
    isLoading,
    isFetching,
    error,
  } = useGetDivisionsPaginatedQuery(
    { page, limit: pageSize, search: search || undefined },
    { skip: !token, refetchOnMountOrArgChange: true },
  )
  const pageItems = paginatedResponse?.data ?? []
  const totalItems = paginatedResponse?.total ?? 0
  const totalPages = paginatedResponse?.totalPages ?? 1
  const [createItem, { isLoading: creating }] = useCreateDivisionMutation()
  const [updateItem, { isLoading: updating }] = useUpdateDivisionMutation()
  const [deleteItem, { isLoading: deleting }] = useDeleteDivisionMutation()
  const { data: users = [] } = useGetAllUsersQuery(undefined, { skip: !token })

  const [viewMode, setViewMode] = React.useState<ViewMode>("cards")
  const [isFormOpen, setIsFormOpen] = React.useState(false)
  const [formMode, setFormMode] = React.useState<"create" | "edit">("create")
  const [formState, setFormState] = React.useState({
    id: "",
    name: "",
    headId: "",
  })
  const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false)
  const [itemToDelete, setItemToDelete] = React.useState<Division | null>(null)

  React.useEffect(() => {
    const timer = setTimeout(() => {
      setSearch(searchInput.trim())
      setPage(1)
    }, 300)
    return () => clearTimeout(timer)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchInput])

  React.useEffect(() => {
    onTotalChange?.(totalItems)
  }, [onTotalChange, totalItems])

  React.useEffect(() => {
    if (page > totalPages) {
      setPage(totalPages)
    }
  }, [page, setPage, totalPages])

  const headOptions = React.useMemo(
    () => [
      { value: "none", label: "No division head" },
      ...users
        .filter((u) => u.role?.name?.toLowerCase() !== "admin")
        .map((u) => ({
          value: u.id,
          label: `${u.name} (${u.email})`,
        })),
    ],
    [users],
  )

  const openCreate = () => {
    setFormMode("create")
    setFormState({ id: "", name: "", headId: "" })
    setIsFormOpen(true)
  }

  const openEdit = (item: Division) => {
    setFormMode("edit")
    setFormState({
      id: item.id,
      name: item.name,
      headId: item.divisionHead?.userId ?? "",
    })
    setIsFormOpen(true)
  }

  const handleFormSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const name = formState.name.trim()
    if (!name) {
      toast.error("Name is required")
      return
    }
    const headId = formState.headId || null
    try {
      if (formMode === "create") {
        await createItem({ name, headId: headId || undefined }).unwrap()
        toast.success("Division created")
      } else {
        await updateItem({ id: formState.id, name, headId }).unwrap()
        toast.success("Division updated")
      }
      setIsFormOpen(false)
    } catch (err) {
      toast.error(getErrorMessage(err, "Failed to save division"))
    }
  }

  const confirmDelete = (item: Division) => {
    setItemToDelete(item)
    setDeleteDialogOpen(true)
  }

  const handleDelete = async () => {
    if (!itemToDelete) return
    try {
      await deleteItem(itemToDelete.id).unwrap()
      toast.success("Division deleted")
      setDeleteDialogOpen(false)
    } catch (err) {
      toast.error(getErrorMessage(err, "Failed to delete division"))
    }
  }

  const viewToggle = (
    <div className="flex bg-white/80 backdrop-blur-sm rounded-xl p-1 border border-border/40 shadow-sm shrink-0">
      <Button
        type="button"
        variant={viewMode === "cards" ? "default" : "ghost"}
        size="icon"
        className={cn(
          "h-8 w-8 rounded-lg transition-all",
          viewMode === "cards"
            ? "bg-[#6C63FF] text-white shadow-md hover:bg-[#5b54e6]"
            : "text-gray-400 hover:text-[#6C63FF] hover:bg-[#6C63FF]/5",
        )}
        onClick={() => setViewMode("cards")}
        title="Card view"
        aria-label="Card view"
        aria-pressed={viewMode === "cards"}
      >
        <LayoutGrid size={16} />
      </Button>
      <Button
        type="button"
        variant={viewMode === "table" ? "default" : "ghost"}
        size="icon"
        className={cn(
          "h-8 w-8 rounded-lg transition-all",
          viewMode === "table"
            ? "bg-[#6C63FF] text-white shadow-md hover:bg-[#5b54e6]"
            : "text-gray-400 hover:text-[#6C63FF] hover:bg-[#6C63FF]/5",
        )}
        onClick={() => setViewMode("table")}
        title="Table view"
        aria-label="Table view"
        aria-pressed={viewMode === "table"}
      >
        <List size={16} />
      </Button>
    </div>
  )

  const toolbar = (
    <div className="flex flex-col lg:flex-row items-stretch lg:items-center justify-between gap-3">
      <div className="flex flex-1 flex-col sm:flex-row items-stretch sm:items-center gap-2 min-w-0">
        <div className="relative flex-1 min-w-[180px] max-w-md">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" size={14} />
          <Input
            placeholder="Search divisions..."
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            className={cn(
              "pl-9 h-10 rounded-xl text-[13px] font-['Lexend_Deca']",
              standalone
                ? "border-white/60 bg-white/60 backdrop-blur-md"
                : "border-gray-200 bg-gray-50 focus:bg-white",
            )}
          />
        </div>
        {isFetching && !isLoading ? (
          <span className="inline-flex items-center gap-1.5 text-[11px] text-indigo-500 font-medium px-2">
            <RefreshCw size={12} className="animate-spin" />
            Syncing
          </span>
        ) : null}
      </div>
      <div className="flex items-center gap-2 shrink-0">
        {viewToggle}
        <Can action="create" subject="division">
          <Button
            onClick={openCreate}
            className={cn(
              "w-full sm:w-auto gap-2 rounded-xl h-10 px-5 shrink-0",
              standalone && "bg-[#6C63FF] hover:bg-[#5b54e6]",
            )}
          >
            <Plus size={16} />
            Add Division
          </Button>
        </Can>
      </div>
    </div>
  )

  const emptyState = (
    <NoDataFound
      variant="card"
      size="lg"
      message={search.trim() ? "No divisions match your search" : "No divisions yet"}
      description={
        search.trim()
          ? "Try a different search term or clear the filter."
          : "Create a division to group teams and assign a division head."
      }
      action={
        !search.trim() ? (
          <Can action="create" subject="division">
            <Button onClick={openCreate} className="rounded-xl gap-2">
              <Plus size={14} />
              Add Division
            </Button>
          </Can>
        ) : undefined
      }
      className="my-8"
    />
  )

  const loadingState = (
    <div className="flex flex-col items-center justify-center py-16 gap-3">
      <RefreshCw size={24} className="animate-spin text-[#6C63FF]/40" />
      <p className="text-[13px] text-gray-400 font-['Lexend_Deca']">Loading divisions…</p>
    </div>
  )

  const errorState = (
    <NoDataFound
      variant="card"
      size="md"
      message="Failed to load divisions"
      description="Check your connection and try again."
      className="my-8"
    />
  )

  const paginationFooter =
    totalItems > 0 ? (
      <div className="flex flex-col sm:flex-row items-center justify-between gap-4 py-3 border-t border-border/40">
        <p className="text-[12px] text-gray-600 font-['Lexend_Deca']">
          Showing {(page - 1) * pageSize + 1}–{Math.min(page * pageSize, totalItems)} of {totalItems}
        </p>
        {totalPages > 1 ? (
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="pagination"
              onClick={() => setPage(Math.max(1, page - 1))}
              disabled={page <= 1}
            >
              Previous
            </Button>
            <span className="text-[12px] font-semibold px-2">
              Page {page} of {totalPages}
            </span>
            <Button
              variant="outline"
              size="pagination"
              onClick={() => setPage(Math.min(totalPages, page + 1))}
              disabled={page >= totalPages}
            >
              Next
            </Button>
          </div>
        ) : null}
      </div>
    ) : null

  const cardsView = (
    <div className={cn(shellClass(standalone), "p-4 md:p-5")}>
      {error ? (
        errorState
      ) : isLoading ? (
        loadingState
      ) : pageItems.length === 0 ? (
        emptyState
      ) : (
        <>
          <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
            {pageItems.map((item) => (
              <DivisionCard
                key={item.id}
                item={item}
                onEdit={openEdit}
                onDelete={confirmDelete}
              />
            ))}
          </div>
          {paginationFooter}
        </>
      )}
    </div>
  )

  const tableView = (
    <div className={cn(shellClass(standalone), "overflow-x-auto scrollbar-themed")}>
      {error ? (
        <div className="p-6">{errorState}</div>
      ) : isLoading ? (
        loadingState
      ) : pageItems.length === 0 ? (
        <div className="p-6">{emptyState}</div>
      ) : (
        <>
          <div className="grid grid-cols-[48px_minmax(140px,1.2fr)_minmax(140px,1.2fr)_80px_minmax(120px,1fr)_minmax(100px,0.9fr)_96px] gap-3 px-5 py-3.5 bg-gray-50/80 border-b border-gray-200/50 min-w-[908px]">
            {(["#", "Name", "Division Head", "Teams", "Created", "Updated", "Actions"] as const).map(
              (label) => (
                <div
                  key={label}
                  className={cn(
                    "text-[10px] font-bold text-gray-400 uppercase tracking-widest font-['Lexend_Deca']",
                    label === "#" && "text-center",
                    label === "Actions" && "text-right",
                  )}
                >
                  {label}
                </div>
              ),
            )}
          </div>
          <div className="divide-y divide-gray-100/80 min-w-[908px]">
            {pageItems.map((item, index) => (
              <div
                key={item.id}
                className="grid grid-cols-[48px_minmax(140px,1.2fr)_minmax(140px,1.2fr)_80px_minmax(120px,1fr)_minmax(100px,0.9fr)_96px] gap-3 px-5 py-3.5 items-center hover:bg-gray-50/60 transition-colors"
              >
                <span className="text-[12px] font-semibold text-gray-500 tabular-nums text-center">
                  {(page - 1) * pageSize + index + 1}
                </span>
                <div className="flex items-center gap-2.5 min-w-0">
                  <div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#6C63FF]/10 text-[#6C63FF]">
                    <Layers size={14} />
                  </div>
                  <span className="text-[13px] font-semibold text-gray-900 truncate">
                    {item.name}
                  </span>
                </div>
                <div className="flex items-center gap-2 min-w-0">
                  <UserAvatar
                    avatar={item.divisionHead?.user?.avatar ?? null}
                    name={item.divisionHead?.user?.name ?? "?"}
                    size="sm"
                  />
                  <span className="text-[12px] text-gray-600 truncate">
                    {item.divisionHead?.user?.name ?? "Unassigned"}
                  </span>
                </div>
                <span className="text-[13px] font-bold text-[#6C63FF] tabular-nums">
                  {item.teamCount ?? 0}
                </span>
                <span className="text-[11px] text-gray-400">
                  {item.createdAt ? format(new Date(item.createdAt), "MMM d, yyyy HH:mm") : "—"}
                </span>
                <span className="text-[11px] text-gray-400">
                  {item.updatedAt
                    ? `${formatDistanceToNow(new Date(item.updatedAt))} ago`
                    : "—"}
                </span>
                <DivisionActions
                  item={item}
                  onEdit={openEdit}
                  onDelete={confirmDelete}
                  className="justify-end"
                />
              </div>
            ))}
          </div>
          <div className="px-5">{paginationFooter}</div>
        </>
      )}
    </div>
  )

  const content = (
    <>
      {toolbar}
      {viewMode === "cards" ? cardsView : tableView}
    </>
  )

  const dialogs = (
    <>
      <Dialog open={isFormOpen} onOpenChange={setIsFormOpen}>
        <DialogContent className="sm:max-w-[420px] rounded-3xl">
          <DialogHeader>
            <DialogTitle className="text-[18px] font-extrabold text-gray-900 font-['Lexend']">
              {formMode === "create" ? "Add Division" : "Edit Division"}
            </DialogTitle>
            <DialogDescription className="text-[13px] text-gray-500">
              Divisions group teams. A division head can view all teams in the division.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={handleFormSubmit} className="space-y-4 py-2">
            <div className="space-y-2">
              <Label className="text-[11px] font-bold text-gray-400 uppercase tracking-widest">
                Name
              </Label>
              <Input
                value={formState.name}
                onChange={(e) => setFormState((p) => ({ ...p, name: e.target.value }))}
                placeholder="e.g. North America"
                className="h-11 rounded-xl border-gray-200 bg-gray-50 focus:bg-white"
                autoFocus
              />
            </div>
            <div className="space-y-2">
              <Label className="text-[11px] font-bold text-gray-400 uppercase tracking-widest">
                Division Head
              </Label>
              <ReactSelect
                value={formState.headId || "none"}
                onValueChange={(val) =>
                  setFormState((p) => ({ ...p, headId: val === "none" ? "" : val }))
                }
                options={headOptions}
                placeholder="No division head"
                aria-label="Division head"
                triggerClassName="h-11 rounded-xl border-gray-200 bg-gray-50"
              />
            </div>
            <DialogFooter className="pt-2">
              <Button
                type="button"
                variant="ghost"
                onClick={() => setIsFormOpen(false)}
                className="rounded-xl"
              >
                Cancel
              </Button>
              <Button
                type="submit"
                disabled={creating || updating || !formState.name.trim()}
                className="rounded-xl px-6"
              >
                {creating || updating ? (
                  <RefreshCw size={14} className="animate-spin mr-2" />
                ) : null}
                Save Changes
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <DeleteDialog
        open={deleteDialogOpen}
        onOpenChange={setDeleteDialogOpen}
        onConfirm={handleDelete}
        title="Delete division"
        description={`Delete "${itemToDelete?.name}"? Divisions with active teams cannot be deleted.`}
        isLoading={deleting}
      />
    </>
  )

  if (standalone) {
    return (
      <div className="space-y-4">
        {content}
        {dialogs}
      </div>
    )
  }

  return (
    <Card className="animate-in fade-in slide-in-from-right-4 duration-500">
      <CardHeader
        title="Divisions"
        description="Organize teams under divisions and assign a division head."
      />
      <div className="p-6 space-y-4">
        {content}
      </div>
      {dialogs}
    </Card>
  )
}
