import {
  PlantingPosition as PrismaPlantingPosition,
  PositionDistribution as PrismaPositionDistribution,
} from '@prisma/client';
import {
  PlantingPosition,
  PlantingPositionData,
} from '../../../domain/aggregates/planting-position.aggregate';

type PlantingPositionWithDistributions = PrismaPlantingPosition & {
  distributions?: PrismaPositionDistribution[];
};

export class PlantingPositionMapper {
  static toDomain(
    prismaPosition: PlantingPositionWithDistributions,
  ): PlantingPosition {
    const data: PlantingPositionData = {
      id: prismaPosition.id,
      userId: prismaPosition.userId,
      totalTreeCount: prismaPosition.totalTreeCount,
      effectiveTreeCount: prismaPosition.effectiveTreeCount,
      pendingTreeCount: prismaPosition.pendingTreeCount,
      firstMiningStartAt: prismaPosition.firstMiningStartAt,
      distributions: prismaPosition.distributions?.map((d) => ({
        id: d.id,
        userId: d.userId,
        provinceCode: d.provinceCode,
        cityCode: d.cityCode,
        treeCount: d.treeCount,
      })),
    };

    return PlantingPosition.reconstitute(data);
  }

  static toPersistence(position: PlantingPosition): {
    positionData: Omit<PrismaPlantingPosition, 'id' | 'createdAt' | 'updatedAt'> & {
      id?: bigint;
    };
    distributions: Omit<
      PrismaPositionDistribution,
      'id' | 'createdAt' | 'updatedAt'
    >[];
  } {
    const data = position.toPersistence();

    const positionData = {
      id: data.id,
      userId: data.userId,
      totalTreeCount: data.totalTreeCount,
      effectiveTreeCount: data.effectiveTreeCount,
      pendingTreeCount: data.pendingTreeCount,
      firstMiningStartAt: data.firstMiningStartAt || null,
    };

    const distributions =
      data.distributions?.map((d) => ({
        userId: d.userId,
        provinceCode: d.provinceCode,
        cityCode: d.cityCode,
        treeCount: d.treeCount,
      })) || [];

    return { positionData, distributions };
  }
}
