import Link from "next/link";
import { and, asc, eq, sql } from "drizzle-orm";
import { requireSession } from "@/lib/auth";
import { canManageSettings } from "@/lib/rbac";
import { db } from "@/db";
import { departments, users, orders } from "@/db/schema";
import { periodRange, monthKey, today } from "@/lib/period";
import { formatPeriod } from "@/lib/format";
import { PageHeader, EmptyState } from "@/components/ui";
import { DepartmentTree, type DepartmentNode } from "./department-tree";
import { updateDepartmentAction, toggleDepartmentActiveAction } from "./actions";

export const dynamic = "force-dynamic";

export default async function DepartmentsPage() {
  const session = await requireSession();

  if (!canManageSettings(session)) {
    return (
      <>
        <PageHeader title="Phòng ban" />
        <EmptyState
          message="Bạn không có quyền sửa cơ cấu phòng ban."
          hint="Cơ cấu phòng ban quyết định ai thấy dữ liệu của ai, nên chỉ Ban giám đốc sửa được."
        />
      </>
    );
  }

  const period = monthKey(today());
  const range = periodRange(period);

  const [rows, staffRows, headcount, revenue] = await Promise.all([
    db
      .select({
        id: departments.id,
        code: departments.code,
        name: departments.name,
        parentId: departments.parentId,
        headUserId: departments.headUserId,
        isActive: departments.isActive,
      })
      .from(departments)
      .where(eq(departments.tenantId, session.tenantId))
      .orderBy(asc(departments.sortOrder), asc(departments.code)),
    db
      .select({ id: users.id, name: users.fullName })
      .from(users)
      .where(and(eq(users.tenantId, session.tenantId), eq(users.isActive, true)))
      .orderBy(asc(users.fullName)),
    db
      .select({ departmentId: users.departmentId, count: sql<number>`count(*)::int` })
      .from(users)
      .where(and(eq(users.tenantId, session.tenantId), eq(users.isActive, true)))
      .groupBy(users.departmentId),
    db
      .select({
        departmentId: orders.departmentId,
        revenue: sql<number>`coalesce(sum(${orders.totalAmount}), 0)::bigint`,
      })
      .from(orders)
      .where(
        and(
          eq(orders.tenantId, session.tenantId),
          eq(orders.status, "CONFIRMED"),
          sql`${orders.orderDate} between ${range.start} and ${range.end}`,
        ),
      )
      .groupBy(orders.departmentId),
  ]);

  const headName = new Map(staffRows.map((s) => [s.id, s.name]));
  const staffCount = new Map(
    headcount.filter((h) => h.departmentId).map((h) => [h.departmentId!, Number(h.count)]),
  );
  const revenueMap = new Map(
    revenue.filter((r) => r.departmentId).map((r) => [r.departmentId!, Number(r.revenue)]),
  );

  const nodes: DepartmentNode[] = rows.map((row) => ({
    ...row,
    headName: row.headUserId ? (headName.get(row.headUserId) ?? null) : null,
    staffCount: staffCount.get(row.id) ?? 0,
    revenue: revenueMap.get(row.id) ?? 0,
  }));

  return (
    <>
      <PageHeader
        title="Phòng ban"
        subtitle={`Cơ cấu tổ chức quyết định phạm vi dữ liệu: quản lý thấy toàn bộ nhánh mình phụ trách. Doanh thu hiển thị của ${formatPeriod(period)}.`}
        actions={
          <>
            <Link href="/danh-muc/nguoi-dung" className="btn-ghost">
              Gán nhân sự
            </Link>
            <Link href="/danh-muc" className="btn-ghost">
              ← Danh mục
            </Link>
          </>
        }
      />
      <DepartmentTree
        nodes={nodes}
        staff={staffRows}
        onUpdate={updateDepartmentAction}
        onToggleActive={toggleDepartmentActiveAction}
      />
      <p className="mt-4 text-xs text-ink-400">
        Phòng ban khác khu vực: khu vực trả lời &ldquo;khách hàng ở đâu&rdquo;, phòng ban trả lời
        &ldquo;ai quản ai&rdquo;. Một team có thể theo dòng sản phẩm chứ không thuần địa lý, nên hai
        chiều này được giữ tách nhau.
      </p>
    </>
  );
}
