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

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

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

export interface FarmInfo {
  soilType: string;
  waterQuality: string;
  climateZone: string;
}

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

export interface IrrigationConfigResponse {
  farmInfo: FarmInfo;
  cropOptions: CropOption[];
}

export interface IrrigationPlan {
  frequencyPerWeek: number | string;
  durationMinutes: number | string;
  bestTimeOfDay: string;
  moistureLevel: number | string;
  warning?: string;
}

export interface IrrigationRecommendPayload {
  crop_id?: string;
  farm_data?: Partial<FarmInfo>;
  soilType?: string;
  waterQuality?: string;
  climateZone?: string;
}

export interface WaterBalanceDailyEntry {
  forecast_date: string;
  et0_mm: number;
  etc_mm: number;
  effective_rainfall_mm: number;
  gross_irrigation_mm: number;
  irrigation_timing: string;
}

export interface WaterBalanceCropProfile {
  kc_initial: number;
  kc_mid: number;
  kc_end: number;
}

export interface WaterBalance {
  daily: WaterBalanceDailyEntry[];
  crop_profile?: WaterBalanceCropProfile;
  active_kc?: number;
}

export interface IrrigationRecommendationResult {
  plan: IrrigationPlan;
  raw_response?: string;
  water_balance?: WaterBalance;
  status?: string;
}

export type IrrigationRecommendResponse =
  | IrrigationRecommendationResult
  | 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: IrrigationRecommendationResult,
): IrrigationRecommendationResult {
  return result.status
    ? {
        ...result,
        status: normalizeRecommendationTaskStatus(result.status),
      }
    : result;
}

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

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

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