"use client";

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

import { apiFetch } from "@/lib/api";

// ── Types ─────────────────────────────────────────────────────────────────────
// Manually typed to match backend Pydantic schemas (sub-PR 3).
// After PR #138 merges run `npm run codegen` to sync with generated openapi types.

export interface WeightProfile {
  id: number;
  user_id: string;
  profile_name: string;
  weights: Record<string, number>;
  is_default: boolean;
  description: string | null;
  created_at: string;
  updated_at: string;
}

export interface WeightProfileCreate {
  user_id: string;
  profile_name: string;
  weights: Record<string, number>;
  is_default?: boolean;
  description?: string | null;
}

export interface WeightProfileUpdate {
  profile_name?: string;
  weights?: Record<string, number>;
  is_default?: boolean;
  description?: string | null;
}

// ── Constants ─────────────────────────────────────────────────────────────────
// ALLOWED_CATEGORIES — mirrors backend weight_profiles.py ALLOWED_CATEGORIES.
// Keep in sync with backend; source of truth is `_POI_WEIGHTS` in parcels.py.

export const POI_CATEGORIES = [
  "school",
  "kindergarten",
  "pharmacy",
  "hospital",
  "shop_mall",
  "shop_supermarket",
  "shop_small",
  "park",
  "bus_stop",
  "metro_stop",
  "tram_stop",
] as const;

export type PoiCategoryKey = (typeof POI_CATEGORIES)[number];

// System defaults — mirrors _POI_WEIGHTS in backend/app/api/v1/parcels.py.
export const POI_DEFAULT_WEIGHTS: Record<PoiCategoryKey, number> = {
  school: 1.5,
  kindergarten: 1.5,
  pharmacy: 0.8,
  hospital: 0.6,
  shop_mall: 1.2,
  shop_supermarket: 1.0,
  shop_small: 0.5,
  park: 1.8,
  bus_stop: 0.3,
  metro_stop: 1.5,
  tram_stop: -0.5,
};

export const POI_LABELS: Record<PoiCategoryKey, string> = {
  school: "Школы",
  kindergarten: "Детсады",
  pharmacy: "Аптеки",
  hospital: "Больницы",
  shop_mall: "ТРЦ / Молы",
  shop_supermarket: "Супермаркеты",
  shop_small: "Магазины у дома",
  park: "Парки",
  bus_stop: "Автобусные ост.",
  metro_stop: "Метро",
  tram_stop: "Трамвайные ост. (−)",
};

// Weight range bounds — mirrors MIN_WEIGHT / MAX_WEIGHT in backend.
export const POI_WEIGHT_MIN = -2;
export const POI_WEIGHT_MAX = 3;

// ── Helpers ───────────────────────────────────────────────────────────────────

const BASE_PATH = "/api/v1/admin/site-finder/weight-profiles";

function profilesHeaders(adminToken: string): HeadersInit {
  return { "X-Admin-Token": adminToken };
}

// ── Hooks ─────────────────────────────────────────────────────────────────────

/** List all weight profiles for a given user_id. */
export function useWeightProfiles(userId: string, adminToken: string) {
  return useQuery<WeightProfile[]>({
    queryKey: ["weight-profiles", userId],
    queryFn: () =>
      apiFetch<WeightProfile[]>(
        `${BASE_PATH}?user_id=${encodeURIComponent(userId)}`,
        {
          headers: profilesHeaders(adminToken),
        },
      ),
    enabled: !!userId && !!adminToken,
  });
}

/** Create a new weight profile. Invalidates the list query on success. */
export function useCreateProfile(adminToken: string) {
  const qc = useQueryClient();
  return useMutation<WeightProfile, Error, WeightProfileCreate>({
    mutationFn: (payload) =>
      apiFetch<WeightProfile>(BASE_PATH, {
        method: "POST",
        headers: profilesHeaders(adminToken),
        body: JSON.stringify(payload),
      }),
    onSuccess: (_, variables) => {
      void qc.invalidateQueries({
        queryKey: ["weight-profiles", variables.user_id],
      });
    },
  });
}

/** Update an existing weight profile by id. */
export function useUpdateProfile(
  userId: string,
  profileId: number,
  adminToken: string,
) {
  const qc = useQueryClient();
  return useMutation<WeightProfile, Error, WeightProfileUpdate>({
    mutationFn: (payload) =>
      apiFetch<WeightProfile>(
        `${BASE_PATH}/${profileId}?user_id=${encodeURIComponent(userId)}`,
        {
          method: "PUT",
          headers: profilesHeaders(adminToken),
          body: JSON.stringify(payload),
        },
      ),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ["weight-profiles", userId] });
    },
  });
}

/** Delete a weight profile by id. Resolves on success (backend returns 204 No Content). */
export function useDeleteProfile(userId: string, adminToken: string) {
  const qc = useQueryClient();
  return useMutation<void, Error, number>({
    mutationFn: (profileId) =>
      apiFetch<void>(
        `${BASE_PATH}/${profileId}?user_id=${encodeURIComponent(userId)}`,
        {
          method: "DELETE",
          headers: profilesHeaders(adminToken),
        },
      ),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ["weight-profiles", userId] });
    },
  });
}
