import { queryOptions } from "@tanstack/react-query";
import { jsonQuery } from "../apiAdapter";

interface LocationRaw {
  users?: { first_name: string; last_name: string };
  user_name?: string;
  shift_date: string;
  arrival_time?: string | null;
  departure_time?: string | null;
  arrival_lat?: string | number | null;
  arrival_lng?: string | number | null;
  arrival_accuracy?: number | null;
  arrival_address?: string | null;
  departure_lat?: string | number | null;
  departure_lng?: string | number | null;
  departure_accuracy?: number | null;
  departure_address?: string | null;
}

export interface LocationRecord {
  user_name: string;
  shift_date: string;
  arrival_time?: string | null;
  departure_time?: string | null;
  arrival_lat?: string | number | null;
  arrival_lng?: string | number | null;
  arrival_accuracy?: number | null;
  arrival_address?: string | null;
  departure_lat?: string | number | null;
  departure_lng?: string | number | null;
  departure_accuracy?: number | null;
  departure_address?: string | null;
}

export interface ProjectLogEntry {
  id?: number;
  project_id?: number;
  project_name?: string;
  started_at?: string;
  ended_at?: string | null;
  hours?: string | number | null;
  minutes?: string | number | null;
}

export interface AttendanceRecord {
  id: number;
  shift_date: string;
  leave_type?: string;
  leave_hours?: number;
  arrival_time?: string | null;
  departure_time?: string | null;
  break_start?: string | null;
  break_end?: string | null;
  notes?: string;
  project_name?: string;
  project_logs?: ProjectLogEntry[];
}

export interface BalanceEntry {
  name: string;
  vacation_total: number;
  vacation_used: number;
  vacation_remaining: number;
  sick_used: number;
}

export interface UserShort {
  id: number | string;
  name: string;
}

export interface BalancesData {
  users: UserShort[];
  balances: Record<string, BalanceEntry>;
}

export interface FundUserData {
  name: string;
  worked: number;
  covered: number;
  overtime: number;
  missing: number;
}

export interface MonthFundData {
  month_name: string;
  fund: number;
  fund_to_date: number;
  business_days: number;
  users?: Record<string, FundUserData>;
}

export interface FundData {
  months: Record<string, MonthFundData>;
  holidays: unknown[];
  users: UserShort[];
  balances: Record<string, unknown>;
}

export interface ProjectUser {
  user_id: number;
  user_name: string;
  hours: number;
}

export interface ProjectEntry {
  project_id: number | null;
  project_number?: string;
  project_name?: string;
  hours: number;
  users: ProjectUser[];
}

export interface MonthProjectData {
  month_name: string;
  projects: ProjectEntry[];
}

export interface ProjectData {
  months: Record<string, MonthProjectData>;
}

export const attendanceHistoryOptions = (filters: {
  month?: string;
  userId?: number;
}) =>
  queryOptions({
    queryKey: ["attendance", "history", filters],
    queryFn: () => {
      const params = new URLSearchParams();
      params.set("limit", "1000");
      if (filters.month) params.set("month", filters.month);
      if (filters.userId) params.set("user_id", String(filters.userId));
      return jsonQuery<AttendanceRecord[]>(
        `/api/admin/attendance?${params.toString()}`,
      );
    },
  });

export const attendanceBalancesOptions = (year: number) =>
  queryOptions({
    queryKey: ["attendance", "balances", year],
    queryFn: () =>
      jsonQuery<BalancesData>(
        `/api/admin/attendance?action=balances&year=${year}`,
      ),
  });

export const attendanceWorkFundOptions = (year: number) =>
  queryOptions({
    queryKey: ["attendance", "workfund", year],
    queryFn: () =>
      jsonQuery<FundData>(`/api/admin/attendance?action=workfund&year=${year}`),
  });

export const attendanceProjectReportOptions = (year: number) =>
  queryOptions({
    queryKey: ["attendance", "project-report", year],
    queryFn: () =>
      jsonQuery<ProjectData>(
        `/api/admin/attendance?action=project_report&year=${year}`,
      ),
  });

export const attendanceLocationOptions = (id: string | undefined) =>
  queryOptions({
    queryKey: ["attendance", "location", id],
    queryFn: async (): Promise<LocationRecord> => {
      // Route through jsonQuery so the response.ok / 401 / non-JSON cases are
      // normalized into the same errors as every other options helper, then
      // apply the location-specific shape transform on the unwrapped data.
      const data = await jsonQuery<LocationRaw | { record: LocationRaw }>(
        `/api/admin/attendance?action=location&id=${id}`,
      );
      const raw = (
        "record" in data && data.record ? data.record : data
      ) as LocationRaw;
      const userName = raw.users
        ? `${raw.users.first_name} ${raw.users.last_name}`.trim()
        : raw.user_name || "";
      const { users: _users, ...rest } = raw;
      return { ...rest, user_name: userName };
    },
    enabled: !!id,
  });
