/**
 * Work Analysis Service
 *
 * Handles complex business logic and data aggregation for detailed work analysis reports
 *
 * @author TK-FB-Project
 * @since 2025-12-19
 */

const { getDb } = require('../dbPool');
const WorkAnalysis = require('../models/WorkAnalysis');
const logger = require('../utils/logger');
const { DatabaseError } = require('../utils/errors');

class WorkAnalysisService {
    constructor() {
        this.db = null;
        this.model = null;
    }

    async init() {
        if (!this.db) {
            this.db = await getDb();
            this.model = new WorkAnalysis(this.db);
        }
    }

    /**
     * 프로젝트별-작업별 시간 분석 및 집계 (Service Layer logic)
     */
    async getProjectWorkTypeAnalysis(startDate, endDate) {
        await this.init();

        try {
            // 1. Get Raw Data from Model
            const rawData = await this.model.getProjectWorkTypeRawData(startDate, endDate);

            // 2. Process and Group Data
            const groupedData = {};

            rawData.forEach(row => {
                const projectKey = `${row.project_id}_${row.project_name}`;

                if (!groupedData[projectKey]) {
                    groupedData[projectKey] = {
                        project_id: row.project_id,
                        project_name: row.project_name,
                        job_no: row.job_no,
                        total_project_hours: 0,
                        total_regular_hours: 0,
                        total_error_hours: 0,
                        work_types: []
                    };
                }

                // Project Totals Accumulation
                groupedData[projectKey].total_project_hours += parseFloat(row.total_hours);
                groupedData[projectKey].total_regular_hours += parseFloat(row.regular_hours);
                groupedData[projectKey].total_error_hours += parseFloat(row.error_hours);

                // Add WorkType Entry
                groupedData[projectKey].work_types.push({
                    work_type_id: row.work_type_id,
                    work_type_name: row.work_type_name,
                    total_hours: parseFloat(row.total_hours),
                    regular_hours: parseFloat(row.regular_hours),
                    error_hours: parseFloat(row.error_hours),
                    total_reports: row.total_reports,
                    regular_reports: row.regular_reports,
                    error_reports: row.error_reports,
                    error_rate_percent: parseFloat(row.error_rate_percent) || 0
                });
            });

            // 3. Calculate Project Error Rates
            Object.values(groupedData).forEach(project => {
                project.project_error_rate = project.total_project_hours > 0
                    ? Math.round((project.total_error_hours / project.total_project_hours) * 100 * 100) / 100
                    : 0;
            });

            // 4. Calculate Grand Totals
            const totalStats = {
                total_projects: Object.keys(groupedData).length,
                total_work_types: new Set(rawData.map(r => r.work_type_id)).size,
                grand_total_hours: Object.values(groupedData).reduce((sum, p) => sum + p.total_project_hours, 0),
                grand_regular_hours: Object.values(groupedData).reduce((sum, p) => sum + p.total_regular_hours, 0),
                grand_error_hours: Object.values(groupedData).reduce((sum, p) => sum + p.total_error_hours, 0)
            };

            totalStats.grand_error_rate = totalStats.grand_total_hours > 0
                ? Math.round((totalStats.grand_error_hours / totalStats.grand_total_hours) * 100 * 100) / 100
                : 0;

            return {
                summary: totalStats,
                projects: Object.values(groupedData),
                period: { start: startDate, end: endDate }
            };

        } catch (error) {
            logger.error('Service: 프로젝트별-작업별 시간 분석 처리 실패', { error: error.message });
            // Re-throw as DatabaseError to maintain consistency with controller expectation, or custom ServiceError
            throw new DatabaseError(`분석 데이터 처리 중 오류 발생: ${error.message}`);
        }
    }
}

module.exports = new WorkAnalysisService();
