/**
 * Hand-written TypeScript types derived from specs/openapi/bff-api.v1.yaml
 * and component schemas. Keep in sync with OpenAPI when schemas change.
 */

// --- Enums (specs/openapi/components/enums.yaml) ---

export type OnboardingStep =
  | "ACCOUNT"
  | "CONSENT"
  | "KYC"
  | "FARM_PROFILE"
  | "LAND_SKETCH"
  | "GIS_MAPPING"
  | "CROP_PLAN"
  | "FARM_ASSETS"
  | "DOCUMENTS"
  | "FINANCE_REQUEST"
  | "REVIEW"
  | "SCORING"
  | "RESULT";

export type OnboardingStatus =
  | "in_progress"
  | "submitted"
  | "scoring"
  | "completed"
  | "abandoned";

export type ApplicationStatus =
  | "none"
  | "in_progress"
  | "submitted"
  | "scoring"
  | "completed";

export type EligibilityOutcome = "eligible" | "conditional" | "not_eligible";

export type KycStatus =
  | "pending"
  | "in_progress"
  | "verified"
  | "rejected"
  | "manual_review";

export type FinanceCaseStatus =
  | "pending"
  | "under_review"
  | "approved"
  | "rejected";

export type GisStatus =
  | "coordinates_provided"
  | "agent_pending"
  | "polygon_provided";

export type VerificationMethod = "sms" | "voice_otp";

export type PreferredLanguage = "uz" | "ru" | "en";

export type ConsentLocale = "uz" | "ru";

export type ConsentKey =
  | "credit_check"
  | "geo_data"
  | "institution_sharing"
  | "data_processing"
  | "credit_bureau"
  | "gis_satellite"
  | "data_sharing_institutions";

export type ConsentAcceptedMap = Partial<Record<ConsentKey, boolean>> & Record<string, boolean>;

export type IdType = "national_id" | "passport" | "biometric_passport";

export type Gender = "male" | "female" | "prefer_not_to_say";

export type FarmerType =
  | "owner"
  | "tenant"
  | "family_farm"
  | "cooperative_member";

export type Education =
  | "none"
  | "primary"
  | "secondary"
  | "vocational"
  | "university";

export type TenureType =
  | "owned"
  | "leased"
  | "sharecrop"
  | "communal"
  | "inheritance";

export type LandUseType =
  | "irrigated_cropland"
  | "rainfed"
  | "orchard"
  | "pasture"
  | "greenhouse";

export type IrrigationSource =
  | "canal"
  | "well"
  | "drip"
  | "rainfed"
  | "mixed";

export type CropSeason = "spring" | "summer" | "autumn" | "winter";

export type AssetCondition = "new" | "good" | "fair" | "poor";

export type CaptureMethod =
  | "gps"
  | "manual_pin"
  | "map_polygon"
  | "agent_assist";

export type RepaymentHistory = "none" | "good" | "fair" | "poor";

export type ExtractionStatus =
  | "pending"
  | "processing"
  | "completed"
  | "failed";

export type DocumentUploadStatus = "uploaded" | "processing" | "failed";

export type DocumentType =
  | "national_id"
  | "land_deed"
  | "tax_receipt"
  | "bank_statement";

export type ReferenceOptionType =
  | "consent_types"
  | "regions"
  | "districts"
  | "crops"
  | "asset_types"
  | "finance_purposes"
  | "required_docs"
  | "institutions"
  | "institution_checklist";

export type CountryCode = string;

// --- Onboarding step payloads (specs/openapi/components/onboarding-steps.yaml) ---

export interface StepAccountData {
  phone: string;
  verified: boolean;
  verificationMethod?: VerificationMethod;
  wizardDeferred?: boolean;
  deferredAfterStep?: OnboardingStep;
  deferredAt?: string;
}

export interface StepConsentData {
  accepted: ConsentAcceptedMap;
  consentVersion: string;
  consentType: string;
  acceptedAt: string;
  locale: ConsentLocale;
}

export type KycAssistMode = "self_serve" | "agent_assisted";

export interface StepKycData {
  nationalId: string;
  pinfl?: string;
  idType: IdType;
  oneIdSessionId?: string;
  fullNameOfficial?: string;
  dateOfBirthOfficial?: string;
  genderOfficial?: Gender;
  kycAssistMode?: KycAssistMode;
  kycStatus: KycStatus;
  verifiedAt: string;
}

export interface StepFarmProfileData {
  fullName: string;
  dateOfBirth: string;
  gender: Gender;
  primaryLanguage: PreferredLanguage;
  region: string;
  district: string;
  householdSize: number;
  yearsFarming: number;
  farmerType: FarmerType;
  education: Education;
}

export interface LandParcel {
  district: string;
  village: string;
  areaHa: number;
  tenureType: TenureType;
  landUseType: LandUseType;
  irrigationSource: IrrigationSource;
  isPrimary: boolean;
  registryRef?: string;
}

export interface StepLandSketchData {
  parcels: LandParcel[];
}

export interface GisCoordinates {
  lat?: number;
  lng?: number;
  accuracyM?: number;
}

export interface StepGisMappingData {
  gisStatus: GisStatus;
  parcelId?: string;
  coordinates?: GisCoordinates;
  geoJson?: GeoJsonPolygon;
  derivedAreaHa?: number;
  note?: string;
  captureMethod?: CaptureMethod;
  agentAssistMode?: boolean;
}

/** GeoJSON Polygon (RFC 7946) — stored from map draw or coordinate entry. */
export interface GeoJsonPolygon {
  type: "Polygon";
  coordinates: number[][][];
}

export interface CropEntry {
  crop: string;
  season: CropSeason;
  areaHa: number;
  expectedYield: number;
  intendedMarket?: string;
  hasBuyerContract?: boolean;
  priorYearYield?: number;
}

export interface StepCropPlanData {
  crops: CropEntry[];
}

export interface AssetEntry {
  assetType: string;
  condition: AssetCondition;
  estimatedValue: number;
  quantity: number;
}

export type OwnershipStatus = "owned" | "leased" | "shared" | "unknown";

export interface StepFarmAssetsData {
  assets?: AssetEntry[];
  totalAssetValueUsd?: number;
  noneDeclared?: boolean;
  ownership?: OwnershipStatus;
  titleProof?: boolean;
  storageCapacity?: number;
}

export interface UseOfFundsEntry {
  category: string;
  amountUzs: number;
}

export interface StepFinanceRequestData {
  purpose: string;
  amountUzs: number;
  amountUsd?: number;
  termMonths: number;
  monthlyIncomeUzs: number;
  existingLoansUzs: number;
  repaymentHistory: RepaymentHistory;
  monthlyExpensesUzs?: number;
  useOfFundsBreakdown?: UseOfFundsEntry[];
  expectedRevenueUzs?: number;
  preferredInstitution?: string;
}

export interface DocumentRecord {
  docType?: DocumentType;
  fileId?: string;
  uploadedAt?: string;
}

export interface FinancialFieldConfidence {
  monthlyIncomeUzs?: number;
  existingLoansUzs?: number;
  accountBalanceUzs?: number;
}

export interface ExtractedFinancials {
  monthlyIncomeUzs?: number;
  existingLoansUzs?: number;
  accountBalanceUzs?: number;
  confidence?: FinancialFieldConfidence;
}

export interface StepDocumentsData {
  uploaded?: Record<string, boolean>;
  documents?: DocumentRecord[];
  extractionStatus?: ExtractionStatus;
  extractedFinancials?: ExtractedFinancials;
  documentQualityScore?: number;
  documentAssistMode?: boolean;
}

export type ConflictResolution = "keep_mine" | "use_document" | "edit";

export type ReviewConflictType = "income_vs_ocr" | "crop_area_vs_land";

export interface ReviewConflict {
  id: string;
  type: ReviewConflictType;
  label: string;
  farmerValue?: string | number;
  documentValue?: string | number;
  resolution?: ConflictResolution;
}

export interface StepReviewData {
  reviewed: boolean;
  reviewedAt: string;
  attestationText?: string;
  conflicts?: ReviewConflict[];
}

export interface ReasonCode {
  code?: string;
  feature?: string;
  contribution?: number;
  direction?: "positive" | "negative";
}

export interface StepScoringData {
  scoringComplete?: boolean;
  scoringError?: boolean;
  scoringFailed?: boolean;
  scoringTimeout?: boolean;
  decision?: EligibilityOutcome;
  score?: number;
  reasonCodes?: ReasonCode[];
  financeCaseId?: string;
  financeCaseStatus?: FinanceCaseStatus;
  conditionalRequirements?: ConditionalRequirement[];
  satelliteSummary?: string;
  farmerExplanation?: FarmerExplanation;
  satelliteImages?: string[];
  scoringMeta?: ScoringMeta;
}

export interface FarmerExplanation {
  uz?: string;
  ru?: string;
  en?: string;
}

export interface ScoringMeta {
  modelVersion?: string;
  scoringSource?: "agri_access" | "rules_fallback";
  cbuClass?: number;
  baselPd?: number;
  riskRating?: string;
  ifrs9Stage?: number;
  farmerExplanation?: FarmerExplanation;
  satelliteSummary?: string;
  processingDurationMs?: number;
}

export type ScoringPhase = "geo" | "documents" | "scoring" | "finalize";

export interface ConditionalRequirement {
  code?: string;
  label?: string;
  description?: string;
}

export interface StepResultData {
  acknowledged: boolean;
  acknowledgedAt: string;
  outcome?: EligibilityOutcome;
  financeCaseId?: string;
  financeCaseStatus?: FinanceCaseStatus;
  conditionalRequirements?: ConditionalRequirement[];
}

export interface OnboardingStepData {
  ACCOUNT?: StepAccountData;
  CONSENT?: StepConsentData;
  KYC?: StepKycData;
  FARM_PROFILE?: StepFarmProfileData;
  LAND_SKETCH?: StepLandSketchData;
  GIS_MAPPING?: StepGisMappingData;
  CROP_PLAN?: StepCropPlanData;
  FARM_ASSETS?: StepFarmAssetsData;
  DOCUMENTS?: StepDocumentsData;
  FINANCE_REQUEST?: StepFinanceRequestData;
  REVIEW?: StepReviewData;
  SCORING?: StepScoringData;
  RESULT?: StepResultData;
  [key: string]: unknown;
}

/** Payload accepted by PATCH /onboarding/{id}/steps/{step} for a given step key. */
export type StepPayload<K extends OnboardingStep> = NonNullable<
  OnboardingStepData[K]
>;

// --- Auth (bff-api.v1.yaml) ---

export interface OtpRequest {
  phone: string;
  countryCode?: CountryCode;
}

export interface OtpVerifyRequest extends OtpRequest {
  code: string;
}

export interface OtpSentResponse {
  sent: boolean;
}

export interface User {
  id: string;
  phone: string;
  countryCode: string;
  kycStatus: KycStatus;
}

export interface VerifyResponse {
  user: User;
}

export interface UserMeResponse extends User {
  farmerProfile?: Record<string, unknown> | null;
  activeSession?: OnboardingSession | null;
}

// --- Onboarding session (bff-api.v1.yaml) ---

export interface CreateOnboardingRequest {
  countryCode?: CountryCode;
  channel?: "farmer";
}

export interface OnboardingSession {
  id: string;
  userId: string;
  countryCode: string;
  channel: string;
  currentStep: number;
  currentStepKey: OnboardingStep;
  status: OnboardingStatus;
  stepData: OnboardingStepData;
  completedSteps: OnboardingStep[];
  stepRecords?: Record<string, unknown>[];
  createdAt?: string;
  updatedAt?: string;
}

export interface UpdateStepRequest<T extends Record<string, unknown> = Record<string, unknown>> {
  data: T;
  markComplete?: boolean;
}

export interface OnboardingStatusResponse {
  onboardingId: string;
  currentStep: OnboardingStep;
  completedSteps: OnboardingStep[];
  status: OnboardingStatus;
  scoringPhase?: ScoringPhase;
  eligibilityOutcome?: EligibilityOutcome | null;
  score?: number | null;
  reasonCodes?: ReasonCode[];
  financeCaseId?: string | null;
  financeCaseStatus?: FinanceCaseStatus | null;
  conditionalRequirements?: ConditionalRequirement[];
  scoringMeta?: ScoringMeta;
  satelliteImages?: string[];
  farmerExplanation?: FarmerExplanation;
}

// --- Documents ---

export interface DocumentUploadResponse {
  documentId: string;
  sessionId: string;
  docType: string;
  fileName: string;
  status: DocumentUploadStatus;
  uploadedAt?: string;
}

// --- Reference ---

export interface ReferenceOption {
  value: string;
  label: string;
  metadata?: Record<string, unknown>;
}

// --- Config (country profile + appearance) ---

export type ThemeOption = "light" | "dark" | "system";

export interface AppearanceConfig {
  allowedThemes: ThemeOption[];
  defaultTheme: ThemeOption;
  darkModeEnabled: boolean;
}

export interface CountryConfigResponse {
  countryCode: string;
  languages: string[];
  consentVersion: string;
  featureFlags: Record<string, boolean>;
  appearance: AppearanceConfig;
}

export interface FarmerPreferencesRequest {
  primaryLanguage: PreferredLanguage;
}

export interface FarmerPreferencesResponse {
  primaryLanguage: PreferredLanguage;
}

// --- Farmer dashboard (bff-api.v1.yaml + dashboard-v2.openapi.yaml) ---

export interface FinanceStage {
  label?: string;
  completed?: boolean;
  timestamp?: string;
}

export interface IdentityEkyc {
  photoUrl?: string;
  dob?: string;
  aadhaarMasked?: string;
  mobileMasked?: string;
}

export interface IdentityGis {
  areaHa: number;
  lat: number;
  lng: number;
  polygonGeoJson?: GeoJsonPolygon;
}

export interface LandEvidenceItem {
  name: string;
  type: "pdf" | "doc";
  verified: boolean;
}

export interface YieldHistoryEntry {
  year: number;
  yieldTHa: number;
  crop: string;
}

export interface ComplianceItem {
  key: string;
  label: string;
  passed: boolean;
}

export interface RoutedInstitution {
  name: string;
  priority: string;
  isBestMatch: boolean;
}

export interface FinanceSla {
  remainingHours: number;
  totalHours: number;
  dueAt: string;
}

export interface BankMatch {
  name: string;
  score: number;
  status: "routed" | "view";
}

export interface FinanceDocumentItem {
  name: string;
  status: "verified" | "pending";
}

export interface InputsKpis {
  seed: number;
  fertiliser: number;
  equipment: number;
  vouchers: number;
  inTransit: number;
}

export interface SupplierRating {
  name: string;
  logoUrl?: string;
  rating: number;
}

export interface CatalogItem {
  id: string;
  name: string;
  unitPrice: number;
  currency: string;
  imageUrl?: string;
}

export interface CatalogCategory {
  category: string;
  items: CatalogItem[];
}

export interface VoucherPaymentRoute {
  step: number;
  label: string;
  completed: boolean;
}

export interface VoucherDetail {
  code: string;
  amount: number;
  currency: string;
  status: "active" | "redeemed" | "expired";
  paymentRoute: VoucherPaymentRoute[];
}

export interface DeliveryStep {
  label: string;
  completed: boolean;
  timestamp?: string | null;
}

export interface DeliveryTracking {
  trackingId: string;
  status: "pending" | "in_transit" | "delivered";
  eta?: string;
  steps: DeliveryStep[];
}

export interface FinanceModule {
  purpose?: string;
  amount?: string;
  existingLoans?: string;
  monthlyIncome?: string;
  repaymentHistory?: string;
  caseId?: string;
  status?: FinanceCaseStatus;
  riskPd?: number;
  riskRating?: string;
  ifrs9Stage?: number;
  cbuClass?: number;
  farmerExplanation?: FarmerExplanation;
  satelliteImages?: string[];
  stages?: FinanceStage[];
  /** dashboard-v2 */
  eligibilityScore?: number;
  eligibilityLabel?: string;
  routedInstitution?: RoutedInstitution;
  sla?: FinanceSla;
  bankMatches?: BankMatch[];
  documents?: FinanceDocumentItem[];
}

export interface BuyerMatch {
  buyerName?: string;
  commodity?: string;
  priceRange?: string;
}

export interface TradeModule {
  crops?: CropEntry[];
  buyerMatches?: BuyerMatch[];
  exportDocsComplete?: boolean;
}

export interface IdentityModule {
  fullName?: string;
  region?: string;
  district?: string;
  gender?: string;
  kycStatus?: string;
  farmSizeHa?: string;
  landOwnership?: string;
  hasGisMapping?: boolean;
  documentCompleteness?: number;
  /** dashboard-v2 */
  farmerId?: string;
  farmName?: string;
  ekyc?: IdentityEkyc;
  gis?: IdentityGis;
  landEvidence?: LandEvidenceItem[];
  yieldHistory?: YieldHistoryEntry[];
  compliance?: ComplianceItem[];
}

export interface RecommendedInput {
  name?: string;
  category?: string;
  relevance?: string;
}

export interface InputsModule {
  assets?: AssetEntry[];
  recommendedInputs?: RecommendedInput[];
  /** dashboard-v2 */
  kpis?: InputsKpis;
  suppliers?: SupplierRating[];
  catalog?: CatalogCategory[];
  voucher?: VoucherDetail;
  delivery?: DeliveryTracking;
}

export interface FarmerDashboardResponse {
  userId: string;
  phone: string;
  sessionId?: string;
  applicationStatus: ApplicationStatus;
  score?: number | null;
  eligibility?: EligibilityOutcome | null;
  reasonCodes?: ReasonCode[];
  finance?: FinanceModule | null;
  trade?: TradeModule | null;
  identity?: IdentityModule | null;
  inputs?: InputsModule | null;
}
