"use client";

import { ActionForm } from "@/components/action-form";
import Link from "next/link";
import { useActionState, useState } from "react";
import { useFormStatus } from "react-dom";
import {
  createUserAction,
  updateUserAction,
  resetPasswordAction,
  type UserFormState,
} from "./actions";
import { ROLE_LABEL } from "@/lib/format";

export type TerritoryOption = { id: string; name: string; level: string };
export type DepartmentOption = { id: string; name: string; depth: number };
export type UserRow = {
  id: string;
  email: string;
  fullName: string;
  phone: string | null;
  jobTitle: string | null;
  role: "DIRECTOR" | "GDKV" | "MANAGER" | "SALES";
  territoryId: string | null;
  departmentId: string | null;
  managedTerritoryIds: string[];
  birthDate: string | null;
  gender: string | null;
  lastLoginAt: string | null;
};

const ALL_ROLES = ["DIRECTOR", "GDKV", "MANAGER", "SALES"] as const;
type Role = (typeof ALL_ROLES)[number];

function Submit({ label, pendingLabel }: { label: string; pendingLabel: string }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className="btn-primary" disabled={pending}>
      {pending ? pendingLabel : label}
    </button>
  );
}

/** Ô chọn phòng ban — quyết định phạm vi dữ liệu, nên hiện cho mọi vai trò. */
function DepartmentField({
  departments,
  defaultValue,
  required,
}: {
  departments: DepartmentOption[];
  defaultValue?: string | null;
  /** Bắt buộc chọn — dành cho người quản lý nhánh, tài khoản mới phải nằm trong nhánh của họ. */
  required?: boolean;
}) {
  return (
    <div>
      <label className="label-caps mb-1.5 block">Phòng ban / Team</label>
      <select name="departmentId" defaultValue={defaultValue ?? ""} required={required} className="input">
        {!required && <option value="">— Chưa phân phòng ban —</option>}
        {required && <option value="" disabled>— Chọn phòng ban / team —</option>}
        {departments.map((department) => (
          <option key={department.id} value={department.id}>
            {"— ".repeat(department.depth)}
            {department.name}
          </option>
        ))}
      </select>
      <p className="mt-1 text-[11px] text-ink-400">
        Quản lý thấy dữ liệu của toàn bộ nhánh phòng ban này.
      </p>
    </div>
  );
}

/** Ô chọn khu vực đổi theo vai trò: NVKD một khu vực, quản lý vùng nhiều khu vực. */
function TerritoryFields({
  role,
  territories,
  defaultTerritoryId,
  defaultManaged,
}: {
  role: string;
  territories: TerritoryOption[];
  defaultTerritoryId?: string | null;
  defaultManaged?: string[];
}) {
  if (role === "DIRECTOR") {
    return (
      <div className="rounded-lg bg-ink-50 px-3 py-2 text-xs text-ink-500">
        Ban giám đốc xem được toàn bộ dữ liệu, không cần gán khu vực.
      </div>
    );
  }

  if (role === "SALES") {
    return (
      <div>
        <label className="label-caps mb-1.5 block">Khu vực phụ trách</label>
        <select name="territoryId" defaultValue={defaultTerritoryId ?? ""} className="input">
          <option value="">— Chưa phân công —</option>
          {territories.map((territory) => (
            <option key={territory.id} value={territory.id}>
              {territory.name}
            </option>
          ))}
        </select>
      </div>
    );
  }

  return (
    <div>
      <label className="label-caps mb-1.5 block">Các khu vực phụ trách</label>
      <div className="flex flex-wrap gap-x-4 gap-y-2 rounded-lg border border-[var(--color-line)] p-3">
        {territories.map((territory) => (
          <label key={territory.id} className="flex items-center gap-2 text-sm text-ink-600">
            <input
              type="checkbox"
              name="managedTerritories"
              value={territory.id}
              defaultChecked={defaultManaged?.includes(territory.id)}
              className="h-4 w-4 accent-brand-500"
            />
            {territory.name}
          </label>
        ))}
      </div>
      <p className="mt-1 text-[11px] text-ink-400">
        Quản lý vùng thấy dữ liệu của các khu vực này và mọi cấp con bên dưới.
      </p>
    </div>
  );
}

export function CreateUserForm({
  territories,
  departments,
  allowedRoles = [...ALL_ROLES],
  requireDepartment = false,
}: {
  territories: TerritoryOption[];
  departments: DepartmentOption[];
  allowedRoles?: Role[];
  requireDepartment?: boolean;
}) {
  const [state, formAction] = useActionState<UserFormState, FormData>(createUserAction, {});
  const [role, setRole] = useState<string>(allowedRoles.includes("SALES") ? "SALES" : allowedRoles[0]);

  return (
    <form action={formAction} className="card flex flex-col gap-4 p-4">
      <h2 className="text-base font-bold text-ink-700">Tạo tài khoản mới</h2>

      <div className="grid gap-4 lg:grid-cols-4">
        <div>
          <label htmlFor="fullName" className="label-caps mb-1.5 block">
            Họ tên *
          </label>
          <input id="fullName" name="fullName" required className="input" placeholder="Nguyễn Văn A" />
        </div>
        <div>
          <label htmlFor="email" className="label-caps mb-1.5 block">
            Email đăng nhập *
          </label>
          <input id="email" name="email" type="email" required className="input" placeholder="ten@congty.vn" />
        </div>
        <div>
          <label htmlFor="phone" className="label-caps mb-1.5 block">
            Điện thoại
          </label>
          <input id="phone" name="phone" type="tel" className="input" />
        </div>
        <div>
          <label htmlFor="jobTitle" className="label-caps mb-1.5 block">
            Chức vụ
          </label>
          <input
            id="jobTitle"
            name="jobTitle"
            className="input"
            placeholder="Trợ lý GĐ kinh doanh, HCNS, Kế toán trưởng..."
          />
        </div>
        <div>
          <label htmlFor="role" className="label-caps mb-1.5 block">
            Vai trò *
          </label>
          <select
            id="role"
            name="role"
            value={role}
            onChange={(event) => setRole(event.target.value)}
            className="input"
          >
            {ALL_ROLES.filter((value) => allowedRoles.includes(value)).map((value) => (
              <option key={value} value={value}>
                {ROLE_LABEL[value]}
              </option>
            ))}
          </select>
        </div>
      </div>
      <p className="-mt-2 text-[11px] text-ink-400">
        Chức vụ chỉ để hiển thị trên hồ sơ — quyền hạn thật vẫn theo Vai trò. Cần quyền đặc biệt
        (ví dụ tải văn bản) thì cấp riêng ở bảng bên dưới sau khi tạo tài khoản.
      </p>

      <div className="lg:w-1/2">
        <DepartmentField departments={departments} required={requireDepartment} />
      </div>

      <TerritoryFields role={role} territories={territories} />

      <div className="lg:w-1/2">
        <label htmlFor="password" className="label-caps mb-1.5 block">
          Mật khẩu đăng nhập lần đầu *
        </label>
        <input
          id="password"
          name="password"
          type="text"
          required
          minLength={8}
          className="input"
          placeholder="Tối thiểu 8 ký tự"
        />
        <p className="mt-1 text-[11px] text-ink-400">
          Hệ thống chỉ lưu bản băm của mật khẩu, không lưu bản gốc và không hiển thị lại được.
          Hãy chuyển mật khẩu này cho người dùng qua kênh riêng và nhắc họ đổi sau lần đăng nhập đầu.
        </p>
      </div>

      {state.error && (
        <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
          {state.error}
        </p>
      )}
      {state.ok && <p className="rounded-lg bg-ink-100 px-3 py-2 text-sm text-brand-600">{state.ok}</p>}

      <div>
        <Submit label="Tạo tài khoản" pendingLabel="Đang tạo…" />
      </div>
    </form>
  );
}

export function EditUserForm({
  user,
  territories,
  departments,
  onClose,
  allowedRoles = [...ALL_ROLES],
}: {
  user: UserRow;
  territories: TerritoryOption[];
  departments: DepartmentOption[];
  onClose: () => void;
  allowedRoles?: Role[];
}) {
  const [state, formAction] = useActionState<UserFormState, FormData>(updateUserAction, {});
  const [pwState, resetAction] = useActionState<UserFormState, FormData>(resetPasswordAction, {});
  const [role, setRole] = useState<string>(user.role);

  return (
    <div className="card flex flex-col gap-4 p-4">
      <div className="flex items-start justify-between gap-3">
        <div>
          <h2 className="text-base font-bold text-ink-700">Sửa tài khoản</h2>
          <p className="text-sm text-ink-400">{user.email}</p>
        </div>
        <button type="button" onClick={onClose} className="btn-ghost px-3 py-1 text-xs">
          Đóng
        </button>
      </div>

      <form action={formAction} className="flex flex-col gap-4">
        <input type="hidden" name="id" value={user.id} />

        <div className="grid gap-4 lg:grid-cols-4">
          <div>
            <label className="label-caps mb-1.5 block">Họ tên</label>
            <input name="fullName" defaultValue={user.fullName} required className="input" />
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Email đăng nhập</label>
            <input name="email" type="email" defaultValue={user.email} required className="input" />
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Điện thoại</label>
            <input name="phone" defaultValue={user.phone ?? ""} className="input" />
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Chức vụ</label>
            <input
              name="jobTitle"
              defaultValue={user.jobTitle ?? ""}
              className="input"
              placeholder="Trợ lý GĐ kinh doanh, HCNS..."
            />
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Ngày sinh</label>
            <input name="birthDate" type="date" defaultValue={user.birthDate ?? ""} className="input" />
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Giới tính</label>
            <select name="gender" defaultValue={user.gender ?? ""} className="input">
              <option value="">— Không nêu —</option>
              <option value="M">Nam</option>
              <option value="F">Nữ</option>
              <option value="O">Khác</option>
            </select>
          </div>
          <div>
            <label className="label-caps mb-1.5 block">Vai trò</label>
            <select
              name="role"
              value={role}
              onChange={(event) => setRole(event.target.value)}
              className="input"
            >
              {ALL_ROLES.filter((value) => allowedRoles.includes(value) || value === user.role).map((value) => (
                <option key={value} value={value} disabled={!allowedRoles.includes(value)}>
                  {ROLE_LABEL[value]}
                </option>
              ))}
            </select>
          </div>
        </div>

        <div className="lg:w-1/2">
          <DepartmentField departments={departments} defaultValue={user.departmentId} />
        </div>

        <TerritoryFields
          role={role}
          territories={territories}
          defaultTerritoryId={user.territoryId}
          defaultManaged={user.managedTerritoryIds}
        />

        {state.error && (
          <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
            {state.error}
          </p>
        )}
        {state.ok && <p className="rounded-lg bg-ink-100 px-3 py-2 text-sm text-brand-600">{state.ok}</p>}

        <div>
          <Submit label="Lưu thay đổi" pendingLabel="Đang lưu…" />
        </div>
      </form>

      <form action={resetAction} className="flex flex-wrap items-end gap-3 border-t border-[var(--color-line)] pt-4">
        <input type="hidden" name="id" value={user.id} />
        <div className="min-w-56 flex-1">
          <label className="label-caps mb-1.5 block">Đặt lại mật khẩu</label>
          <input
            name="password"
            type="text"
            minLength={8}
            required
            className="input"
            placeholder="Mật khẩu mới, tối thiểu 8 ký tự"
          />
        </div>
        <Submit label="Đặt lại" pendingLabel="Đang đặt…" />
        {pwState.error && <p className="text-sm text-red-700">{pwState.error}</p>}
        {pwState.ok && <p className="text-sm text-brand-600">{pwState.ok}</p>}
      </form>
    </div>
  );
}

export function UserTable({
  users,
  territories,
  departments,
  territoryNames,
  departmentNames,
  currentUserId,
  onToggleActive,
  activeMap,
  lockedMap,
  onUnlockLogin,
  canUploadDocumentsMap,
  onToggleCanUploadDocuments,
  canEditStaffInfoMap,
  onToggleCanEditStaffInfo,
  onDelete,
  deletableMap,
  canPostAnnouncementsMap,
  onToggleCanPostAnnouncements,
  canGrantPostAnnouncements = true,
  allowedRoles = [...ALL_ROLES],
  canGrantUploadDocuments = true,
  canGrantEditStaffInfo = true,
}: {
  users: UserRow[];
  territories: TerritoryOption[];
  departments: DepartmentOption[];
  territoryNames: Record<string, string>;
  departmentNames: Record<string, string>;
  currentUserId: string;
  onToggleActive: (formData: FormData) => Promise<unknown>;
  activeMap: Record<string, boolean>;
  lockedMap: Record<string, boolean>;
  onUnlockLogin: (formData: FormData) => Promise<unknown>;
  canUploadDocumentsMap: Record<string, boolean>;
  onToggleCanUploadDocuments: (formData: FormData) => Promise<unknown>;
  canEditStaffInfoMap: Record<string, boolean>;
  onToggleCanEditStaffInfo: (formData: FormData) => Promise<unknown>;
  onDelete: (formData: FormData) => Promise<unknown>;
  canPostAnnouncementsMap: Record<string, boolean>;
  onToggleCanPostAnnouncements: (formData: FormData) => Promise<unknown>;
  canGrantPostAnnouncements?: boolean;
  /** Tài khoản xoá hẳn được (tạo nhầm: chưa đăng nhập, chưa có dữ liệu). */
  deletableMap: Record<string, boolean>;
  /** Vai trò người thao tác được gán; cờ quyền chỉ cấp được khi chính người thao tác đang có. */
  allowedRoles?: Role[];
  canGrantUploadDocuments?: boolean;
  canGrantEditStaffInfo?: boolean;
}) {
  const [editing, setEditing] = useState<string | null>(null);
  const editingUser = users.find((u) => u.id === editing);
  // Lọc nhanh trong danh sách (hàng chục tài khoản): theo tên/email/chức vụ và theo trạng thái.
  const [query, setQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState<"" | "active" | "blocked" | "locked">("");
  const needle = query.trim().toLowerCase();
  const visibleUsers = users.filter((user) => {
    if (needle && !`${user.fullName} ${user.email} ${user.jobTitle ?? ""}`.toLowerCase().includes(needle)) return false;
    if (statusFilter === "active") return activeMap[user.id];
    if (statusFilter === "blocked") return !activeMap[user.id];
    if (statusFilter === "locked") return lockedMap[user.id];
    return true;
  });

  return (
    <div className="flex flex-col gap-4">
      {editingUser && (
        <EditUserForm
          key={editingUser.id}
          user={editingUser}
          territories={territories}
          departments={departments}
          onClose={() => setEditing(null)}
          allowedRoles={allowedRoles}
        />
      )}

      <div className="flex flex-wrap items-end gap-3">
        <div className="min-w-56 flex-1">
          <label htmlFor="user-search" className="label-caps mb-1.5 block">
            Tìm tài khoản
          </label>
          <input
            id="user-search"
            type="search"
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            className="input"
            placeholder="Tên, email, chức vụ…"
          />
        </div>
        <div>
          <label htmlFor="user-status" className="label-caps mb-1.5 block">
            Trạng thái
          </label>
          <select
            id="user-status"
            value={statusFilter}
            onChange={(event) => setStatusFilter(event.target.value as typeof statusFilter)}
            className="input"
          >
            <option value="">Tất cả</option>
            <option value="active">Đang hoạt động</option>
            <option value="blocked">Đã khoá</option>
            <option value="locked">Tạm khoá đăng nhập</option>
          </select>
        </div>
        <span className="pb-2 text-xs text-ink-400">
          {visibleUsers.length}/{users.length} tài khoản
        </span>
      </div>

      <div className="card overflow-x-auto">
        <table className="data-table">
          <thead>
            <tr>
              <th>Họ tên</th>
              <th>Email</th>
              <th>Chức vụ</th>
              <th>Vai trò</th>
              <th>Phòng ban</th>
              <th>Khu vực</th>
              <th>Trạng thái</th>
              <th>Đăng nhập gần nhất</th>
              <th title="Tải văn bản công ty và đăng thông báo toàn công ty">Văn bản &amp; TB công ty</th>
              <th title="Đăng thông báo trong phòng ban / khu vực của mình (Trợ lý...)">Đăng TB phòng/KV</th>
              <th>Sửa TT nhân viên</th>
              <th />
            </tr>
          </thead>
          <tbody>
            {visibleUsers.map((user) => {
              const isActive = activeMap[user.id];
              const territoryLabel =
                user.role === "MANAGER" || user.role === "GDKV"
                  ? user.managedTerritoryIds.map((id) => territoryNames[id]).filter(Boolean).join(" · ")
                  : (user.territoryId && territoryNames[user.territoryId]) || "";

              return (
                <tr key={user.id}>
                  <td className="font-medium text-ink-700">
                    <Link href={`/danh-muc/nguoi-dung/${user.id}`} className="hover:text-brand-600">
                      {user.fullName}
                    </Link>
                    {user.id === currentUserId && (
                      <span className="ml-2 text-[11px] text-ink-400">(bạn)</span>
                    )}
                  </td>
                  <td className="text-ink-500">{user.email}</td>
                  <td className="text-ink-500">{user.jobTitle || "—"}</td>
                  <td className="text-ink-500">{ROLE_LABEL[user.role]}</td>
                  <td className="text-ink-500">
                    {user.departmentId ? (departmentNames[user.departmentId] ?? "—") : "—"}
                  </td>
                  <td className="text-ink-500">
                    {user.role === "DIRECTOR" ? "Toàn công ty" : territoryLabel || "—"}
                  </td>
                  <td>
                    <span
                      className={`inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-semibold ${
                        isActive ? "bg-emerald-50 text-emerald-700" : "bg-red-50 text-red-700"
                      }`}
                    >
                      {isActive ? "Đang hoạt động" : "Đã khoá"}
                    </span>
                    {lockedMap[user.id] && (
                      <div className="mt-1.5 flex flex-col items-start gap-1">
                        <span className="inline-flex items-center rounded-full bg-gold-100 px-2 py-0.5 text-[11px] font-semibold text-gold-500">
                          Tạm khoá đăng nhập
                        </span>
                        <ActionForm action={onUnlockLogin} success="Đã cho đăng nhập lại.">
                          <input type="hidden" name="id" value={user.id} />
                          <button type="submit" className="btn-ghost px-2 py-1 text-xs text-brand-600">
                            Cho đăng nhập lại
                          </button>
                        </ActionForm>
                      </div>
                    )}
                  </td>
                  <td className="tnum whitespace-nowrap text-xs text-ink-500">
                    {user.lastLoginAt ?? "Chưa đăng nhập"}
                  </td>
                  <td>
                    {user.role === "DIRECTOR" ? (
                      <span className="text-[11px] text-ink-400">Luôn có</span>
                    ) : (
                      !canUploadDocumentsMap[user.id] && !canGrantUploadDocuments ? (
                        <span className="text-[11px] text-ink-300" title="Bạn chỉ cấp được quyền mà chính bạn đang có">
                          Không thể cấp
                        </span>
                      ) : (
                      <ActionForm action={onToggleCanUploadDocuments} success="Đã cập nhật quyền tải văn bản.">
                        <input type="hidden" name="id" value={user.id} />
                        <button
                          type="submit"
                          className={`btn-ghost px-2 py-1 text-xs ${
                            canUploadDocumentsMap[user.id] ? "text-emerald-700" : "text-ink-400"
                          }`}
                        >
                          {canUploadDocumentsMap[user.id] ? "Đang được cấp" : "Cấp quyền"}
                        </button>
                      </ActionForm>
                      )
                    )}
                  </td>
                  <td>
                    {user.role === "DIRECTOR" || user.role === "GDKV" || user.role === "MANAGER" ? (
                      <span className="text-[11px] text-ink-400">Theo vai trò</span>
                    ) : !canPostAnnouncementsMap[user.id] && !canGrantPostAnnouncements ? (
                      <span className="text-[11px] text-ink-300">Không thể cấp</span>
                    ) : (
                      <ActionForm action={onToggleCanPostAnnouncements} success="Đã cập nhật quyền đăng thông báo.">
                        <input type="hidden" name="id" value={user.id} />
                        <button
                          type="submit"
                          className={`btn-ghost px-2 py-1 text-xs ${
                            canPostAnnouncementsMap[user.id] ? "text-emerald-700" : "text-ink-400"
                          }`}
                        >
                          {canPostAnnouncementsMap[user.id] ? "Đang được cấp" : "Cấp quyền"}
                        </button>
                      </ActionForm>
                    )}
                  </td>
                  <td>
                    {user.role === "DIRECTOR" ? (
                      <span className="text-[11px] text-ink-400">Luôn có</span>
                    ) : (
                      !canEditStaffInfoMap[user.id] && !canGrantEditStaffInfo ? (
                        <span className="text-[11px] text-ink-300" title="Bạn chỉ cấp được quyền mà chính bạn đang có">
                          Không thể cấp
                        </span>
                      ) : (
                      <ActionForm action={onToggleCanEditStaffInfo} success="Đã cập nhật quyền sửa thông tin nhân viên.">
                        <input type="hidden" name="id" value={user.id} />
                        <button
                          type="submit"
                          className={`btn-ghost px-2 py-1 text-xs ${
                            canEditStaffInfoMap[user.id] ? "text-emerald-700" : "text-ink-400"
                          }`}
                        >
                          {canEditStaffInfoMap[user.id] ? "Đang được cấp" : "Cấp quyền"}
                        </button>
                      </ActionForm>
                      )
                    )}
                  </td>
                  <td>
                    <div className="flex justify-end gap-2">
                      <button
                        type="button"
                        onClick={() => setEditing(user.id === editing ? null : user.id)}
                        className="btn-ghost px-2 py-1 text-xs"
                      >
                        Sửa
                      </button>
                      {deletableMap[user.id] && (
                        <ActionForm
                          action={onDelete}
                          success="Đã xoá tài khoản."
                          confirm="Xoá hẳn tài khoản này? Chỉ áp dụng cho tài khoản tạo nhầm — không thể hoàn tác."
                        >
                          <input type="hidden" name="id" value={user.id} />
                          <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
                            Xoá
                          </button>
                        </ActionForm>
                      )}
                      {user.id !== currentUserId && (
                        <ActionForm action={onToggleActive} success="Đã cập nhật trạng thái.">
                          <input type="hidden" name="id" value={user.id} />
                          <button
                            type="submit"
                            className={`btn-ghost px-2 py-1 text-xs ${isActive ? "text-red-600" : "text-emerald-700"}`}
                          >
                            {isActive ? "Khoá" : "Mở khoá"}
                          </button>
                        </ActionForm>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}
