// Bảng điều khiển Văn phòng số (E-Office) — landing dashboard, PURO HomePage style.
// Composes the 3 shared ui widgets (PageHeader / KpiCard / WidgetCard) over the
// EXISTING data hooks of the four E-Office modules. NO new API calls, NO new BE:
// every query below mirrors the queryKey + endpoint already used by the module
// pages, so the TanStack cache is shared and counts are computed client-side.
//
//   • Đề xuất        → GET /proposals            (ProposalsListPage)
//   • Đơn từ         → GET /leave|ot|travel-requests (WorkflowAppsListPage KIND_CONFIG)
//   • Ticket CNTT    → GET /it-tickets           (ItTicketsPage)
//   • Phòng họp      → GET /meeting-bookings      (MeetingCalendarPage)
//
// Layout: PageHeader (brand) on top, then a 2-col grid — LEFT (~2/3) a stack of
// WidgetCards, RIGHT (~1/3) a "Công việc của tôi" panel + quick-action buttons.
// Stacks to 1 column under lg. Each widget's onExpand navigates to its real route.
// gotcha 66: any heading on the brand gradient lives inside WidgetCard, which
// already uses text-white! — this page adds no gradient headings of its own.
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import {
  AlertTriangle,
  CalendarDays,
  ClipboardList,
  FilePlus2,
  FileSignature,
  Inbox,
  LayoutDashboard,
  ListChecks,
  Plus,
  Ticket,
} from 'lucide-react'
import { PageHeader } from '@/components/ui/PageHeader'
import { KpiCard } from '@/components/ui/KpiCard'
import { WidgetCard } from '@/components/ui/WidgetCard'
import { Button } from '@/components/ui/Button'
import { api } from '@/lib/api'
import { cn } from '@/lib/cn'
import { ProposalStatus, type PagedResult, type ProposalListItemDto } from '@/types/proposal'
import {
  IT_TICKET_STATUS_LABELS,
  ItTicketStatus,
  WorkflowAppStatus,
  type ItTicketDto,
  type LeaveRequestDto,
  type OtRequestDto,
  type TravelRequestDto,
} from '@/types/workflowApps'
import type { MeetingBookingDto } from '@/types/meeting'

// ── date window for "today" meeting bookings (local midnight → next midnight) ──
function todayWindow(): { start: string; end: string } {
  const start = new Date()
  start.setHours(0, 0, 0, 0)
  const end = new Date(start)
  end.setDate(end.getDate() + 1)
  return { start: start.toISOString(), end: end.toISOString() }
}

function countByStatus<T extends { status: number }>(items: T[], status: number): number {
  return items.reduce((n, x) => (x.status === status ? n + 1 : n), 0)
}

// A small skeleton body used while a widget's data is loading. Mimics a couple of
// stat rows so the card keeps its height (no layout shift on resolve).
function WidgetSkeleton() {
  return (
    <div className="space-y-2.5" aria-hidden>
      <div className="h-3.5 w-2/3 animate-pulse rounded bg-slate-100 motion-reduce:animate-none" />
      <div className="h-3.5 w-1/2 animate-pulse rounded bg-slate-100 motion-reduce:animate-none" />
      <div className="h-3.5 w-3/5 animate-pulse rounded bg-slate-100 motion-reduce:animate-none" />
    </div>
  )
}

// Inline error body — graceful, never blocks the page.
function WidgetError({ onRetry }: { onRetry: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center gap-2 py-6 text-center">
      <span
        className="icon-chip"
        style={{ ['--chip-bg' as string]: 'var(--color-accent-500)', ['--chip-fg' as string]: '#fff' }}
        aria-hidden
      >
        <AlertTriangle className="h-4 w-4" />
      </span>
      <p className="text-xs text-slate-500">Không tải được dữ liệu.</p>
      <button
        type="button"
        onClick={onRetry}
        className="rounded-md px-2 py-1 text-xs font-medium text-brand-600 transition hover:bg-brand-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500"
      >
        Thử lại
      </button>
    </div>
  )
}

// A labelled metric line inside a widget body. `tone` tints the value; clickable
// rows expose a button affordance (used to deep-link a filtered list view).
function MetricRow({
  label,
  value,
  tone,
  onClick,
}: {
  label: string
  value: number
  tone: string
  onClick?: () => void
}) {
  const clickable = !!onClick
  return (
    <div
      role={clickable ? 'button' : undefined}
      tabIndex={clickable ? 0 : undefined}
      onClick={onClick}
      onKeyDown={
        clickable
          ? (e) => {
              if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault()
                onClick?.()
              }
            }
          : undefined
      }
      className={cn(
        'flex items-center justify-between gap-3 rounded-lg px-2.5 py-1.5 transition',
        clickable &&
          'cursor-pointer hover:bg-slate-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500',
      )}
    >
      <span className="text-[13px] text-slate-600">{label}</span>
      <span className={cn('stat-value text-base', tone)}>{value}</span>
    </div>
  )
}

export function OfficeDashboardPage() {
  const navigate = useNavigate()
  const { start, end } = useMemo(todayWindow, [])

  // ── Đề xuất ── same queryKey/endpoint as ProposalsListPage (shared cache).
  // First page, large size: enough to count the active workload client-side.
  const proposalsQ = useQuery({
    queryKey: ['proposals', { status: null, inboxOnly: false, search: '', page: 1, dashboard: true }],
    queryFn: async () =>
      (await api.get<PagedResult<ProposalListItemDto>>('/proposals', { params: { page: 1, pageSize: 100 } })).data,
  })
  // "Cần duyệt" = items in MY approval inbox (BE inboxOnly filter — the real
  // needs-my-action signal). Mirrors the inbox toggle on ProposalsListPage.
  const proposalsInboxQ = useQuery({
    queryKey: ['proposals', { status: null, inboxOnly: true, search: '', page: 1, dashboard: true }],
    queryFn: async () =>
      (await api.get<PagedResult<ProposalListItemDto>>('/proposals', { params: { inboxOnly: true, page: 1, pageSize: 100 } }))
        .data,
  })

  // ── Đơn từ ── three endpoints from WorkflowAppsListPage KIND_CONFIG.
  const leaveQ = useQuery({
    queryKey: ['/leave-requests', { page: 1 }],
    queryFn: async () => (await api.get<PagedResult<LeaveRequestDto>>('/leave-requests', { params: { page: 1, pageSize: 50 } })).data,
  })
  const otQ = useQuery({
    queryKey: ['/ot-requests', { page: 1 }],
    queryFn: async () => (await api.get<PagedResult<OtRequestDto>>('/ot-requests', { params: { page: 1, pageSize: 50 } })).data,
  })
  const travelQ = useQuery({
    queryKey: ['/travel-requests', { page: 1 }],
    queryFn: async () => (await api.get<PagedResult<TravelRequestDto>>('/travel-requests', { params: { page: 1, pageSize: 50 } })).data,
  })

  // ── Ticket CNTT ── same queryKey/endpoint as ItTicketsPage (shared cache).
  const ticketsQ = useQuery({
    queryKey: ['it-tickets'],
    queryFn: async () => (await api.get<PagedResult<ItTicketDto>>('/it-tickets', { params: { pageSize: 100 } })).data,
  })

  // ── Phòng họp hôm nay ── /meeting-bookings windowed to today (no room filter).
  const meetingsTodayQ = useQuery({
    queryKey: ['meeting-bookings', { dashboard: 'today', start }],
    queryFn: async () =>
      (await api.get<MeetingBookingDto[]>('/meeting-bookings', { params: { startDate: start, endDate: end } })).data,
  })

  // ── derived counts (client-side) ──
  const proposals = proposalsQ.data?.items ?? []
  const proposalTotal = proposalsQ.data?.total ?? proposals.length
  const proposalPending = countByStatus(proposals, ProposalStatus.DaGuiDuyet)
  const proposalInbox = proposalsInboxQ.data?.total ?? (proposalsInboxQ.data?.items.length ?? 0)

  const donTu = useMemo(
    () => [...(leaveQ.data?.items ?? []), ...(otQ.data?.items ?? []), ...(travelQ.data?.items ?? [])],
    [leaveQ.data, otQ.data, travelQ.data],
  )
  const donTuSubmitted = countByStatus(donTu, WorkflowAppStatus.DaGuiDuyet)
  const donTuReturned = countByStatus(donTu, WorkflowAppStatus.TraLai)
  const donTuApproved = countByStatus(donTu, WorkflowAppStatus.DaDuyet)
  const donTuLoading = leaveQ.isLoading || otQ.isLoading || travelQ.isLoading
  const donTuError = leaveQ.isError || otQ.isError || travelQ.isError

  const tickets = ticketsQ.data?.items ?? []
  const ticketOpen = countByStatus(tickets, ItTicketStatus.Open)
  const ticketInProgress = countByStatus(tickets, ItTicketStatus.InProgress)
  const ticketBreached = tickets.reduce((n, t) => (t.slaBreached ? n + 1 : n), 0)

  const meetingsToday = meetingsTodayQ.data ?? []
  const meetingsTodayCount = meetingsToday.length

  // "Công việc của tôi" — total items currently awaiting THIS user's action across
  // the modules. Proposals come from the BE inbox filter; đơn-từ in "Đã gửi duyệt"
  // are pending approval. (Tickets have their own assignment flow, surfaced in
  // their widget rather than double-counted here.)
  const myTodo = proposalInbox + donTuSubmitted

  return (
    <div className="p-6">
      <PageHeader
        eyebrow="Văn phòng số"
        title="Bảng điều khiển"
        subtitle="Tổng quan đề xuất, đơn từ, ticket và lịch họp trong ngày"
        icon={<LayoutDashboard className="h-5 w-5" />}
        accent="brand"
      />

      <div className="grid grid-cols-1 gap-5 lg:grid-cols-3">
        {/* ───────────────────────── LEFT (~2/3) — widget stack ───────────────────────── */}
        <div className="flex flex-col gap-5 lg:col-span-2">
          {/* Đề xuất */}
          <WidgetCard
            title="Đề xuất"
            icon={<FileSignature className="h-4 w-4" />}
            accent="brand"
            onExpand={() => navigate('/proposals')}
            onRefresh={() => {
              proposalsQ.refetch()
              proposalsInboxQ.refetch()
            }}
            empty={!proposalsQ.isLoading && !proposalsQ.isError && proposalTotal === 0}
            emptyText="Chưa có đề xuất nào."
          >
            {proposalsQ.isError ? (
              <WidgetError onRetry={() => proposalsQ.refetch()} />
            ) : proposalsQ.isLoading ? (
              <WidgetSkeleton />
            ) : (
              <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
                <KpiCard
                  label="Cần duyệt"
                  value={proposalInbox}
                  icon={<Inbox className="h-4 w-4" />}
                  accent="amberx"
                  onClick={() => navigate('/proposals?inboxOnly=true')}
                />
                <KpiCard
                  label="Chờ duyệt"
                  value={proposalPending}
                  icon={<ClipboardList className="h-4 w-4" />}
                  accent="brand"
                  onClick={() => navigate(`/proposals?status=${ProposalStatus.DaGuiDuyet}`)}
                />
                <KpiCard
                  label="Tất cả"
                  value={proposalTotal}
                  icon={<ListChecks className="h-4 w-4" />}
                  accent="teal"
                  onClick={() => navigate('/proposals')}
                />
              </div>
            )}
          </WidgetCard>

          {/* Đơn từ (nghỉ phép / OT / công tác) */}
          <WidgetCard
            title="Đơn từ"
            icon={<FileSignature className="h-4 w-4" />}
            accent="teal"
            onExpand={() => navigate('/workflow-apps/leave')}
            onRefresh={() => {
              leaveQ.refetch()
              otQ.refetch()
              travelQ.refetch()
            }}
            empty={!donTuLoading && !donTuError && donTu.length === 0}
            emptyText="Chưa có đơn từ nào."
          >
            {donTuError ? (
              <WidgetError
                onRetry={() => {
                  leaveQ.refetch()
                  otQ.refetch()
                  travelQ.refetch()
                }}
              />
            ) : donTuLoading ? (
              <WidgetSkeleton />
            ) : (
              <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
                <KpiCard
                  label="Đã gửi duyệt"
                  value={donTuSubmitted}
                  accent="amberx"
                  onClick={() => navigate('/workflow-apps/leave')}
                />
                <KpiCard
                  label="Trả lại"
                  value={donTuReturned}
                  accent="violet"
                  onClick={() => navigate('/workflow-apps/leave')}
                />
                <KpiCard
                  label="Đã duyệt"
                  value={donTuApproved}
                  accent="greenx"
                  onClick={() => navigate('/workflow-apps/leave')}
                />
              </div>
            )}
          </WidgetCard>

          {/* Ticket CNTT */}
          <WidgetCard
            title="Ticket CNTT"
            icon={<Ticket className="h-4 w-4" />}
            accent="violet"
            onExpand={() => navigate('/it-tickets')}
            onRefresh={() => ticketsQ.refetch()}
            empty={!ticketsQ.isLoading && !ticketsQ.isError && tickets.length === 0}
            emptyText="Chưa có ticket nào."
          >
            {ticketsQ.isError ? (
              <WidgetError onRetry={() => ticketsQ.refetch()} />
            ) : ticketsQ.isLoading ? (
              <WidgetSkeleton />
            ) : (
              <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
                <KpiCard
                  label={IT_TICKET_STATUS_LABELS[ItTicketStatus.Open]}
                  value={ticketOpen}
                  icon={<Inbox className="h-4 w-4" />}
                  accent="violet"
                  onClick={() => navigate('/it-tickets')}
                />
                <KpiCard
                  label={IT_TICKET_STATUS_LABELS[ItTicketStatus.InProgress]}
                  value={ticketInProgress}
                  icon={<ClipboardList className="h-4 w-4" />}
                  accent="brand"
                  onClick={() => navigate('/it-tickets')}
                />
                <KpiCard
                  label="Quá hạn SLA"
                  value={ticketBreached}
                  icon={<AlertTriangle className="h-4 w-4" />}
                  accent="amberx"
                  onClick={() => navigate('/it-tickets')}
                />
              </div>
            )}
          </WidgetCard>

          {/* Phòng họp hôm nay */}
          <WidgetCard
            title="Phòng họp hôm nay"
            icon={<CalendarDays className="h-4 w-4" />}
            accent="amberx"
            onExpand={() => navigate('/meeting-calendar')}
            onRefresh={() => meetingsTodayQ.refetch()}
            empty={!meetingsTodayQ.isLoading && !meetingsTodayQ.isError && meetingsTodayCount === 0}
            emptyText="Hôm nay chưa có lịch họp."
          >
            {meetingsTodayQ.isError ? (
              <WidgetError onRetry={() => meetingsTodayQ.refetch()} />
            ) : meetingsTodayQ.isLoading ? (
              <WidgetSkeleton />
            ) : (
              <div className="space-y-3">
                <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
                  <KpiCard
                    label="Lịch họp hôm nay"
                    value={meetingsTodayCount}
                    icon={<CalendarDays className="h-4 w-4" />}
                    accent="amberx"
                    onClick={() => navigate('/meeting-calendar')}
                  />
                </div>
                {/* A compact peek of the next few bookings today. */}
                <ul className="divide-y divide-slate-100 overflow-hidden rounded-lg border border-slate-200">
                  {meetingsToday
                    .slice()
                    .sort((a, b) => new Date(a.startAt).getTime() - new Date(b.startAt).getTime())
                    .slice(0, 4)
                    .map((b) => (
                      <li key={b.id} className="flex items-center justify-between gap-3 px-3 py-2 text-xs">
                        <span className="min-w-0 truncate font-medium text-slate-700">{b.title}</span>
                        <span className="shrink-0 tabular-nums text-slate-500">
                          {new Date(b.startAt).toLocaleTimeString('vi-VN', { hour: '2-digit', minute: '2-digit' })} ·{' '}
                          {b.roomCode}
                        </span>
                      </li>
                    ))}
                </ul>
              </div>
            )}
          </WidgetCard>
        </div>

        {/* ───────────────────────── RIGHT (~1/3) — my work + actions ───────────────────────── */}
        <div className="flex flex-col gap-5 lg:col-span-1">
          {/* Công việc của tôi */}
          <WidgetCard
            title="Công việc của tôi"
            icon={<ListChecks className="h-4 w-4" />}
            accent="brand"
            empty={false}
          >
            {proposalsInboxQ.isError ? (
              <WidgetError onRetry={() => proposalsInboxQ.refetch()} />
            ) : (
              <div className="space-y-3">
                <div className="flex items-end justify-between gap-3 rounded-xl bg-brand-50 px-3.5 py-3">
                  <div>
                    <div className="label-eyebrow">Cần xử lý</div>
                    <p className="mt-0.5 text-[13px] text-slate-600">Mục đang chờ thao tác của bạn</p>
                  </div>
                  <div className="stat-value text-3xl text-brand-800">
                    {proposalsInboxQ.isLoading || donTuLoading ? '—' : myTodo}
                  </div>
                </div>
                <div className="space-y-1">
                  <MetricRow
                    label="Đề xuất chờ tôi duyệt"
                    value={proposalsInboxQ.isLoading ? 0 : proposalInbox}
                    tone="text-brand-800"
                    onClick={() => navigate('/proposals?inboxOnly=true')}
                  />
                  <MetricRow
                    label="Đơn từ đã gửi duyệt"
                    value={donTuLoading ? 0 : donTuSubmitted}
                    tone="text-teal-700"
                    onClick={() => navigate('/workflow-apps/leave')}
                  />
                  <MetricRow
                    label="Ticket đang mở"
                    value={ticketsQ.isLoading ? 0 : ticketOpen}
                    tone="text-violet-700"
                    onClick={() => navigate('/it-tickets')}
                  />
                </div>
              </div>
            )}
          </WidgetCard>

          {/* Thao tác nhanh */}
          <section className="card-accent flex flex-col gap-2 p-4" style={{ ['--accent' as string]: 'var(--color-brand-500)' }}>
            <h3 className="mb-1 text-sm font-semibold tracking-tight text-slate-800">Thao tác nhanh</h3>
            <Button variant="primary" className="justify-start" onClick={() => navigate('/proposals/new')}>
              <FilePlus2 className="h-4 w-4" />
              Tạo đề xuất
            </Button>
            <Button variant="secondary" className="justify-start" onClick={() => navigate('/workflow-apps/leave')}>
              <FileSignature className="h-4 w-4" />
              Tạo đơn
            </Button>
            <Button variant="outline" className="justify-start" onClick={() => navigate('/it-tickets')}>
              <Plus className="h-4 w-4" />
              Tạo ticket
            </Button>
          </section>
        </div>
      </div>
    </div>
  )
}
