import { ActionForm } from "@/components/action-form";
import Link from "next/link";
import { and, eq, asc } from "drizzle-orm";
import { requireSession } from "@/lib/auth";
import { canManageSettings } from "@/lib/rbac";
import { db } from "@/db";
import { departments, territories, users } from "@/db/schema";
import { formatDate, formatDateTime } from "@/lib/format";
import { today } from "@/lib/period";
import { PageHeader, TableWrap, Badge, EmptyState } from "@/components/ui";
import { canPostAnywhere, posterScopes, visibleAnnouncements } from "@/lib/announcements";
import { createAnnouncementAction, deactivateAnnouncementAction, togglePinAnnouncementAction, updateAnnouncementAction } from "./actions";

export const dynamic = "force-dynamic";

const SCOPE_LABEL: Record<string, string> = {
  COMPANY: "Toàn công ty",
  DEPARTMENT: "Phòng ban",
  TERRITORY: "Khu vực",
};

export default async function AnnouncementsPage() {
  const session = await requireSession();
  const scopes = await posterScopes(session);

  if (!canPostAnywhere(scopes)) {
    return (
      <>
        <PageHeader title="Thông báo" />
        <EmptyState
          message="Bạn không có quyền đăng thông báo."
          hint="Ban giám đốc đăng mọi phạm vi; Giám đốc khu vực và Quản lý đăng cho phòng ban, khu vực mình phụ trách; Hành chính nhân sự (được cấp quyền) đăng toàn công ty."
        />
      </>
    );
  }

  const [allRows, departmentRows, territoryRows, authorRows] = await Promise.all([
    visibleAnnouncements(session, { includeExpired: true }),
    db
      .select({ id: departments.id, name: departments.name })
      .from(departments)
      .where(and(eq(departments.tenantId, session.tenantId), eq(departments.isActive, true)))
      .orderBy(asc(departments.sortOrder), asc(departments.code)),
    db
      .select({ id: territories.id, name: territories.name })
      .from(territories)
      .where(and(eq(territories.tenantId, session.tenantId), eq(territories.isActive, true)))
      .orderBy(asc(territories.code)),
    db.select({ id: users.id, name: users.fullName }).from(users).where(eq(users.tenantId, session.tenantId)),
  ]);

  const isDirector = canManageSettings(session);
  // Chỉ hiện các phòng ban / khu vực người này được phép đăng, và chỉ những tin họ được sửa (của mình, hoặc mọi tin nếu là Ban giám đốc).
  const allowedDepartments = departmentRows.filter((d) => scopes.departmentIds === null || scopes.departmentIds.includes(d.id));
  const allowedTerritories = territoryRows.filter((t) => scopes.territoryIds === null || scopes.territoryIds.includes(t.id));
  const rows = allRows.filter((row) => isDirector || row.createdBy === session.userId);

  const departmentName = new Map(departmentRows.map((d) => [d.id, d.name]));
  const territoryName = new Map(territoryRows.map((t) => [t.id, t.name]));
  const authorName = new Map(authorRows.map((u) => [u.id, u.name]));
  const todayIso = today();

  function scopeDescription(row: { scopeType: string; scopeId: string | null }) {
    if (row.scopeType === "COMPANY") return SCOPE_LABEL.COMPANY;
    if (row.scopeType === "DEPARTMENT") return `Phòng ban · ${departmentName.get(row.scopeId ?? "") ?? "—"}`;
    return `Khu vực · ${territoryName.get(row.scopeId ?? "") ?? "—"}`;
  }

  return (
    <>
      <PageHeader
        title="Thông báo"
        subtitle="Tin đăng trên trang chủ — chọn phạm vi để chỉ đúng người liên quan nhìn thấy. Có thể ghim, đặt hạn hiển thị và đính kèm ảnh hoặc tệp."
        actions={
          <Link href="/danh-muc" className="btn-ghost">
            ← Danh mục
          </Link>
        }
      />

      <div className="card mb-6 p-4">
        <ActionForm action={createAnnouncementAction} success="Đã đăng thông báo." resetOnSuccess className="flex flex-col gap-3">
          <div>
            <label htmlFor="title" className="label-caps mb-1.5 block">
              Tiêu đề
            </label>
            <input id="title" name="title" required className="input" placeholder="Nhắc lịch chốt báo cáo tuần" />
          </div>
          <div>
            <label htmlFor="body" className="label-caps mb-1.5 block">
              Nội dung
            </label>
            <textarea id="body" name="body" required rows={3} className="input" placeholder="Nội dung thông báo…" />
          </div>
          <div className="grid gap-3 lg:grid-cols-2">
            <div>
              <label htmlFor="scopeType" className="label-caps mb-1.5 block">
                Phạm vi
              </label>
              <select id="scopeType" name="scopeType" className="input" defaultValue={scopes.company ? "COMPANY" : allowedDepartments.length > 0 ? "DEPARTMENT" : "TERRITORY"}>
                {scopes.company && <option value="COMPANY">Toàn công ty</option>}
                {allowedDepartments.length > 0 && <option value="DEPARTMENT">Một phòng ban</option>}
                {allowedTerritories.length > 0 && <option value="TERRITORY">Một khu vực</option>}
              </select>
            </div>
            <div>
              <label htmlFor="scopeId" className="label-caps mb-1.5 block">
                Phòng ban / Khu vực cụ thể
              </label>
              <select id="scopeId" name="scopeId" className="input">
                <option value="">— Chọn nếu phạm vi không phải toàn công ty —</option>
                {allowedDepartments.length > 0 && (
                  <optgroup label="Phòng ban">
                    {allowedDepartments.map((d) => (
                      <option key={d.id} value={d.id}>
                        {d.name}
                      </option>
                    ))}
                  </optgroup>
                )}
                {allowedTerritories.length > 0 && (
                  <optgroup label="Khu vực">
                    {allowedTerritories.map((t) => (
                      <option key={t.id} value={t.id}>
                        {t.name}
                      </option>
                    ))}
                  </optgroup>
                )}
              </select>
            </div>
            <div>
              <label htmlFor="expiresAt" className="label-caps mb-1.5 block">
                Hiển thị đến hết ngày (tuỳ chọn)
              </label>
              <input id="expiresAt" name="expiresAt" type="date" className="input" />
            </div>
            <div>
              <label htmlFor="eventDate" className="label-caps mb-1.5 block">
                Ngày diễn ra sự kiện (nếu là tin lịch sự kiện)
              </label>
              <input id="eventDate" name="eventDate" type="date" className="input" />
            </div>
            <div className="lg:col-span-2">
              <label htmlFor="file" className="label-caps mb-1.5 block">
                Đính kèm ảnh hoặc tệp (PDF, Word, Excel — tối đa 8 MB)
              </label>
              <input id="file" name="file" type="file" accept="image/*,application/pdf,.docx,.xlsx" className="input" />
            </div>
          </div>
          <label className="flex items-center gap-2 text-sm text-ink-600">
            <input type="checkbox" name="isPinned" className="h-4 w-4" />
            Ghim lên đầu trang chủ
          </label>
          <button type="submit" className="btn-primary self-start">
            Đăng thông báo
          </button>
        </ActionForm>
      </div>

      {rows.length === 0 ? (
        <EmptyState message="Chưa có thông báo nào đang hiển thị." />
      ) : (
        <TableWrap>
          <thead>
            <tr>
              <th>Tiêu đề</th>
              <th>Phạm vi</th>
              <th>Hiển thị</th>
              <th>Đăng lúc</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {rows.map((row) => {
              const expired = !!row.expiresAt && row.expiresAt < todayIso;
              return (
                <tr key={row.id} className={expired ? "opacity-60" : undefined}>
                  <td>
                    <div className="font-medium text-ink-700">
                      {row.isPinned && (
                        <span className="mr-1 text-gold-500" title="Đang ghim" aria-label="Đang ghim">
                          ★
                        </span>
                      )}
                      {row.title}
                    </div>
                    <div className="text-xs text-ink-400">{row.body}</div>
                    {row.attachmentPath && (
                      <a
                        href={`/api/anh/${row.attachmentPath}`}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="mt-1 inline-block text-xs text-brand-600 hover:underline"
                      >
                        📎 {row.attachmentName}
                      </a>
                    )}
                  </td>
                  <td>
                    <Badge tone={row.scopeType === "COMPANY" ? "brand" : "neutral"}>{scopeDescription(row)}</Badge>
                    <div className="mt-1 text-[11px] text-ink-400">{authorName.get(row.createdBy ?? "") ?? "—"}</div>
                  </td>
                  <td className="text-xs text-ink-500">
                    {row.eventDate && <div>Sự kiện: {formatDate(row.eventDate)}</div>}
                    {row.expiresAt ? (
                      expired ? (
                        <Badge tone="red">Đã hết hạn {formatDate(row.expiresAt)}</Badge>
                      ) : (
                        <div>Đến {formatDate(row.expiresAt)}</div>
                      )
                    ) : (
                      <div>Không giới hạn</div>
                    )}
                  </td>
                  <td className="tnum text-ink-500">{formatDateTime(row.createdAt)}</td>
                  <td>
                    <details className="mb-1 text-right">
                      <summary className="cursor-pointer text-xs font-semibold text-brand-600">Sửa</summary>
                      <ActionForm action={updateAnnouncementAction} success="Đã cập nhật thông báo." className="mt-2 flex w-72 flex-col gap-2 text-left">
                        <input type="hidden" name="id" value={row.id} />
                        <input name="title" required defaultValue={row.title} className="input" aria-label="Tiêu đề" />
                        <textarea name="body" required rows={3} defaultValue={row.body} className="input" aria-label="Nội dung" />
                        <label className="text-[11px] text-ink-400">
                          Hiển thị đến hết ngày
                          <input name="expiresAt" type="date" defaultValue={row.expiresAt ?? ""} className="input" />
                        </label>
                        <label className="text-[11px] text-ink-400">
                          Ngày diễn ra sự kiện
                          <input name="eventDate" type="date" defaultValue={row.eventDate ?? ""} className="input" />
                        </label>
                        <label className="text-[11px] text-ink-400">
                          {row.attachmentName ? `Thay tệp đính kèm (hiện: ${row.attachmentName})` : "Đính kèm tệp"}
                          <input name="file" type="file" accept="image/*,application/pdf,.docx,.xlsx" className="input" />
                        </label>
                        {row.attachmentName && (
                          <label className="flex items-center gap-2 text-[11px] text-ink-500">
                            <input type="checkbox" name="removeAttachment" value="1" /> Gỡ tệp đính kèm
                          </label>
                        )}
                        <button type="submit" className="btn-primary self-start px-3 py-1 text-xs">
                          Lưu thay đổi
                        </button>
                      </ActionForm>
                    </details>
                    <div className="flex justify-end gap-1">
                      <ActionForm action={togglePinAnnouncementAction} success="Đã cập nhật ghim.">
                        <input type="hidden" name="id" value={row.id} />
                        <button type="submit" className="btn-ghost px-2 py-1 text-xs">
                          {row.isPinned ? "Bỏ ghim" : "Ghim"}
                        </button>
                      </ActionForm>
                      <ActionForm action={deactivateAnnouncementAction} success="Đã gỡ thông báo." confirm="Gỡ thông báo này?">
                        <input type="hidden" name="id" value={row.id} />
                        <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
                          Gỡ
                        </button>
                      </ActionForm>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </TableWrap>
      )}
    </>
  );
}
