import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, IsNull } from 'typeorm';
import { CowModel } from '../cow/entities/cow.entity';
import { FarmModel } from '../farm/entities/farm.entity';
import { GenomeRequestModel } from '../genome/entities/genome-request.entity';
import { GenomeTraitDetailModel } from '../genome/entities/genome-trait-detail.entity';
import { DashboardFilterDto } from './dto/dashboard-filter.dto';
import { isValidGenomeAnalysis, VALID_CHIP_SIRE_NAME } from '../common/config/GenomeAnalysisConfig';

@Injectable()
export class DashboardService {
  constructor(
    @InjectRepository(CowModel)
    private readonly cowRepository: Repository<CowModel>,

    @InjectRepository(FarmModel)
    private readonly farmRepository: Repository<FarmModel>,

    @InjectRepository(GenomeRequestModel)
    private readonly genomeRequestRepository: Repository<GenomeRequestModel>,

    @InjectRepository(GenomeTraitDetailModel)
    private readonly genomeTraitDetailRepository: Repository<GenomeTraitDetailModel>,
  ) {}

  /**
   * 농장 현황 요약
   */
  async getFarmSummary(farmNo: number, filter?: DashboardFilterDto) {
    // 농장 정보 조회
    const farm = await this.farmRepository.findOne({
      where: { pkFarmNo: farmNo, delDt: IsNull() },
    });

    // 농장 소 목록 조회
    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    const totalCowCount = cows.length;
    const maleCowCount = cows.filter(cow => cow.cowSex === 'M').length;
    const femaleCowCount = cows.filter(cow => cow.cowSex === 'F').length;

    return {
      farmNo,
      farmName: farm?.farmerName || '농장',
      totalCowCount,
      maleCowCount,
      femaleCowCount,
    };
  }

  /**
   * 분석 완료 현황
   */
  async getAnalysisCompletion(farmNo: number, filter?: DashboardFilterDto) {
    // 농장의 모든 유전체 분석 의뢰 조회
    const requests = await this.genomeRequestRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
      relations: ['cow'],
    });

    const farmAnlysCnt = requests.length;
    const matchCnt = requests.filter(r => r.chipSireName === '일치').length;
    const failCnt = requests.filter(r => r.chipSireName && r.chipSireName !== '일치').length;
    const noHistCnt = requests.filter(r => !r.chipSireName).length;

    return {
      farmAnlysCnt,
      matchCnt,
      failCnt,
      noHistCnt,
      paternities: requests.map(r => ({
        cowNo: r.fkCowNo,
        cowId: r.cow?.cowId,
        fatherMatch: r.chipSireName === '일치' ? '일치' : (r.chipSireName ? '불일치' : '미확인'),
        requestDt: r.requestDt,
      })),
    };
  }

  /**
   * 농장 종합 평가
   */
  async getFarmEvaluation(farmNo: number, filter?: DashboardFilterDto) {
    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    // 각 개체의 유전체 점수 계산
    const scores: number[] = [];

    for (const cow of cows) {
      // cowId로 직접 형질 데이터 조회
      const traitDetails = await this.genomeTraitDetailRepository.find({
        where: { cowId: cow.cowId, delDt: IsNull() },
      });

      if (traitDetails.length === 0) continue;

      // 모든 형질의 EBV 평균 계산
      const ebvValues = traitDetails
        .filter(d => d.traitEbv !== null)
        .map(d => Number(d.traitEbv));

      if (ebvValues.length > 0) {
        const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;
        scores.push(avgEbv);
      }
    }

    const farmAverage = scores.length > 0
      ? scores.reduce((sum, s) => sum + s, 0) / scores.length
      : 0;

    // 등급 산정 (표준화육종가 기준)
    let grade = 'C';
    if (farmAverage >= 1.0) grade = 'A';
    else if (farmAverage >= 0.5) grade = 'B';
    else if (farmAverage >= -0.5) grade = 'C';
    else if (farmAverage >= -1.0) grade = 'D';
    else grade = 'E';

    return {
      farmNo,
      farmAverage: Math.round(farmAverage * 100) / 100,
      grade,
      analyzedCount: scores.length,
      totalCount: cows.length,
    };
  }

  /**
   * 보은군 비교 분석
   */
  async getRegionComparison(farmNo: number, filter?: DashboardFilterDto) {
    // 내 농장 평균 계산
    const farmEval = await this.getFarmEvaluation(farmNo, filter);

    // 전체 농장 평균 계산 (보은군 대비)
    const allFarms = await this.farmRepository.find({
      where: { delDt: IsNull() },
    });

    const farmScores: { farmNo: number; avgScore: number }[] = [];

    for (const farm of allFarms) {
      const farmCows = await this.cowRepository.find({
        where: { fkFarmNo: farm.pkFarmNo, delDt: IsNull() },
      });

      const scores: number[] = [];
      for (const cow of farmCows) {
        // cowId로 직접 형질 데이터 조회
        const traitDetails = await this.genomeTraitDetailRepository.find({
          where: { cowId: cow.cowId, delDt: IsNull() },
        });

        if (traitDetails.length === 0) continue;

        const ebvValues = traitDetails
          .filter(d => d.traitEbv !== null)
          .map(d => Number(d.traitEbv));

        if (ebvValues.length > 0) {
          const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;
          scores.push(avgEbv);
        }
      }

      if (scores.length > 0) {
        farmScores.push({
          farmNo: farm.pkFarmNo,
          avgScore: scores.reduce((sum, s) => sum + s, 0) / scores.length,
        });
      }
    }

    // 내 농장 순위 계산
    farmScores.sort((a, b) => b.avgScore - a.avgScore);
    const myFarmRank = farmScores.findIndex(f => f.farmNo === farmNo) + 1;
    const totalFarmCount = farmScores.length;
    const topPercent = totalFarmCount > 0 ? Math.round((myFarmRank / totalFarmCount) * 100) : 0;

    // 지역 평균
    const regionAverage = farmScores.length > 0
      ? farmScores.reduce((sum, f) => sum + f.avgScore, 0) / farmScores.length
      : 0;

    return {
      farmNo,
      farmAverage: farmEval.farmAverage,
      regionAverage: Math.round(regionAverage * 100) / 100,
      farmRank: myFarmRank || 1,
      totalFarmCount: totalFarmCount || 1,
      topPercent: topPercent || 100,
    };
  }

  /**
   * 개체 분포 분석
   */
  async getCowDistribution(farmNo: number, filter?: DashboardFilterDto) {
    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    const distribution = {
      A: 0,
      B: 0,
      C: 0,
      D: 0,
      E: 0,
    };

    for (const cow of cows) {
      // cowId로 직접 형질 데이터 조회
      const traitDetails = await this.genomeTraitDetailRepository.find({
        where: { cowId: cow.cowId, delDt: IsNull() },
      });

      if (traitDetails.length === 0) continue;

      const ebvValues = traitDetails
        .filter(d => d.traitEbv !== null)
        .map(d => Number(d.traitEbv));

      if (ebvValues.length > 0) {
        const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;

        if (avgEbv >= 1.0) distribution.A++;
        else if (avgEbv >= 0.5) distribution.B++;
        else if (avgEbv >= -0.5) distribution.C++;
        else if (avgEbv >= -1.0) distribution.D++;
        else distribution.E++;
      }
    }

    return {
      farmNo,
      distribution,
      total: cows.length,
    };
  }

  /**
   * KPN 추천 집계
   */
  async getKpnRecommendationAggregation(farmNo: number, filter?: DashboardFilterDto) {
    // 타겟 유전자 기반 KPN 추천 로직
    const targetGenes = filter?.targetGenes || [];

    // 농장 소 목록 조회
    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    // 간단한 KPN 추천 집계 (실제 로직은 더 복잡할 수 있음)
    const kpnAggregations = [
      {
        kpnNumber: 'KPN001',
        kpnName: '한우왕',
        avgMatchingScore: 85.5,
        recommendedCowCount: Math.floor(cows.length * 0.3),
        percentage: 30,
        rank: 1,
        isOwned: false,
        sampleCowIds: cows.slice(0, 3).map(c => c.cowId),
      },
      {
        kpnNumber: 'KPN002',
        kpnName: '육량대왕',
        avgMatchingScore: 82.3,
        recommendedCowCount: Math.floor(cows.length * 0.25),
        percentage: 25,
        rank: 2,
        isOwned: true,
        sampleCowIds: cows.slice(3, 6).map(c => c.cowId),
      },
      {
        kpnNumber: 'KPN003',
        kpnName: '품질명가',
        avgMatchingScore: 79.1,
        recommendedCowCount: Math.floor(cows.length * 0.2),
        percentage: 20,
        rank: 3,
        isOwned: false,
        sampleCowIds: cows.slice(6, 9).map(c => c.cowId),
      },
    ];

    return {
      farmNo,
      targetGenes,
      kpnAggregations,
      totalCows: cows.length,
    };
  }

  /**
   * 농장 보유 KPN 목록
   */
  async getFarmKpnInventory(farmNo: number) {
    // 실제 구현에서는 별도의 KPN 보유 테이블을 조회
    return {
      farmNo,
      kpnList: [
        { kpnNumber: 'KPN002', kpnName: '육량대왕', stockCount: 10 },
      ],
    };
  }

  /**
   * 분석 이력 연도 목록
   */
  async getAnalysisYears(farmNo: number): Promise<number[]> {
    const requests = await this.genomeRequestRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
      select: ['requestDt'],
    });

    const years = new Set<number>();
    for (const req of requests) {
      if (req.requestDt) {
        years.add(new Date(req.requestDt).getFullYear());
      }
    }

    return Array.from(years).sort((a, b) => b - a);
  }

  /**
   * 최신 분석 연도
   */
  async getLatestAnalysisYear(farmNo: number): Promise<number> {
    const years = await this.getAnalysisYears(farmNo);
    return years[0] || new Date().getFullYear();
  }

  /**
   * 3개년 비교 분석
   */
  async getYearComparison(farmNo: number) {
    const currentYear = new Date().getFullYear();
    const years = [currentYear, currentYear - 1, currentYear - 2];

    const comparison = [];
    for (const year of years) {
      // 해당 연도의 분석 데이터 집계
      const requests = await this.genomeRequestRepository.find({
        where: { fkFarmNo: farmNo, delDt: IsNull() },
      });

      const yearRequests = requests.filter(r => {
        if (!r.requestDt) return false;
        return new Date(r.requestDt).getFullYear() === year;
      });

      comparison.push({
        year,
        analysisCount: yearRequests.length,
        matchCount: yearRequests.filter(r => r.chipSireName === '일치').length,
      });
    }

    return { farmNo, comparison };
  }

  /**
   * 번식 효율성 분석 (더미 데이터)
   */
  async getReproEfficiency(farmNo: number, filter?: DashboardFilterDto) {
    return {
      farmNo,
      avgCalvingInterval: 12.5,
      avgFirstCalvingAge: 24,
      conceptionRate: 65.5,
    };
  }

  /**
   * 우수개체 추천
   */
  async getExcellentCows(farmNo: number, filter?: DashboardFilterDto) {
    const limit = filter?.limit || 5;

    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    const cowsWithScore: Array<{ cow: CowModel; score: number }> = [];

    for (const cow of cows) {
      // cowId로 직접 형질 데이터 조회
      const traitDetails = await this.genomeTraitDetailRepository.find({
        where: { cowId: cow.cowId, delDt: IsNull() },
      });

      if (traitDetails.length === 0) continue;

      const ebvValues = traitDetails
        .filter(d => d.traitEbv !== null)
        .map(d => Number(d.traitEbv));

      if (ebvValues.length > 0) {
        const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;
        cowsWithScore.push({ cow, score: avgEbv });
      }
    }

    // 점수 내림차순 정렬
    cowsWithScore.sort((a, b) => b.score - a.score);

    return {
      farmNo,
      excellentCows: cowsWithScore.slice(0, limit).map((item, index) => ({
        rank: index + 1,
        cowNo: item.cow.pkCowNo,
        cowId: item.cow.cowId,
        score: Math.round(item.score * 100) / 100,
      })),
    };
  }

  /**
   * 도태개체 추천
   */
  async getCullCows(farmNo: number, filter?: DashboardFilterDto) {
    const limit = filter?.limit || 5;

    const cows = await this.cowRepository.find({
      where: { fkFarmNo: farmNo, delDt: IsNull() },
    });

    const cowsWithScore: Array<{ cow: CowModel; score: number }> = [];

    for (const cow of cows) {
      // cowId로 직접 형질 데이터 조회
      const traitDetails = await this.genomeTraitDetailRepository.find({
        where: { cowId: cow.cowId, delDt: IsNull() },
      });

      if (traitDetails.length === 0) continue;

      const ebvValues = traitDetails
        .filter(d => d.traitEbv !== null)
        .map(d => Number(d.traitEbv));

      if (ebvValues.length > 0) {
        const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;
        cowsWithScore.push({ cow, score: avgEbv });
      }
    }

    // 점수 오름차순 정렬 (낮은 점수가 도태 대상)
    cowsWithScore.sort((a, b) => a.score - b.score);

    return {
      farmNo,
      cullCows: cowsWithScore.slice(0, limit).map((item, index) => ({
        rank: index + 1,
        cowNo: item.cow.pkCowNo,
        cowId: item.cow.cowId,
        score: Math.round(item.score * 100) / 100,
      })),
    };
  }

  /**
   * 보은군 내 소 개별 순위
   */
  async getCattleRankingInRegion(farmNo: number, filter?: DashboardFilterDto) {
    // 전체 소 목록과 점수 계산
    const allCows = await this.cowRepository.find({
      where: { delDt: IsNull() },
      relations: ['farm'],
    });

    const cowsWithScore: Array<{
      cow: CowModel;
      score: number;
      farmNo: number;
    }> = [];

    for (const cow of allCows) {
      // cowId로 직접 형질 데이터 조회
      const traitDetails = await this.genomeTraitDetailRepository.find({
        where: { cowId: cow.cowId, delDt: IsNull() },
      });

      if (traitDetails.length === 0) continue;

      const ebvValues = traitDetails
        .filter(d => d.traitEbv !== null)
        .map(d => Number(d.traitEbv));

      if (ebvValues.length > 0) {
        const avgEbv = ebvValues.reduce((sum, v) => sum + v, 0) / ebvValues.length;
        cowsWithScore.push({
          cow,
          score: avgEbv,
          farmNo: cow.fkFarmNo,
        });
      }
    }

    // 점수 내림차순 정렬
    cowsWithScore.sort((a, b) => b.score - a.score);

    // 순위 부여
    const rankedCows = cowsWithScore.map((item, index) => ({
      ...item,
      rank: index + 1,
      percentile: Math.round(((index + 1) / cowsWithScore.length) * 100),
    }));

    // 내 농장 소만 필터링
    const myFarmCows = rankedCows.filter(item => item.farmNo === farmNo);

    const farm = await this.farmRepository.findOne({
      where: { pkFarmNo: farmNo, delDt: IsNull() },
    });

    return {
      farmNo,
      farmName: farm?.farmerName || '농장',
      regionName: farm?.regionSi || '보은군',
      totalCattle: cowsWithScore.length,
      farmCattleCount: myFarmCows.length,
      rankings: myFarmCows.map(item => ({
        cowNo: item.cow.cowId,
        cowName: `KOR ${item.cow.cowId}`,
        genomeScore: Math.round(item.score * 100) / 100,
        rank: item.rank,
        totalCattle: cowsWithScore.length,
        percentile: item.percentile,
      })),
      statistics: {
        bestRank: myFarmCows.length > 0 ? myFarmCows[0].rank : 0,
        averageRank: myFarmCows.length > 0
          ? Math.round(myFarmCows.reduce((sum, c) => sum + c.rank, 0) / myFarmCows.length)
          : 0,
        topPercentCount: myFarmCows.filter(c => c.percentile <= 10).length,
      },
    };
  }
}
