// src/types/expiry.ts
// ============================================================================
// EXPIRY DATE TRACKING TYPE DEFINITIONS
// ============================================================================
// Type definitions for the expiry date tracking and inventory management feature.
// Covers pantry items, expiry ranges, alerts, and receipt scanning.
// ============================================================================

/**
 * Storage locations for pantry items.
 * Used to determine appropriate shelf life.
 */
export type StorageLocation = 'fridge' | 'freezer' | 'pantry' | 'room_temp';

/**
 * Sources for how an item was added to inventory.
 */
export type InventorySource = 'manual' | 'receipt_scan' | 'upc_scan';

/**
 * How the expiry date was determined.
 */
export type ExpirySource = 'manual' | 'calculated' | 'package' | 'receipt';

/**
 * Alert delivery methods for expiry notifications.
 */
export type AlertMethod = 'email' | 'push' | 'in_app';

/**
 * Types of expiry alerts.
 */
export type ExpiryAlertType = 'expiring_soon' | 'expired' | 'expiry_reminder';

/**
 * Expiry status for inventory items.
 */
export type ExpiryStatus = 'fresh' | 'expiring_soon' | 'expired' | 'unknown';

/**
 * Data sources for expiry range information.
 */
export type ExpiryRangeSource = 'usda' | 'fda' | 'manual' | 'community';

// ============================================================================
// PANTRY/INVENTORY ITEM TYPES
// ============================================================================

/**
 * User inventory item with all fields including calculated expiry status.
 * Extended version of pantry_items table with computed fields.
 */
export interface UserInventoryItem {
  /** Primary key */
  inventory_id: number;
  /** Owning user */
  user_id: string;
  /** Link to products table if from UPC scan */
  product_id: number | null;
  /** Link to master grocery items */
  master_item_id: number | null;
  /** Item name (required fallback) */
  item_name: string;
  /** Quantity of item */
  quantity: number;
  /** Unit of measurement */
  unit: string | null;
  /** When the item was purchased */
  purchase_date: string | null;
  /** Expected expiry date */
  expiry_date: string | null;
  /** How the item was added */
  source: InventorySource;
  /** Where the item is stored */
  location: StorageLocation | null;
  /** User notes */
  notes: string | null;
  /** Whether fully consumed */
  is_consumed: boolean;
  /** When consumed */
  consumed_at: string | null;
  /** How expiry was determined */
  expiry_source: ExpirySource | null;
  /** Link to receipt item if from receipt */
  receipt_item_id: number | null;
  /** Pantry location reference */
  pantry_location_id: number | null;
  /** When notification was sent */
  notification_sent_at: string | null;
  /** Record timestamps */
  created_at: string;
  updated_at: string;

  // Computed fields (not in database)
  /** Days until expiry (negative = already expired) */
  days_until_expiry: number | null;
  /** Current expiry status */
  expiry_status: ExpiryStatus;
  /** Item name from master items if linked */
  master_item_name?: string;
  /** Category name if linked */
  category_name?: string;
}

/**
 * Request to add an item to user inventory.
 */
export interface AddInventoryItemRequest {
  /** Link to products table */
  product_id?: number;
  /** Link to master grocery items */
  master_item_id?: number;
  /** Item name (required if no product/master item) */
  item_name: string;
  /** Quantity of item */
  quantity?: number;
  /** Unit of measurement */
  unit?: string;
  /** When the item was purchased */
  purchase_date?: string;
  /** Expected expiry date (if known) */
  expiry_date?: string;
  /** How the item is being added */
  source: InventorySource;
  /** Where the item will be stored */
  location?: StorageLocation;
  /** User notes */
  notes?: string;
}

/**
 * Request to update an existing inventory item.
 */
export interface UpdateInventoryItemRequest {
  /** Updated quantity */
  quantity?: number;
  /** Updated unit */
  unit?: string;
  /** Updated expiry date */
  expiry_date?: string;
  /** Updated storage location */
  location?: StorageLocation;
  /** Updated notes */
  notes?: string;
  /** Mark as consumed */
  is_consumed?: boolean;
}

// ============================================================================
// EXPIRY DATE RANGE TYPES
// ============================================================================

/**
 * Reference data for typical shelf life of items.
 * Maps to public.expiry_date_ranges table.
 */
export interface ExpiryDateRange {
  /** Primary key */
  expiry_range_id: number;
  /** Specific item this applies to */
  master_item_id: number | null;
  /** Category this applies to */
  category_id: number | null;
  /** Regex pattern for item name matching */
  item_pattern: string | null;
  /** Storage location this range applies to */
  storage_location: StorageLocation;
  /** Minimum shelf life in days */
  min_days: number;
  /** Maximum shelf life in days */
  max_days: number;
  /** Typical/recommended shelf life in days */
  typical_days: number;
  /** Storage tips or warnings */
  notes: string | null;
  /** Data source */
  source: ExpiryRangeSource | null;
  /** Record timestamps */
  created_at: string;
  updated_at: string;
}

/**
 * Request to add a new expiry date range (admin operation).
 */
export interface AddExpiryRangeRequest {
  /** Specific item this applies to */
  master_item_id?: number;
  /** Category this applies to */
  category_id?: number;
  /** Regex pattern for item name matching */
  item_pattern?: string;
  /** Storage location this range applies to */
  storage_location: StorageLocation;
  /** Minimum shelf life in days */
  min_days: number;
  /** Maximum shelf life in days */
  max_days: number;
  /** Typical/recommended shelf life in days */
  typical_days: number;
  /** Storage tips or warnings */
  notes?: string;
  /** Data source */
  source?: ExpiryRangeSource;
}

// ============================================================================
// ALERT TYPES
// ============================================================================

/**
 * User's expiry alert settings.
 * Maps to public.expiry_alerts table.
 */
export interface ExpiryAlertSettings {
  /** Primary key */
  expiry_alert_id: number;
  /** User ID */
  user_id: string;
  /** Days before expiry to send alert */
  days_before_expiry: number;
  /** How to deliver the alert */
  alert_method: AlertMethod;
  /** Whether this alert type is enabled */
  is_enabled: boolean;
  /** Last time an alert was sent */
  last_alert_sent_at: string | null;
  /** Record timestamps */
  created_at: string;
  updated_at: string;
}

/**
 * Request to update expiry alert settings.
 */
export interface UpdateExpiryAlertSettingsRequest {
  /** Days before expiry to send alert */
  days_before_expiry?: number;
  /** Whether this alert type is enabled */
  is_enabled?: boolean;
}

/**
 * Record of a sent expiry alert.
 * Maps to public.expiry_alert_log table.
 */
export interface ExpiryAlertLogRecord {
  /** Primary key */
  alert_log_id: number;
  /** User who received the alert */
  user_id: string;
  /** Pantry item that triggered the alert */
  pantry_item_id: number | null;
  /** Type of alert sent */
  alert_type: ExpiryAlertType;
  /** How the alert was delivered */
  alert_method: AlertMethod;
  /** Item name at time of alert */
  item_name: string;
  /** Expiry date that triggered alert */
  expiry_date: string | null;
  /** Days until expiry when alert was sent */
  days_until_expiry: number | null;
  /** When the alert was sent */
  sent_at: string;
}

// ============================================================================
// RESPONSE TYPES
// ============================================================================

/**
 * Grouped response for expiring items by urgency.
 */
export interface ExpiringItemsResponse {
  /** Items expiring today */
  expiring_today: UserInventoryItem[];
  /** Items expiring within 7 days */
  expiring_this_week: UserInventoryItem[];
  /** Items expiring within 30 days */
  expiring_this_month: UserInventoryItem[];
  /** Items already expired */
  already_expired: UserInventoryItem[];
  /** Summary counts */
  counts: {
    today: number;
    this_week: number;
    this_month: number;
    expired: number;
    total: number;
  };
}

/**
 * Recipe that can be made with expiring ingredients.
 */
export interface RecipeWithExpiringIngredients {
  /** Recipe ID */
  recipe_id: number;
  /** Recipe name */
  recipe_name: string;
  /** Recipe image URL */
  photo_url: string | null;
  /** Prep time in minutes */
  prep_time_minutes: number | null;
  /** Cook time in minutes */
  cook_time_minutes: number | null;
  /** Number of servings */
  servings: number | null;
  /** Average rating */
  avg_rating: number;
  /** Expiring items that match recipe ingredients */
  matching_expiring_items: UserInventoryItem[];
  /** Number of matching ingredients */
  matching_count: number;
  /** Total recipe ingredients */
  total_ingredients: number;
  /** Percentage of ingredients matched by expiring items */
  match_percentage: number;
}

/**
 * Recipe suggestions based on expiring items.
 */
export interface ExpiryRecipeSuggestionsResponse {
  /** Recipes that use expiring items */
  recipes: RecipeWithExpiringIngredients[];
  /** Total count for pagination */
  total: number;
  /** Items that were considered for matching */
  considered_items: UserInventoryItem[];
}

// ============================================================================
// RECEIPT SCANNING TYPES
// ============================================================================

/**
 * Receipt processing status.
 */
export type ReceiptStatus = 'pending' | 'processing' | 'completed' | 'failed';

/**
 * Receipt item matching status.
 */
export type ReceiptItemStatus = 'unmatched' | 'matched' | 'needs_review' | 'ignored';

/**
 * Receipt processing step for logging.
 */
export type ReceiptProcessingStep =
  | 'upload'
  | 'ocr_extraction'
  | 'text_parsing'
  | 'store_detection'
  | 'item_extraction'
  | 'item_matching'
  | 'price_parsing'
  | 'finalization';

/**
 * Receipt processing log status.
 */
export type ReceiptProcessingStatus = 'started' | 'completed' | 'failed' | 'skipped';

/**
 * OCR providers for receipt processing.
 */
export type OcrProvider =
  | 'tesseract'
  | 'openai'
  | 'anthropic'
  | 'google_vision'
  | 'aws_textract'
  | 'gemini'
  | 'internal';

/**
 * Receipt scan record from database.
 * Maps to public.receipts table.
 */
export interface ReceiptScan {
  /** Primary key */
  receipt_id: number;
  /** User who uploaded the receipt */
  user_id: string;
  /** Detected store */
  store_id: number | null;
  /** Path to receipt image */
  receipt_image_url: string;
  /** Transaction date from receipt */
  transaction_date: string | null;
  /** Total amount in cents */
  total_amount_cents: number | null;
  /** Processing status */
  status: ReceiptStatus;
  /** Raw OCR text */
  raw_text: string | null;
  /** Store detection confidence */
  store_confidence: number | null;
  /** OCR provider used */
  ocr_provider: OcrProvider | null;
  /** Error details if failed */
  error_details: Record<string, unknown> | null;
  /** Number of retry attempts */
  retry_count: number;
  /** OCR confidence score */
  ocr_confidence: number | null;
  /** Detected currency */
  currency: string;
  /** Record timestamps */
  created_at: string;
  processed_at: string | null;
  updated_at: string;
}

/**
 * Item extracted from a receipt.
 * Maps to public.receipt_items table.
 */
export interface ReceiptItem {
  /** Primary key */
  receipt_item_id: number;
  /** Parent receipt */
  receipt_id: number;
  /** Raw item text from receipt */
  raw_item_description: string;
  /** Quantity purchased */
  quantity: number;
  /** Price paid in cents */
  price_paid_cents: number;
  /** Matched master item */
  master_item_id: number | null;
  /** Matched product */
  product_id: number | null;
  /** Matching status */
  status: ReceiptItemStatus;
  /** Line number on receipt */
  line_number: number | null;
  /** Match confidence score */
  match_confidence: number | null;
  /** Whether this is a discount line */
  is_discount: boolean;
  /** Unit price if detected */
  unit_price_cents: number | null;
  /** Unit type if detected */
  unit_type: string | null;
  /** Whether added to pantry */
  added_to_pantry: boolean;
  /** Link to pantry item if added */
  pantry_item_id: number | null;
  /** UPC code if extracted */
  upc_code: string | null;
  /** Record timestamps */
  created_at: string;
  updated_at: string;
}

/**
 * Request to upload a receipt for scanning.
 */
export interface UploadReceiptRequest {
  /** Base64-encoded receipt image */
  image_base64: string;
  /** Known store ID (optional) */
  store_id?: number;
  /** Known transaction date (optional) */
  transaction_date?: string;
}

/**
 * Request to confirm receipt items and add to inventory.
 */
export interface ConfirmReceiptItemsRequest {
  /** Items to add to inventory */
  items: Array<{
    /** Receipt item ID */
    receipt_item_id: number;
    /** Override item name */
    item_name?: string;
    /** Override quantity */
    quantity?: number;
    /** Storage location */
    location?: StorageLocation;
    /** Expiry date if known */
    expiry_date?: string;
    /** Whether to add this item (false = skip) */
    include: boolean;
  }>;
}

/**
 * Receipt processing log record.
 * Maps to public.receipt_processing_log table.
 */
export interface ReceiptProcessingLogRecord {
  /** Primary key */
  log_id: number;
  /** Parent receipt */
  receipt_id: number;
  /** Processing step */
  processing_step: ReceiptProcessingStep;
  /** Step status */
  status: ReceiptProcessingStatus;
  /** Provider used */
  provider: OcrProvider | null;
  /** Duration in milliseconds */
  duration_ms: number | null;
  /** Tokens used (for LLM) */
  tokens_used: number | null;
  /** Cost in cents */
  cost_cents: number | null;
  /** Input data */
  input_data: Record<string, unknown> | null;
  /** Output data */
  output_data: Record<string, unknown> | null;
  /** Error message if failed */
  error_message: string | null;
  /** When logged */
  created_at: string;
}

// ============================================================================
// QUERY OPTION TYPES
// ============================================================================

/**
 * Options for querying user inventory.
 */
export interface InventoryQueryOptions {
  /** User ID to filter by */
  user_id: string;
  /** Filter by storage location */
  location?: StorageLocation;
  /** Filter by consumed status */
  is_consumed?: boolean;
  /** Filter items expiring within N days */
  expiring_within_days?: number;
  /** Filter by category ID */
  category_id?: number;
  /** Search by item name */
  search?: string;
  /** Maximum number of results */
  limit?: number;
  /** Offset for pagination */
  offset?: number;
  /** Sort field */
  sort_by?: 'expiry_date' | 'purchase_date' | 'item_name' | 'created_at';
  /** Sort direction */
  sort_order?: 'asc' | 'desc';
}

/**
 * Options for querying expiry date ranges.
 */
export interface ExpiryRangeQueryOptions {
  /** Filter by master item ID */
  master_item_id?: number;
  /** Filter by category ID */
  category_id?: number;
  /** Filter by storage location */
  storage_location?: StorageLocation;
  /** Filter by source */
  source?: ExpiryRangeSource;
  /** Maximum number of results */
  limit?: number;
  /** Offset for pagination */
  offset?: number;
}

/**
 * Options for calculating expiry date.
 */
export interface CalculateExpiryOptions {
  /** Master item ID for lookup */
  master_item_id?: number;
  /** Category ID for fallback lookup */
  category_id?: number;
  /** Item name for pattern matching fallback */
  item_name?: string;
  /** Storage location */
  storage_location: StorageLocation;
  /** Purchase date to calculate from */
  purchase_date: string;
}
