import { toBrapiIsoDateTime } from "@/lib/brapiIso";
import {
  createCachedLoader,
  loadDropdownBundle,
} from "@/services/dropdownCache";
import { getAuthToken } from "@/utils/token";
import {
  normalizePlateRow,
  type StudyContextOption,
  type TrialContextOption,
  validatePlateCoreContext,
  validatePlateWell,
} from "./plateUtils";
import {
  resolveSampleWell,
  validateSamplePayload,
  type ObservationUnitContextOption,
} from "./sampleUtils";
import {
  NONE_SELECT_VALUE,
  type PlateQuery,
  type PlateRecord,
  type SampleQuery,
  type SampleRecord,
  type SelectOption,
} from "./types";

interface BrapiPagination {
  currentPage: number;
  pageSize: number;
  totalCount: number;
  totalPages: number;
}

interface BrapiListResponse<T> {
  metadata: {
    pagination: BrapiPagination;
    status: Array<Record<string, unknown>>;
    datafiles: Array<Record<string, unknown>>;
  };
  result: {
    data: T[];
  };
}

interface BrapiSingleResponse<T> {
  metadata: {
    pagination: BrapiPagination;
    status: Array<Record<string, unknown>>;
    datafiles: Array<Record<string, unknown>>;
  };
  result: T;
}

interface StudyResponse {
  studyDbId: string;
  studyName: string | null;
  trialDbId: string | null;
  programDbId: string | null;
}

interface TrialResponse {
  trialDbId: string;
  trialName: string | null;
  programDbId: string | null;
}

type PlatePayload = Partial<Record<
  | "id"
  | "plate_name"
  | "plate_barcode"
  | "plate_format"
  | "sample_type"
  | "program_id"
  | "trial_id"
  | "study_id",
  unknown
>>;

type SamplePayload = Partial<Record<
  | "id"
  | "sample_name"
  | "sample_barcode"
  | "sample_pui"
  | "sample_group_db_id"
  | "sample_type"
  | "tissue_type"
  | "sample_description"
  | "sample_timestamp"
  | "taken_by"
  | "study_id"
  | "trial_id"
  | "program_id"
  | "germplasm_id"
  | "observation_unit_id"
  | "plate_id"
  | "row"
  | "column"
  | "well",
  unknown
>>;

interface ObservationUnitResponse {
  observationUnitDbId: string;
  observationUnitName: string | null;
  studyDbId: string | null;
}

interface CallSetListResponse {
  metadata: {
    pagination: BrapiPagination;
  };
  result: {
    data: Array<Record<string, unknown>>;
  };
}

export interface SamplePlateOptions {
  programs: SelectOption[];
  trials: TrialContextOption[];
  studies: StudyContextOption[];
  germplasm: SelectOption[];
  observationUnits: ObservationUnitContextOption[];
  plates: SelectOption[];
  people: SelectOption[];
}

const apiBase = () => {
  if (typeof window !== "undefined") return "";
  return process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000";
};

async function request<T>(path: string, init?: RequestInit): Promise<T> {
  const token = getAuthToken();
  const response = await fetch(`${apiBase()}${path}`, {
    ...init,
    headers: {
      "Content-Type": "application/json",
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      ...(init?.headers || {}),
    },
  });

  if (!response.ok) {
    const detail = await response.text();
    throw new Error(detail || `?????${response.status}`);
  }
  return response.json() as Promise<T>;
}

export const optionalText = (value: unknown) => {
  const normalized = String(value ?? "").trim();
  if (!normalized || normalized === NONE_SELECT_VALUE) return null;
  return normalized;
};

const requiredText = (value: unknown, message: string) => {
  const normalized = optionalText(value);
  if (!normalized) throw new Error(message);
  return normalized;
};

const optionalNumber = (value: unknown) => {
  const normalized = optionalText(value);
  if (normalized === null) return null;
  const parsed = Number(normalized);
  return Number.isNaN(parsed) ? null : parsed;
};

const trialContextLoader = createCachedLoader(async () => {
  const response = await request<BrapiListResponse<TrialResponse>>("/brapi/v2/trials?page=0&pageSize=10");
  return response.result.data.map((trial) => ({
    value: trial.trialDbId,
    label: trial.trialName || trial.trialDbId,
    programDbId: trial.programDbId ?? null,
  }));
});

const studyContextLoader = createCachedLoader(async () => {
  const response = await request<BrapiListResponse<StudyResponse>>("/brapi/v2/studies?page=0&pageSize=10");
  return response.result.data.map((study) => ({
    value: study.studyDbId,
    label: study.studyName || study.studyDbId,
    trialDbId: study.trialDbId ?? null,
    programDbId: study.programDbId ?? null,
  }));
});

const observationUnitContextLoader = createCachedLoader(async () => {
  const response = await request<BrapiListResponse<ObservationUnitResponse>>(
    "/brapi/v2/observationunits?page=0&pageSize=10",
  );
  return response.result.data.map((unit) => ({
    value: unit.observationUnitDbId,
    label: unit.observationUnitName || unit.observationUnitDbId,
    studyDbId: unit.studyDbId ?? null,
  }));
});

const plateRowsLoader = createCachedLoader(async () => {
  const response = await request<BrapiListResponse<PlateRecord>>("/brapi/v2/plates?page=0&pageSize=10");
  return response.result.data.map(mapPlate);
});

const sampleRowsAllLoader = createCachedLoader(async () => {
  const response = await request<BrapiListResponse<SampleRecord>>("/brapi/v2/samples?page=0&pageSize=10");
  return response.result.data.map(mapSample);
});

export function invalidatePlateRowsCache() {
  plateRowsLoader.invalidate();
}

export function invalidateSampleRowsCache() {
  sampleRowsAllLoader.invalidate();
}

function hasPlateServerFilter(query?: PlateQuery) {
  return Boolean(
    (query?.program_id && query.program_id !== NONE_SELECT_VALUE)
    || (query?.trial_id && query.trial_id !== NONE_SELECT_VALUE)
    || (query?.study_id && query.study_id !== NONE_SELECT_VALUE)
    || query?.plate_name,
  );
}

function hasSampleServerFilter(query?: SampleQuery, plateDbId?: string) {
  return Boolean(
    plateDbId
    || query?.sample_name
    || (query?.program_id && query.program_id !== NONE_SELECT_VALUE)
    || (query?.trial_id && query.trial_id !== NONE_SELECT_VALUE)
    || (query?.study_id && query.study_id !== NONE_SELECT_VALUE)
    || (query?.plate_id && query.plate_id !== NONE_SELECT_VALUE)
    || (query?.observation_unit_id && query.observation_unit_id !== NONE_SELECT_VALUE),
  );
}

async function loadRawPlates(query?: PlateQuery, force = false): Promise<PlateRecord[]> {
  if (hasPlateServerFilter(query)) {
    const params = new URLSearchParams({ page: "0", pageSize: "10" });
    if (query?.program_id && query.program_id !== NONE_SELECT_VALUE) params.set("programDbId", query.program_id);
    if (query?.trial_id && query.trial_id !== NONE_SELECT_VALUE) params.set("trialDbId", query.trial_id);
    if (query?.study_id && query.study_id !== NONE_SELECT_VALUE) params.set("studyDbId", query.study_id);
    if (query?.plate_name) params.set("plateName", query.plate_name);
    const response = await request<BrapiListResponse<PlateRecord>>(`/brapi/v2/plates?${params.toString()}`);
    return response.result.data.map(mapPlate);
  }
  return plateRowsLoader.load(force);
}

async function loadRawSamples(query?: SampleQuery, plateDbId?: string, force = false): Promise<SampleRecord[]> {
  if (hasSampleServerFilter(query, plateDbId)) {
    const params = new URLSearchParams({ page: "0", pageSize: "10" });
    const effectivePlateId = plateDbId || optionalText(query?.plate_id);
    if (effectivePlateId) params.set("plateDbId", effectivePlateId);
    if (query?.sample_name) params.set("sampleName", query.sample_name);
    if (query?.study_id && query.study_id !== NONE_SELECT_VALUE) params.set("studyDbId", query.study_id);
    if (query?.trial_id && query.trial_id !== NONE_SELECT_VALUE) params.set("trialDbId", query.trial_id);
    if (query?.program_id && query.program_id !== NONE_SELECT_VALUE) params.set("programDbId", query.program_id);
    if (query?.observation_unit_id && query.observation_unit_id !== NONE_SELECT_VALUE) {
      params.set("observationUnitDbId", query.observation_unit_id);
    }
    const response = await request<BrapiListResponse<SampleRecord>>(`/brapi/v2/samples?${params.toString()}`);
    return response.result.data.map(mapSample);
  }
  return sampleRowsAllLoader.load(force);
}

export const mapPlate = (plate: PlateRecord): PlateRecord => ({
  ...plate,
  id: plate.plateDbId || plate.id,
  plate_name: plate.plate_name || plate.plateName || null,
  plate_barcode: plate.plate_barcode || plate.plateBarcode || null,
  plate_format: plate.plate_format || plate.plateFormat || null,
  sample_type: plate.sample_type || plate.sampleType || null,
  program_id: plate.program_id || plate.programDbId || null,
  trial_id: plate.trial_id || plate.trialDbId || null,
  study_id: plate.study_id || plate.studyDbId || null,
});

export const mapSample = (sample: SampleRecord): SampleRecord => ({
  ...sample,
  id: sample.sampleDbId || sample.id,
  sample_name: sample.sample_name || sample.sampleName || null,
  sample_barcode: sample.sample_barcode || sample.sampleBarcode || null,
  sample_pui: sample.sample_pui || sample.samplePUI || null,
  sample_group_db_id: sample.sample_group_db_id || sample.sampleGroupDbId || null,
  sample_type: sample.sample_type || sample.sampleType || null,
  tissue_type: sample.tissue_type || sample.tissueType || null,
  sample_description: sample.sample_description || sample.sampleDescription || null,
  sample_timestamp: sample.sample_timestamp || sample.sampleTimestamp || null,
  taken_by: sample.taken_by || sample.takenBy || null,
  study_id: sample.study_id || sample.studyDbId || null,
  trial_id: sample.trial_id || sample.trialDbId || null,
  program_id: sample.program_id || sample.programDbId || null,
  germplasm_id: sample.germplasm_id || sample.germplasmDbId || null,
  observation_unit_id: sample.observation_unit_id || sample.observationUnitDbId || null,
  plate_id: sample.plate_id || sample.plateDbId || null,
  plate_name: sample.plate_name || sample.plateName || null,
});

function enrichSampleRows(
  samples: SampleRecord[],
  options: Pick<SamplePlateOptions, "programs" | "trials" | "studies" | "plates">,
): SampleRecord[] {
  const programLabel = new Map(options.programs.map((item) => [item.value, item.label]));
  const trialLabel = new Map(options.trials.map((item) => [item.value, item.label]));
  const studyLabel = new Map(options.studies.map((item) => [item.value, item.label]));
  const plateLabel = new Map(options.plates.map((item) => [item.value, item.label]));

  return samples.map((sample) => ({
    ...sample,
    program_name: sample.program_id ? programLabel.get(sample.program_id) ?? sample.program_id : null,
    trial_name: sample.trial_id ? trialLabel.get(sample.trial_id) ?? sample.trial_id : null,
    study_name: sample.study_id ? studyLabel.get(sample.study_id) ?? sample.study_id : null,
    plate_name: sample.plate_id ? plateLabel.get(sample.plate_id) ?? sample.plate_name ?? sample.plate_id : sample.plate_name ?? null,
  }));
}

function filterSamples(samples: SampleRecord[], query: SampleQuery) {
  const sampleName = optionalText(query.sample_name)?.toLowerCase();
  const barcode = optionalText(query.sample_barcode)?.toLowerCase();
  const programId = optionalText(query.program_id);
  const trialId = optionalText(query.trial_id);
  const studyId = optionalText(query.study_id);
  const plateId = optionalText(query.plate_id);
  const observationUnitId = optionalText(query.observation_unit_id);

  return samples.filter((sample) => {
    if (programId && sample.program_id !== programId) return false;
    if (trialId && sample.trial_id !== trialId) return false;
    if (studyId && sample.study_id !== studyId) return false;
    if (plateId && sample.plate_id !== plateId) return false;
    if (observationUnitId && sample.observation_unit_id !== observationUnitId) return false;
    if (sampleName && !String(sample.sample_name ?? "").toLowerCase().includes(sampleName)) return false;
    if (barcode && !String(sample.sample_barcode ?? "").toLowerCase().includes(barcode)) return false;
    return true;
  });
}

function enrichPlateRows(
  plates: PlateRecord[],
  options: Pick<SamplePlateOptions, "programs" | "trials" | "studies">,
  samples: SampleRecord[],
): PlateRecord[] {
  const programLabel = new Map(options.programs.map((item) => [item.value, item.label]));
  const trialLabel = new Map(options.trials.map((item) => [item.value, item.label]));
  const studyLabel = new Map(options.studies.map((item) => [item.value, item.label]));
  const sampleCount = samples.reduce<Map<string, number>>((acc, sample) => {
    const plateId = sample.plate_id;
    if (!plateId) return acc;
    acc.set(plateId, (acc.get(plateId) ?? 0) + 1);
    return acc;
  }, new Map());

  return plates.map((plate) => ({
    ...plate,
    program_name: plate.program_id ? programLabel.get(plate.program_id) ?? plate.program_id : null,
    trial_name: plate.trial_id ? trialLabel.get(plate.trial_id) ?? plate.trial_id : null,
    study_name: plate.study_id ? studyLabel.get(plate.study_id) ?? plate.study_id : null,
    sample_count: sampleCount.get(plate.id) ?? 0,
  }));
}

function filterPlates(plates: PlateRecord[], query: PlateQuery) {
  const plateName = optionalText(query.plate_name)?.toLowerCase();
  const barcode = optionalText(query.plate_barcode)?.toLowerCase();
  const programId = optionalText(query.program_id);
  const trialId = optionalText(query.trial_id);
  const studyId = optionalText(query.study_id);

  return plates.filter((plate) => {
    if (programId && plate.program_id !== programId) return false;
    if (trialId && plate.trial_id !== trialId) return false;
    if (studyId && plate.study_id !== studyId) return false;
    if (plateName && !String(plate.plate_name ?? "").toLowerCase().includes(plateName)) return false;
    if (barcode && !String(plate.plate_barcode ?? "").toLowerCase().includes(barcode)) return false;
    return true;
  });
}

const plateBody = (payload: PlatePayload) => {
  const body: Record<string, unknown> = {
    plateName: requiredText(payload.plate_name, "????????"),
  };
  const plateBarcode = optionalText(payload.plate_barcode);
  const plateFormat = optionalText(payload.plate_format);
  const sampleType = optionalText(payload.sample_type);
  const programDbId = optionalText(payload.program_id);
  const trialDbId = optionalText(payload.trial_id);
  const studyDbId = optionalText(payload.study_id);

  if (plateBarcode) body.plateBarcode = plateBarcode;
  if (plateFormat) body.plateFormat = plateFormat;
  if (sampleType) body.sampleType = sampleType;
  if (programDbId) body.programDbId = programDbId;
  if (trialDbId) body.trialDbId = trialDbId;
  if (studyDbId) body.studyDbId = studyDbId;

  return body;
};

const sampleBody = (payload: SamplePayload, plateFormat?: string | null) => {
  const row = optionalText(payload.row);
  const column = optionalNumber(payload.column);
  const well = resolveSampleWell(row, column, optionalText(payload.well));

  validatePlateWell(plateFormat ?? null, row, column, well);

  const body: Record<string, unknown> = {
    sampleName: requiredText(payload.sample_name, "???????"),
  };

  const optionalFields: Array<[string, unknown]> = [
    ["sampleBarcode", optionalText(payload.sample_barcode)],
    ["samplePUI", optionalText(payload.sample_pui)],
    ["sampleGroupDbId", optionalText(payload.sample_group_db_id)],
    ["sampleType", optionalText(payload.sample_type)],
    ["tissueType", optionalText(payload.tissue_type)],
    ["sampleDescription", optionalText(payload.sample_description)],
    ["sampleTimestamp", toBrapiIsoDateTime(payload.sample_timestamp)],
    ["takenBy", optionalText(payload.taken_by)],
    ["studyDbId", optionalText(payload.study_id)],
    ["trialDbId", optionalText(payload.trial_id)],
    ["programDbId", optionalText(payload.program_id)],
    ["germplasmDbId", optionalText(payload.germplasm_id)],
    ["observationUnitDbId", optionalText(payload.observation_unit_id)],
    ["plateDbId", optionalText(payload.plate_id)],
    ["row", row ? normalizePlateRow(row) : null],
    ["column", column],
    ["well", well],
  ];

  optionalFields.forEach(([key, value]) => {
    if (value !== null && value !== undefined && value !== "") body[key] = value;
  });

  return body;
};

async function getContextOptions() {
  const [trials, studies, sharedOptions] = await Promise.all([
    trialContextLoader.load(),
    studyContextLoader.load(),
    loadDropdownBundle({ programs: true }),
  ]);
  return { trials, studies, programs: sharedOptions.programs };
}

async function validatePlatePayload(payload: PlatePayload) {
  const { trials, studies } = await getContextOptions();
  validatePlateCoreContext(payload, trials, studies);
}

export async function loadSamplePlatePageData(params: {
  plateQuery?: PlateQuery;
  sampleQuery?: SampleQuery;
  force?: boolean;
} = {}): Promise<{
  options: SamplePlateOptions;
  plates: PlateRecord[];
  samples: SampleRecord[];
}> {
  const force = params.force ?? false;
  const options = await fetchSamplePlateOptions(force);
  const [rawPlates, allSamples] = await Promise.all([
    loadRawPlates(params.plateQuery, force),
    sampleRowsAllLoader.load(force),
  ]);

  let tableSamples = allSamples;
  if (hasSampleServerFilter(params.sampleQuery)) {
    tableSamples = await loadRawSamples(params.sampleQuery, undefined, force);
  }

  const filteredPlates = filterPlates(rawPlates, params.plateQuery ?? {});
  const plates = enrichPlateRows(filteredPlates, options, allSamples);
  const samples = enrichSampleRows(filterSamples(tableSamples, params.sampleQuery ?? {}), options);

  return { options, plates, samples };
}

export async function fetchPlateRows(query?: PlateQuery, force = false): Promise<PlateRecord[]> {
  const { plates } = await loadSamplePlatePageData({ plateQuery: query, force });
  return plates;
}

export async function fetchPlateDetail(id: string): Promise<PlateRecord> {
  const response = await request<BrapiSingleResponse<PlateRecord>>(
    `/brapi/v2/plates/${encodeURIComponent(id)}`,
  );
  const [options, allSamples] = await Promise.all([
    fetchSamplePlateOptions(),
    sampleRowsAllLoader.load(),
  ]);
  return enrichPlateRows([mapPlate(response.result)], options, allSamples)[0];
}

async function getSampleValidationContext() {
  const [trials, studies, observationUnits, plates, existingSamples] = await Promise.all([
    trialContextLoader.load(),
    studyContextLoader.load(),
    observationUnitContextLoader.load(),
    plateRowsLoader.load(),
    sampleRowsAllLoader.load(),
  ]);
  return { trials, studies, observationUnits, plates, existingSamples };
}

function resolvePlateFormatFromContext(
  plateId: string | null,
  plates: PlateRecord[],
  explicitFormat?: string | null,
) {
  if (explicitFormat) return explicitFormat;
  if (!plateId) return null;
  return plates.find((plate) => plate.id === plateId)?.plate_format ?? null;
}

async function validateSamplePayloadRequest(
  payload: SamplePayload,
  options?: { plateFormat?: string | null; sampleDbId?: string | null },
) {
  const context = await getSampleValidationContext();
  const plateId = optionalText(payload.plate_id);
  validateSamplePayload(payload, {
    plateFormat: resolvePlateFormatFromContext(plateId, context.plates, options?.plateFormat),
    trials: context.trials,
    studies: context.studies,
    observationUnits: context.observationUnits,
    existingSamples: context.existingSamples,
    sampleDbId: options?.sampleDbId,
  });
}

export async function fetchSampleRows(
  query?: SampleQuery,
  plateDbId?: string,
  preloadedOptions?: SamplePlateOptions,
): Promise<SampleRecord[]> {
  const rawSamples = await loadRawSamples(query, plateDbId);
  const options = preloadedOptions ?? await fetchSamplePlateOptions();
  return enrichSampleRows(filterSamples(rawSamples, query ?? {}), options);
}

export async function fetchSampleDetail(id: string): Promise<SampleRecord> {
  const response = await request<BrapiSingleResponse<SampleRecord>>(
    `/brapi/v2/samples/${encodeURIComponent(id)}`,
  );
  const options = await fetchSamplePlateOptions();
  return enrichSampleRows([mapSample(response.result)], options)[0];
}

export async function countCallsetsBySample(sampleDbId: string): Promise<number> {
  const response = await request<CallSetListResponse>(
    `/brapi/v2/callsets?sampleDbId=${encodeURIComponent(sampleDbId)}&page=0&pageSize=1`,
  );
  return response.metadata.pagination.totalCount ?? 0;
}

export async function fetchSamplePlateOptions(force = false): Promise<SamplePlateOptions> {
  const [sharedOptions, trials, studies, plates, observationUnits] = await Promise.all([
    loadDropdownBundle({
      programs: true,
      germplasms: true,
      people: true,
    }, force),
    trialContextLoader.load(force),
    studyContextLoader.load(force),
    plateRowsLoader.load(force),
    observationUnitContextLoader.load(force),
  ]);

  const plateOptions = plates.map((plate) => ({
    value: plate.id,
    label: plate.plate_name || plate.id,
  }));

  return {
    programs: sharedOptions.programs,
    trials,
    studies,
    germplasm: sharedOptions.germplasms,
    observationUnits,
    plates: plateOptions,
    people: sharedOptions.people,
  };
}

export function normalizePlateFormData(record: PlateRecord): Record<string, unknown> {
  return {
    id: record.id,
    plate_name: record.plate_name ?? "",
    plate_barcode: record.plate_barcode ?? "",
    plate_format: record.plate_format && record.plate_format !== NONE_SELECT_VALUE ? record.plate_format : NONE_SELECT_VALUE,
    sample_type: record.sample_type && record.sample_type !== NONE_SELECT_VALUE ? record.sample_type : NONE_SELECT_VALUE,
    program_id: record.program_id && record.program_id !== NONE_SELECT_VALUE ? record.program_id : NONE_SELECT_VALUE,
    trial_id: record.trial_id && record.trial_id !== NONE_SELECT_VALUE ? record.trial_id : NONE_SELECT_VALUE,
    study_id: record.study_id && record.study_id !== NONE_SELECT_VALUE ? record.study_id : NONE_SELECT_VALUE,
  };
}

export async function createPlateRow(payload: PlatePayload): Promise<PlateRecord> {
  await validatePlatePayload(payload);
  const response = await request<BrapiListResponse<PlateRecord>>("/brapi/v2/plates", {
    method: "POST",
    body: JSON.stringify([plateBody(payload)]),
  });
  invalidatePlateRowsCache();
  return mapPlate(response.result.data[0]);
}

export async function updatePlateRow(id: string, payload: PlatePayload): Promise<PlateRecord> {
  await validatePlatePayload(payload);
  const response = await request<BrapiListResponse<PlateRecord>>("/brapi/v2/plates", {
    method: "PUT",
    body: JSON.stringify({ [id]: plateBody(payload) }),
  });
  invalidatePlateRowsCache();
  return mapPlate(response.result.data[0]);
}

export async function countSamplesByPlate(id: string): Promise<number> {
  const samples = await fetchSampleRows(undefined, id);
  return samples.length;
}

export async function createSampleRow(payload: SamplePayload, plateFormat?: string | null): Promise<SampleRecord> {
  await validateSamplePayloadRequest(payload, { plateFormat });
  const response = await request<BrapiListResponse<SampleRecord>>("/brapi/v2/samples", {
    method: "POST",
    body: JSON.stringify([sampleBody(payload, plateFormat)]),
  });
  invalidateSampleRowsCache();
  invalidatePlateRowsCache();
  return mapSample(response.result.data[0]);
}

export async function updateSampleRow(id: string, payload: SamplePayload, plateFormat?: string | null): Promise<SampleRecord> {
  await validateSamplePayloadRequest(payload, { plateFormat, sampleDbId: id });
  const response = await request<BrapiListResponse<SampleRecord>>("/brapi/v2/samples", {
    method: "PUT",
    body: JSON.stringify({ [id]: sampleBody(payload, plateFormat) }),
  });
  invalidateSampleRowsCache();
  invalidatePlateRowsCache();
  return mapSample(response.result.data[0]);
}

export function normalizeSampleFormData(record: SampleRecord): Record<string, unknown> {
  return {
    id: record.id,
    sample_name: record.sample_name ?? "",
    sample_barcode: record.sample_barcode ?? "",
    sample_pui: record.sample_pui ?? "",
    sample_group_db_id: record.sample_group_db_id ?? "",
    sample_type: record.sample_type && record.sample_type !== NONE_SELECT_VALUE ? record.sample_type : NONE_SELECT_VALUE,
    tissue_type: record.tissue_type && record.tissue_type !== NONE_SELECT_VALUE ? record.tissue_type : NONE_SELECT_VALUE,
    sample_description: record.sample_description ?? "",
    sample_timestamp: record.sample_timestamp ?? "",
    taken_by: record.taken_by && record.taken_by !== NONE_SELECT_VALUE ? record.taken_by : NONE_SELECT_VALUE,
    study_id: record.study_id && record.study_id !== NONE_SELECT_VALUE ? record.study_id : NONE_SELECT_VALUE,
    trial_id: record.trial_id && record.trial_id !== NONE_SELECT_VALUE ? record.trial_id : NONE_SELECT_VALUE,
    program_id: record.program_id && record.program_id !== NONE_SELECT_VALUE ? record.program_id : NONE_SELECT_VALUE,
    germplasm_id: record.germplasm_id && record.germplasm_id !== NONE_SELECT_VALUE ? record.germplasm_id : NONE_SELECT_VALUE,
    observation_unit_id: record.observation_unit_id && record.observation_unit_id !== NONE_SELECT_VALUE ? record.observation_unit_id : NONE_SELECT_VALUE,
    plate_id: record.plate_id && record.plate_id !== NONE_SELECT_VALUE ? record.plate_id : NONE_SELECT_VALUE,
    row: record.row ?? "",
    column: record.column ?? "",
    well: record.well ?? "",
  };
}

export async function deleteSampleRow(id: string): Promise<void> {
  const callsetCount = await countCallsetsBySample(id);
  if (callsetCount > 0) {
    throw new Error(`????? ${callsetCount} ? CallSet ????????????????????`);
  }
  throw new Error("BrAPI Samples ?????? DELETE???????????????");
}

export async function deletePlateRow(id: string): Promise<void> {
  const count = await countSamplesByPlate(id);
  if (count > 0) {
    throw new Error(`??????? ${count} ??????????????????BrAPI ???? DELETE /plates`);
  }
  throw new Error("BrAPI Plates ?????? DELETE???????????????");
}
