/**
 * Fertilization Recommendation API
 * @see RECOMMENDATION_APIS.md
 */

import { apiClient } from "../client";
import type {
  RecommendationTaskInitResponse,
  RecommendationTaskStatusResponse,
} from "./recommendationTask";
import { normalizeRecommendationTaskStatus } from "./recommendationTask";

const PREFIX = "/api/fertilization-recommendation";

export interface FarmData {
  soilType: string;
  organicMatter: string;
  waterEC: string;
}

export interface GrowthStage {
  id: string;
  icon: string;
}

export interface CropOption {
  id: string;
  labelKey: string;
  icon: string;
}

export interface FertilizationConfigResponse {
  farmData: FarmData;
  growthStages: GrowthStage[];
  cropOptions: CropOption[];
}

export interface FertilizationPlan {
  npkRatio: string;
  amountPerHectare: string;
  applicationMethod: string;
  applicationInterval: string;
  reasoning: string;
}

export interface FertilizationRecommendPayload {
  crop_id?: string;
  growth_stage?: string;
  farm_data?: Partial<FarmData>;
  soilType?: string;
  organicMatter?: string;
  waterEC?: string;
}

export interface FertilizationRecommendationResult {
  plan: FertilizationPlan;
  status?: string;
}

export type FertilizationRecommendResponse =
  | FertilizationRecommendationResult
  | RecommendationTaskInitResponse;

interface ApiResponse<T> {
  status: string;
  data: T;
}

async function unwrap<T>(promise: Promise<ApiResponse<T>>): Promise<T> {
  const res = await promise;
  return res.data;
}

function normalizeTaskInitResponse(
  task: RecommendationTaskInitResponse,
): RecommendationTaskInitResponse {
  return {
    ...task,
    status: normalizeRecommendationTaskStatus(task.status),
  };
}

function normalizeRecommendationResult(
  result: FertilizationRecommendationResult,
): FertilizationRecommendationResult {
  return result.status
    ? {
        ...result,
        status: normalizeRecommendationTaskStatus(result.status),
      }
    : result;
}

export const fertilizationRecommendationService = {
  getConfig(): Promise<FertilizationConfigResponse> {
    return unwrap(
      apiClient.get<ApiResponse<FertilizationConfigResponse>>(
        `${PREFIX}/config/`,
      ),
    );
  },

  recommend(
    payload?: FertilizationRecommendPayload,
  ): Promise<FertilizationRecommendResponse> {
    return unwrap(
      apiClient.post<ApiResponse<FertilizationRecommendResponse>>(
        `${PREFIX}/recommend/`,
        payload ?? {},
      ),
    ).then((response) =>
      "task_id" in response
        ? normalizeTaskInitResponse(response)
        : normalizeRecommendationResult(response),
    );
  },

  getRecommendStatus(
    taskId: string,
  ): Promise<
    RecommendationTaskStatusResponse<FertilizationRecommendationResult>
  > {
    return unwrap(
      apiClient.get<
        ApiResponse<
          RecommendationTaskStatusResponse<FertilizationRecommendationResult>
        >
      >(`${PREFIX}/recommend/status/${taskId}/`),
    ).then((response) => ({
      ...response,
      status: normalizeRecommendationTaskStatus(response.status),
      result: response.result
        ? normalizeRecommendationResult(response.result)
        : undefined,
    }));
  },
};
