/**
 * Inline AI Validation Payload Builder
 *
 * Centralized utility for building payloads sent to the inline AI validation endpoints.
 * This ensures consistent payload structure across all validation triggers:
 * - Blur handler in ValidationTable
 * - Auto-validation on page load
 * - Copy-down validation
 * - Template application
 *
 * Note: IDs are not included as the AI model can't look them up - only names are useful.
 */

import type { RowData } from '../store/types';
import type { Field, SelectOption } from '../../../types';
import { useValidationStore } from '../store/validationStore';

/**
 * Helper to look up field option label from field definitions
 */
export function getFieldLabel(
  fields: Field<string>[],
  fieldKey: string,
  val: unknown
): string | undefined {
  const fieldDef = fields.find(f => f.key === fieldKey);
  if (fieldDef && fieldDef.fieldType.type === 'select' && 'options' in fieldDef.fieldType) {
    const option = fieldDef.fieldType.options?.find(o => o.value === String(val));
    return option?.label;
  }
  return undefined;
}

/**
 * Look up line name from the productLinesCache
 * Line options are loaded dynamically per-company and stored in a separate cache
 */
function getLineName(companyId: string | number, lineId: string | number): string | undefined {
  const { productLinesCache } = useValidationStore.getState();
  const lineOptions = productLinesCache.get(String(companyId)) as SelectOption[] | undefined;
  if (lineOptions) {
    const option = lineOptions.find(o => o.value === String(lineId));
    return option?.label;
  }
  return undefined;
}

/**
 * Look up subline name from the sublinesCache
 * Subline options are loaded dynamically per-line and stored in a separate cache
 */
function getSublineName(lineId: string | number, sublineId: string | number): string | undefined {
  const { sublinesCache } = useValidationStore.getState();
  const sublineOptions = sublinesCache.get(String(lineId)) as SelectOption[] | undefined;
  if (sublineOptions) {
    const option = sublineOptions.find(o => o.value === String(sublineId));
    return option?.label;
  }
  return undefined;
}

/**
 * Compute sibling product names for naming context.
 * Siblings are products with the same company + line (+ subline if set).
 */
export function computeSiblingNames(
  row: RowData,
  allRows: RowData[]
): string[] {
  const siblingNames: string[] = [];

  if (!row.company || !row.line) {
    return siblingNames;
  }

  const companyId = String(row.company);
  const lineId = String(row.line);
  const sublineId = row.subline ? String(row.subline) : null;

  for (const otherRow of allRows) {
    // Skip self
    if (otherRow.__index === row.__index) continue;

    // Must match company and line
    if (String(otherRow.company) !== companyId) continue;
    if (String(otherRow.line) !== lineId) continue;

    // If current product has subline, siblings must match subline too
    if (sublineId && String(otherRow.subline) !== sublineId) continue;

    // Add name if it exists
    if (otherRow.name && typeof otherRow.name === 'string' && otherRow.name.trim()) {
      siblingNames.push(otherRow.name);
    }
  }

  return siblingNames;
}

/**
 * Payload for name validation endpoint
 */
export interface NameValidationPayload {
  name: string;
  company_name?: string;
  company_id?: string;  // Needed by backend to load company-specific prompts (not sent to AI)
  line_name?: string;
  subline_name?: string;
  siblingNames?: string[];
  [key: string]: unknown;
}

/**
 * Payload for description validation endpoint
 */
export interface DescriptionValidationPayload {
  name: string;
  description: string;
  company_name?: string;
  company_id?: string;  // Needed by backend to load company-specific prompts (not sent to AI)
  categories?: string;
  [key: string]: unknown;
}

/**
 * Options for overriding row values when building payloads
 */
export interface PayloadOverrides {
  name?: string;
  description?: string;
  line?: string | number;  // Line ID override (for line change handler)
}

/**
 * Build payload for name validation API
 *
 * @param row - The row data
 * @param fields - Field definitions for label lookup
 * @param allRows - All rows for sibling computation
 * @param overrides - Optional value overrides (e.g., new name from blur handler, new line from line change)
 */
export function buildNameValidationPayload(
  row: RowData,
  fields: Field<string>[],
  allRows: RowData[],
  overrides?: PayloadOverrides
): NameValidationPayload {
  // Use override line for sibling computation if provided
  const effectiveRow = overrides?.line !== undefined
    ? { ...row, line: String(overrides.line) }
    : row;
  const siblingNames = computeSiblingNames(effectiveRow, allRows);

  // Determine line_name - use override if provided
  // Line options are stored in productLinesCache (keyed by company ID), not field options
  const lineValue = overrides?.line ?? row.line;
  const lineName = row.company && lineValue
    ? getLineName(row.company, lineValue)
    : undefined;

  // Subline options are stored in sublinesCache (keyed by line ID), not field options
  const sublineName = lineValue && row.subline
    ? getSublineName(lineValue, row.subline)
    : undefined;

  return {
    name: overrides?.name ?? String(row.name || ''),
    company_name: row.company ? getFieldLabel(fields, 'company', row.company) : undefined,
    company_id: row.company ? String(row.company) : undefined,  // For backend prompt loading
    line_name: lineName,
    subline_name: sublineName,
    siblingNames: siblingNames.length > 0 ? siblingNames : undefined,
  };
}

/**
 * Build payload for description validation API
 *
 * @param row - The row data
 * @param fields - Field definitions for label lookup
 * @param overrides - Optional value overrides (e.g., from blur handler)
 */
export function buildDescriptionValidationPayload(
  row: RowData,
  fields: Field<string>[],
  overrides?: PayloadOverrides
): DescriptionValidationPayload {
  const payload: DescriptionValidationPayload = {
    name: overrides?.name ?? String(row.name || ''),
    description: overrides?.description ?? String(row.description || ''),
    company_name: row.company ? getFieldLabel(fields, 'company', row.company) : undefined,
    company_id: row.company ? String(row.company) : undefined,  // For backend prompt loading
    categories: row.categories as string | undefined,
  };

  // Add AI supplemental context if present (from MatchColumnsStep "AI context only" columns)
  if (row.__aiSupplemental && typeof row.__aiSupplemental === 'object') {
    payload.additional_context = row.__aiSupplemental;
  }

  return payload;
}
