"use client";

/**
 * Team-management API client (#2556, эпик #2549) — CRUD сотрудников, квоты,
 * история. Mirrors `app/api/v1/team.py` + `app/schemas/team.py` (tradein-mvp
 * backend, PR #2554/#2563). Hand-written types — tradein-mvp/frontend has no
 * `codegen` script (см. `src/lib/admin-audit-api.ts` для того же паттерна).
 *
 * Auth: team-роуты требуют session-cookie (`current_team_actor` в team.py —
 * читает ТОЛЬКО cookie, не legacy X-Authenticated-User). `apiFetch` не задаёт
 * `credentials` явно — запросы same-origin (basePath `/trade-in` за тем же
 * Caddy), браузер по умолчанию шлёт cookie на same-origin fetch.
 */

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { apiFetch, HTTPError } from "./api";

const BASE = "/api/v1/team";

// Тот же regex что и `app.schemas.team._USERNAME_RE` — клиентская валидация
// зеркалит серверную, чтобы показывать понятную подсказку ДО round-trip.
export const USERNAME_PATTERN = /^[A-Za-z0-9._-]{3,64}$/;
export const USERNAME_HINT =
  "Латиница, цифры, точка, дефис, подчёркивание; 3–64 символа";

// ---- Types (mirror app/schemas/team.py) ------------------------------------

export interface QuotaStatus {
  limit: number;
  used: number;
  remaining: number;
  unlimited: boolean;
}

export interface Employee {
  id: number;
  username: string;
  display_name: string | null;
  org_name: string | null;
  email: string | null;
  is_active: boolean;
  manager_id: number | null;
  created_at: string;
  quota: QuotaStatus;
}

export interface EmployeeHistoryEntry {
  estimate_id: string | null;
  address: string | null;
  area_m2: string | null;
  rooms: string | null;
  median_price: number | null;
  confidence: string | null;
  n_analogs: number | null;
  created_at: string;
}

export interface CreateEmployeeInput {
  username: string;
  password: string;
  display_name?: string;
  org_name?: string;
  email?: string;
  monthly_limit?: number;
}

export interface UpdateEmployeeInput {
  is_active?: boolean;
  monthly_limit?: number;
  display_name?: string;
  org_name?: string;
  email?: string;
  new_password?: string;
}

// ---- Hooks -------------------------------------------------------------------

const EMPLOYEES_LIST_KEY = ["team", "employees"] as const;

/**
 * GET /api/v1/team/employees?limit=&offset=
 * Backend сам скоупит по роли (manager → только свои, admin → все).
 *
 * `enabled` (default true) — вызывающая страница обязана передать `false`
 * для ролей, которым эндпоинт всё равно ответит 401/403 (employee/analyst/
 * pilot и т.п.): без этого прямой заход на /team шлёт обречённый round-trip
 * ДО отрисовки role-gate, который лишний и палит наличие эндпоинта.
 */
export function useEmployees(limit: number, offset: number, enabled = true) {
  return useQuery<Employee[]>({
    queryKey: [...EMPLOYEES_LIST_KEY, limit, offset],
    queryFn: () =>
      apiFetch<Employee[]>(`${BASE}/employees?limit=${limit}&offset=${offset}`),
    enabled,
    staleTime: 15_000,
    retry: false,
  });
}

/**
 * GET /api/v1/team/employees/{id}/history?limit=&offset=
 * `enabled: false` пока employeeId === null — ленивая загрузка при открытии drawer.
 */
export function useEmployeeHistory(
  employeeId: number | null,
  limit = 50,
  offset = 0,
) {
  return useQuery<EmployeeHistoryEntry[]>({
    queryKey: ["team", "employees", employeeId, "history", limit, offset],
    queryFn: () =>
      apiFetch<EmployeeHistoryEntry[]>(
        `${BASE}/employees/${employeeId}/history?limit=${limit}&offset=${offset}`,
      ),
    enabled: employeeId !== null,
    staleTime: 15_000,
    retry: false,
  });
}

/** POST /api/v1/team/employees — создать сотрудника. */
export function useCreateEmployee() {
  const queryClient = useQueryClient();
  return useMutation<Employee, Error, CreateEmployeeInput>({
    mutationFn: (input) =>
      apiFetch<Employee>(`${BASE}/employees`, {
        method: "POST",
        body: JSON.stringify(input),
      }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: EMPLOYEES_LIST_KEY });
    },
  });
}

/**
 * PATCH /api/v1/team/employees/{id} — частичное обновление (блокировка,
 * квота, профиль, сброс пароля — любая комбинация полей в одном запросе,
 * зеркалит `EmployeeUpdateRequest`).
 */
export function useUpdateEmployee() {
  const queryClient = useQueryClient();
  return useMutation<
    Employee,
    Error,
    { employeeId: number; patch: UpdateEmployeeInput }
  >({
    mutationFn: ({ employeeId, patch }) =>
      apiFetch<Employee>(`${BASE}/employees/${employeeId}`, {
        method: "PATCH",
        body: JSON.stringify(patch),
      }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: EMPLOYEES_LIST_KEY });
    },
  });
}

// ---- Error mapping -----------------------------------------------------------

/**
 * Достаёт человеко-читаемый текст из FastAPI error body — либо `{detail:
 * string}` (наши ручные `HTTPException(...)`), либо Pydantic-валидация
 * `{detail: [{msg: string, ...}]}` (напр. username не прошёл field_validator
 * на этапе парсинга тела запроса, ДО хендлера).
 */
function extractDetailMessage(body: unknown): string | null {
  if (body === null || typeof body !== "object" || !("detail" in body)) {
    return null;
  }
  const detail = (body as { detail?: unknown }).detail;
  if (typeof detail === "string") return detail;
  if (Array.isArray(detail) && detail.length > 0) {
    const first: unknown = detail[0];
    if (first !== null && typeof first === "object" && "msg" in first) {
      const msg = (first as { msg?: unknown }).msg;
      if (typeof msg === "string") return msg;
    }
  }
  return null;
}

/** Русский текст ошибки для team-мутаций/запросов — по коду статуса. */
export function teamErrorMessage(error: unknown): string {
  if (error instanceof HTTPError) {
    if (error.status === 409) return "Логин уже занят";
    if (error.status === 403) return "Недостаточно прав";
    if (error.status === 404) return "Сотрудник не найден";
    if (error.status === 422) {
      return extractDetailMessage(error.body) ?? "Проверьте правильность заполнения формы";
    }
  }
  return "Не удалось выполнить запрос. Попробуйте ещё раз";
}
