import { env } from '@/shared/config/env';
import { getAccessToken } from '@/shared/utils/token';
import type {
  AcademicTitleOption,
  ProfileVerificationStatus,
  StaffProfileDto,
  UnitOption,
} from '@/components/profile/types';
import type { Role } from '@/lib/permissions';

const FRONTEND_ROLES = new Set<Role>(['admin', 'editor', 'viewer']);

function parseFrontendRoles(raw: unknown): Role[] {
  if (!Array.isArray(raw)) return [];
  const out: Role[] = [];
  for (const x of raw) {
    if (typeof x === 'string' && FRONTEND_ROLES.has(x as Role)) {
      out.push(x as Role);
    }
  }
  return [...new Set(out)].sort();
}

export type RegisteredUserRow = {
  userId: string;
  email: string;
  fullName: string;
  phone: string | null;
  createdAt: string;
  employeeId: string | null;
  jobTitle: string | null;
  unitNameFreetext: string | null;
  unitCatalogName: string | null;
  academicTitleLabelVi: string | null;
  academicTitleOther: string | null;
  profileVerificationStatus: ProfileVerificationStatus;
  roles: Role[];
  adminFromPolicy: boolean;
  /** Reflects current server policy list — if true, UI must not allow clearing admin. */
  policyAdminLocked: boolean;
};

const API_URL = env.API_URL.replace(/\/$/, '');
const AUTH_BASE = `${API_URL}/api/v1/auth`;
const ADMIN_PROFILE_BASE = `${API_URL}/api/v1/admin/user-profiles`;

function parseFastApiError(body: unknown): string {
  if (!body || typeof body !== 'object') return 'Yêu cầu thất bại';
  const d = (body as { detail?: unknown }).detail;
  if (typeof d === 'string') return d;
  if (Array.isArray(d)) {
    return d
      .map((e) => (typeof e === 'object' && e && 'msg' in e ? String((e as { msg: string }).msg) : String(e)))
      .join(' ');
  }
  return 'Yêu cầu thất bại';
}

function authHeaders() {
  const token = getAccessToken();
  if (!token) return null;
  return {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  } as const;
}

export function mapStaffProfileDto(raw: Record<string, unknown> | undefined): StaffProfileDto | undefined {
  if (!raw || typeof raw !== 'object') return undefined;
  const r = raw as Record<string, unknown>;
  return {
    employeeId: (r.employeeId as string) ?? null,
    academicTitleCode: (r.academicTitleCode as string) ?? null,
    academicTitleOther: (r.academicTitleOther as string) ?? null,
    unitId: (r.unitId as string) ?? null,
    unitNameFreetext: (r.unitNameFreetext as string) ?? null,
    jobTitle: (r.jobTitle as string) ?? null,
    profileVerificationStatus: (r.profileVerificationStatus as ProfileVerificationStatus) ?? 'draft',
    verificationSubmittedAt: (r.verificationSubmittedAt as string) ?? null,
    verifiedAt: (r.verifiedAt as string) ?? null,
    verifiedByUserId: (r.verifiedByUserId as string) ?? null,
    rejectionReason: (r.rejectionReason as string) ?? null,
    version: Number(r.version ?? 1),
  };
}

export type PendingProfileRow = {
  userId: string;
  email: string;
  fullName: string;
  employeeId: string | null;
  jobTitle: string | null;
  verificationSubmittedAt: string | null;
  version: number;
};

export type AdminProfileDetail = {
  userId: string;
  email: string;
  fullName: string;
  phone: string | null;
  unitId: string | null;
  unitCatalogName: string | null;
  staffProfile: StaffProfileDto;
};

export const userProfileService = {
  async fetchAcademicTitles(): Promise<AcademicTitleOption[]> {
    const res = await fetch(`${AUTH_BASE}/reference/academic-titles`);
    if (!res.ok) return [];
    const data = (await res.json()) as AcademicTitleOption[];
    return Array.isArray(data) ? data : [];
  },

  async fetchUnits(): Promise<UnitOption[]> {
    const res = await fetch(`${AUTH_BASE}/reference/units`);
    if (!res.ok) return [];
    const data = (await res.json()) as UnitOption[];
    return Array.isArray(data) ? data : [];
  },

  async listPendingProfiles(): Promise<
    { success: true; items: PendingProfileRow[] } | { success: false; error: string }
  > {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/pending`, { headers: h });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    return { success: true, items: body as PendingProfileRow[] };
  },

  async listRegisteredUsers(): Promise<
    { success: true; items: RegisteredUserRow[] } | { success: false; error: string }
  > {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/registry`, { headers: h });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    const raw = body as Array<Record<string, unknown>>;
    if (!Array.isArray(raw)) return { success: false, error: 'Dữ liệu danh sách không hợp lệ.' };
    const items: RegisteredUserRow[] = raw.map((row) => ({
      userId: String(row.userId),
      email: String(row.email),
      fullName: String(row.fullName),
      phone: (row.phone as string) ?? null,
      createdAt: String(row.createdAt),
      employeeId: (row.employeeId as string) ?? null,
      jobTitle: (row.jobTitle as string) ?? null,
      unitNameFreetext: (row.unitNameFreetext as string) ?? null,
      unitCatalogName: (row.unitCatalogName as string) ?? null,
      academicTitleLabelVi: (row.academicTitleLabelVi as string) ?? null,
      academicTitleOther: (row.academicTitleOther as string) ?? null,
      profileVerificationStatus: (row.profileVerificationStatus as ProfileVerificationStatus) ?? 'draft',
      roles: parseFrontendRoles(row.roles),
      adminFromPolicy: Boolean(row.adminFromPolicy),
      policyAdminLocked: Boolean(row.policyAdminLocked),
    }));
    return { success: true, items };
  },

  async getAdminProfileDetail(
    userId: string,
  ): Promise<{ success: true; detail: AdminProfileDetail } | { success: false; error: string }> {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/${userId}`, { headers: h });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    const b = body as Record<string, unknown>;
    const staff = mapStaffProfileDto(b.staffProfile as Record<string, unknown> | undefined);
    if (!staff) return { success: false, error: 'Dữ liệu hồ sơ không hợp lệ.' };
    return {
      success: true,
      detail: {
        userId: String(b.userId),
        email: String(b.email),
        fullName: String(b.fullName),
        phone: (b.phone as string) ?? null,
        unitId: (b.unitId as string) ?? null,
        unitCatalogName: (b.unitCatalogName as string) ?? null,
        staffProfile: staff,
      },
    };
  },

  async verifyProfile(
    userId: string,
    expectedVersion: number,
  ): Promise<{ success: true } | { success: false; error: string }> {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/${userId}/verify`, {
      method: 'POST',
      headers: h,
      body: JSON.stringify({ expectedVersion }),
    });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    return { success: true };
  },

  async rejectProfile(
    userId: string,
    expectedVersion: number,
    reason: string,
  ): Promise<{ success: true } | { success: false; error: string }> {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/${userId}/reject`, {
      method: 'POST',
      headers: h,
      body: JSON.stringify({ expectedVersion, reason }),
    });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    return { success: true };
  },

  async removeUserAccount(
    userId: string,
    confirmEmail: string,
  ): Promise<{ success: true } | { success: false; error: string }> {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/${userId}/remove`, {
      method: 'POST',
      headers: h,
      body: JSON.stringify({ confirmEmail: confirmEmail.trim() }),
    });
    const body = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(body) };
    return { success: true };
  },

  async updateUserRoles(
    userId: string,
    body: { admin: boolean; editor: boolean; viewer: boolean },
  ): Promise<
    | { success: true; roles: Role[]; adminFromPolicy: boolean; policyAdminLocked: boolean }
    | { success: false; error: string }
  > {
    const h = authHeaders();
    if (!h) return { success: false, error: 'Chưa đăng nhập.' };
    const res = await fetch(`${ADMIN_PROFILE_BASE}/${userId}/roles`, {
      method: 'PATCH',
      headers: h,
      body: JSON.stringify({
        admin: body.admin,
        editor: body.editor,
        viewer: body.viewer,
      }),
    });
    const raw = await res.json().catch(() => ({}));
    if (!res.ok) return { success: false, error: parseFastApiError(raw) };
    const b = raw as Record<string, unknown>;
    return {
      success: true,
      roles: parseFrontendRoles(b.roles),
      adminFromPolicy: Boolean(b.adminFromPolicy),
      policyAdminLocked: Boolean(b.policyAdminLocked),
    };
  },
};
