import type { IndustrialParkStatus, VietnamRegion } from '@prisma/client';
import type { IndustrialParkEntity } from '../entities/industrial-park.entity';

export const INDUSTRIAL_PARK_REPOSITORY = Symbol('INDUSTRIAL_PARK_REPOSITORY');

export interface IndustrialParkSearchParams {
  query?: string;
  province?: string;
  region?: VietnamRegion;
  status?: IndustrialParkStatus;
  minAreaHa?: number;
  maxRentUsdM2?: number;
  targetIndustry?: string;
  ownerId?: string;
  page?: number;
  limit?: number;
}

export interface PaginatedResult<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface IndustrialParkListItem {
  id: string;
  name: string;
  nameEn: string | null;
  slug: string;
  developer: string;
  status: IndustrialParkStatus;
  province: string;
  region: VietnamRegion;
  totalAreaHa: number;
  occupancyRate: number;
  remainingAreaHa: number;
  tenantCount: number;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  landRentUsdM2Year: string | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  rbfRentUsdM2Month: string | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  rbwRentUsdM2Month: string | null;
  targetIndustries: string[];
  latitude: number;
  longitude: number;
  ownerId: string | null;
}

export interface IndustrialParkDetailData {
  id: string;
  name: string;
  nameEn: string | null;
  slug: string;
  developer: string;
  operator: string | null;
  status: IndustrialParkStatus;
  latitude: number;
  longitude: number;
  address: string;
  district: string;
  province: string;
  region: VietnamRegion;
  totalAreaHa: number;
  leasableAreaHa: number;
  occupancyRate: number;
  remainingAreaHa: number;
  tenantCount: number;
  establishedYear: number | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  landRentUsdM2Year: string | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  rbfRentUsdM2Month: string | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  rbwRentUsdM2Month: string | null;
  /** Decimal(18,4) serialised as string — use parseFloat() for arithmetic. */
  managementFeeUsd: string | null;
  infrastructure: Record<string, unknown> | null;
  connectivity: Record<string, unknown> | null;
  incentives: Record<string, unknown> | null;
  targetIndustries: string[];
  existingTenants: Record<string, unknown>[] | null;
  certifications: string[] | null;
  media: Record<string, unknown>[] | null;
  documents: Record<string, unknown>[] | null;
  description: string | null;
  descriptionEn: string | null;
  isVerified: boolean;
  ownerId: string | null;
  listingCount: number;
  createdAt: Date;
  updatedAt: Date;
}

export interface IndustrialParkStatsData {
  totalParks: number;
  totalAreaHa: number;
  avgOccupancyRate: number;
  totalTenants: number;
  byRegion: { region: string; count: number; avgOccupancy: number }[];
  byStatus: { status: string; count: number }[];
  topProvinces: { province: string; count: number; avgRent: number | null }[];
}

export interface IndustrialMarketData {
  totalParks: number;
  avgOccupancyRate: number;
  /** AVG(numeric) serialised as string by PostgreSQL. */
  avgLandRentUsdM2: string | null;
  /** AVG(numeric) serialised as string by PostgreSQL. */
  avgRbfRentUsdM2: string | null;
  rentByRegion: { region: string; avgLandRent: string | null; avgRbfRent: string | null; parkCount: number }[];
  rentByProvince: { province: string; avgLandRent: string | null; avgRbfRent: string | null; parkCount: number }[];
}

export interface IIndustrialParkRepository {
  findById(id: string): Promise<IndustrialParkEntity | null>;
  findBySlug(slug: string): Promise<IndustrialParkEntity | null>;
  findDetailBySlug(slug: string): Promise<IndustrialParkDetailData | null>;
  findDetailById(id: string): Promise<IndustrialParkDetailData | null>;
  save(entity: IndustrialParkEntity): Promise<void>;
  update(entity: IndustrialParkEntity): Promise<void>;
  delete(id: string): Promise<void>;
  search(params: IndustrialParkSearchParams): Promise<PaginatedResult<IndustrialParkListItem>>;
  compareParks(ids: string[]): Promise<IndustrialParkDetailData[]>;
  getStats(): Promise<IndustrialParkStatsData>;
  getMarketData(): Promise<IndustrialMarketData>;
}
