/**
 * Japan Post API - Raw Types
 *
 * Types for Japan Post Digital Address API responses.
 * These match the actual API response structure.
 */

import { z } from "zod";

// ============================================================================
// Token Response
// ============================================================================

/**
 * Token response from POST /api/v1/j/token
 */
export const japanPostTokenResponseSchema = z.object({
  scope: z.string().optional(),
  token_type: z.string(),
  expires_in: z.number(),
  token: z.string(),
});

export type JapanPostTokenResponse = z.infer<typeof japanPostTokenResponseSchema>;

// ============================================================================
// Address Search Response
// ============================================================================

/**
 * Single address record from Japan Post API
 * Fields from GET /api/v1/searchcode/{search_code}
 *
 * Note: API returns `null` for empty fields, so we use `.nullish()` instead of `.optional()`
 */
export const japanPostAddressRecordSchema = z.object({
  // ZIP code
  zipcode: z.string().nullish(),
  zip_code: z.string().nullish(),

  // Digital address code (can be null)
  dgacode: z.string().nullish(),

  // Prefecture
  pref_code: z.string().nullish(),
  pref_name: z.string().nullish(),
  pref_kana: z.string().nullish(),
  pref_roma: z.string().nullish(),

  // City
  city_code: z.string().nullish(),
  city_name: z.string().nullish(),
  city_kana: z.string().nullish(),
  city_roma: z.string().nullish(),

  // Town
  town_code: z.string().nullish(),
  town_name: z.string().nullish(),
  town_kana: z.string().nullish(),
  town_roma: z.string().nullish(),

  // Block/street details (often null)
  block_name: z.string().nullish(),
  block_kana: z.string().nullish(),
  block_roma: z.string().nullish(),

  // Business/office info (for business ZIP codes)
  biz_name: z.string().nullish(),
  biz_kana: z.string().nullish(),
  biz_roma: z.string().nullish(),

  // Legacy office fields
  office_name: z.string().nullish(),
  office_kana: z.string().nullish(),
  office_roma: z.string().nullish(),

  // Additional fields from API
  other_name: z.string().nullish(),
  address: z.string().nullish(),
  longitude: z.union([z.string(), z.number()]).nullish(),
  latitude: z.union([z.string(), z.number()]).nullish(),
});

export type JapanPostAddressRecord = z.infer<typeof japanPostAddressRecordSchema>;

/**
 * Search response from GET /api/v1/searchcode/{search_code}
 */
export const japanPostSearchResponseSchema = z.object({
  addresses: z.array(japanPostAddressRecordSchema),
  searchtype: z.string().optional(),
  limit: z.number().optional(),
  count: z.number(),
  page: z.number().optional(),
});

export type JapanPostSearchResponse = z.infer<typeof japanPostSearchResponseSchema>;

// ============================================================================
// Error Response
// ============================================================================

/**
 * Error response from Japan Post API
 */
export const japanPostErrorResponseSchema = z.object({
  error: z.string().optional(),
  error_description: z.string().optional(),
  message: z.string().optional(),
});

export type JapanPostErrorResponse = z.infer<typeof japanPostErrorResponseSchema>;
