-- 007_create_monthly_worker_status.sql
-- 월별 작업자 상태 집계 테이블 생성

-- 월별 작업자 상태 집계 테이블
CREATE TABLE IF NOT EXISTS monthly_worker_status (
    id INT PRIMARY KEY AUTO_INCREMENT,
    year INT NOT NULL COMMENT '연도',
    month INT NOT NULL COMMENT '월 (1-12)',
    worker_id INT NOT NULL COMMENT '작업자 ID',
    date DATE NOT NULL COMMENT '날짜',
    
    -- 작업 시간 정보
    total_work_hours DECIMAL(5,2) DEFAULT 0.00 COMMENT '총 작업시간',
    actual_work_hours DECIMAL(5,2) DEFAULT 0.00 COMMENT '실제 작업시간 (휴가 제외)',
    vacation_hours DECIMAL(5,2) DEFAULT 0.00 COMMENT '휴가 시간',
    
    -- 작업 건수
    total_work_count INT DEFAULT 0 COMMENT '총 작업 건수',
    regular_work_count INT DEFAULT 0 COMMENT '정규 작업 건수',
    error_work_count INT DEFAULT 0 COMMENT '오류 작업 건수',
    
    -- 상태 정보
    work_status ENUM(
        'incomplete',      -- 미입력 (0시간)
        'partial',         -- 부분입력 (8시간 미만)
        'complete',        -- 정시근로 (8시간)
        'overtime',        -- 연장근로 (8시간 초과)
        'vacation-full',   -- 연차 (8시간)
        'vacation-half',   -- 반차 (4시간)
        'vacation-quarter',-- 반반차 (2시간)
        'vacation-half-half', -- 조퇴 (6시간)
        'error',           -- 오류 발생
        'overtime-warning' -- 초과근무 확인필요 (12시간 초과)
    ) NOT NULL DEFAULT 'incomplete' COMMENT '작업 상태',
    
    has_vacation BOOLEAN DEFAULT FALSE COMMENT '휴가 여부',
    has_error BOOLEAN DEFAULT FALSE COMMENT '오류 여부',
    has_issues BOOLEAN DEFAULT FALSE COMMENT '문제 여부 (미입력/부분입력)',
    
    -- 메타 정보
    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '마지막 업데이트 시간',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    -- 인덱스
    UNIQUE KEY unique_worker_date (worker_id, date),
    KEY idx_year_month (year, month),
    KEY idx_worker_year_month (worker_id, year, month),
    KEY idx_status (work_status),
    KEY idx_has_issues (has_issues),
    KEY idx_has_error (has_error),
    
    -- 외래키
    FOREIGN KEY (worker_id) REFERENCES workers(worker_id) ON DELETE CASCADE
) COMMENT='월별 작업자 상태 집계 테이블';

-- 월별 집계 요약 테이블 (캘린더 최적화용)
CREATE TABLE IF NOT EXISTS monthly_summary (
    id INT PRIMARY KEY AUTO_INCREMENT,
    year INT NOT NULL COMMENT '연도',
    month INT NOT NULL COMMENT '월 (1-12)',
    date DATE NOT NULL COMMENT '날짜',
    
    -- 작업자 수
    total_workers INT DEFAULT 0 COMMENT '총 작업자 수',
    working_workers INT DEFAULT 0 COMMENT '작업한 작업자 수',
    
    -- 상태별 작업자 수
    incomplete_workers INT DEFAULT 0 COMMENT '미입력 작업자 수',
    partial_workers INT DEFAULT 0 COMMENT '부분입력 작업자 수',
    complete_workers INT DEFAULT 0 COMMENT '완료 작업자 수',
    overtime_workers INT DEFAULT 0 COMMENT '연장근로 작업자 수',
    vacation_workers INT DEFAULT 0 COMMENT '휴가 작업자 수',
    error_workers INT DEFAULT 0 COMMENT '오류 작업자 수',
    
    -- 집계 정보
    total_work_hours DECIMAL(8,2) DEFAULT 0.00 COMMENT '총 작업시간',
    total_work_count INT DEFAULT 0 COMMENT '총 작업 건수',
    total_error_count INT DEFAULT 0 COMMENT '총 오류 건수',
    
    -- 상태 플래그 (캘린더 표시용)
    has_issues BOOLEAN DEFAULT FALSE COMMENT '문제 있음 (미입력/부분입력)',
    has_errors BOOLEAN DEFAULT FALSE COMMENT '오류 있음',
    
    -- 메타 정보
    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    -- 인덱스
    UNIQUE KEY unique_date (date),
    KEY idx_year_month (year, month),
    KEY idx_has_issues (has_issues),
    KEY idx_has_errors (has_errors)
) COMMENT='월별 일자별 요약 테이블 (캘린더 최적화용)';

-- 집계 데이터 업데이트 함수
DELIMITER $$

CREATE OR REPLACE PROCEDURE UpdateMonthlyWorkerStatus(
    IN p_date DATE,
    IN p_worker_id INT
)
BEGIN
    DECLARE v_year INT;
    DECLARE v_month INT;
    DECLARE v_total_hours DECIMAL(5,2);
    DECLARE v_actual_hours DECIMAL(5,2);
    DECLARE v_vacation_hours DECIMAL(5,2);
    DECLARE v_total_count INT;
    DECLARE v_regular_count INT;
    DECLARE v_error_count INT;
    DECLARE v_has_vacation BOOLEAN;
    DECLARE v_has_error BOOLEAN;
    DECLARE v_has_issues BOOLEAN;
    DECLARE v_status VARCHAR(20);
    
    -- 연도, 월 추출
    SET v_year = YEAR(p_date);
    SET v_month = MONTH(p_date);
    
    -- 해당 날짜의 작업자 데이터 집계
    SELECT 
        COALESCE(SUM(work_hours), 0),
        COALESCE(SUM(CASE WHEN project_id != 13 THEN work_hours ELSE 0 END), 0),
        COALESCE(SUM(CASE WHEN project_id = 13 THEN work_hours ELSE 0 END), 0),
        COUNT(*),
        COUNT(CASE WHEN project_id != 13 AND work_status_id != 2 THEN 1 END),
        COUNT(CASE WHEN work_status_id = 2 THEN 1 END),
        MAX(CASE WHEN project_id = 13 THEN 1 ELSE 0 END),
        MAX(CASE WHEN work_status_id = 2 THEN 1 ELSE 0 END)
    INTO 
        v_total_hours, v_actual_hours, v_vacation_hours,
        v_total_count, v_regular_count, v_error_count,
        v_has_vacation, v_has_error
    FROM daily_work_reports 
    WHERE report_date = p_date AND worker_id = p_worker_id;
    
    -- 상태 결정 로직
    IF v_has_error THEN
        SET v_status = 'error';
        SET v_has_issues = FALSE;
    ELSEIF v_total_hours > 12 THEN
        SET v_status = 'overtime-warning';
        SET v_has_issues = TRUE;
    ELSEIF v_has_vacation AND v_vacation_hours > 0 THEN
        -- 휴가 상태 결정
        CASE v_vacation_hours
            WHEN 8 THEN SET v_status = 'vacation-full';
            WHEN 6 THEN SET v_status = 'vacation-half-half';
            WHEN 4 THEN SET v_status = 'vacation-half';
            WHEN 2 THEN SET v_status = 'vacation-quarter';
            ELSE SET v_status = 'vacation-full';
        END CASE;
        SET v_has_issues = FALSE;
    ELSEIF v_total_hours > 8 THEN
        SET v_status = 'overtime';
        SET v_has_issues = FALSE;
    ELSEIF v_total_hours = 8 THEN
        SET v_status = 'complete';
        SET v_has_issues = FALSE;
    ELSEIF v_total_hours > 0 THEN
        SET v_status = 'partial';
        SET v_has_issues = TRUE;
    ELSE
        SET v_status = 'incomplete';
        SET v_has_issues = TRUE;
    END IF;
    
    -- 데이터 업서트
    INSERT INTO monthly_worker_status (
        year, month, worker_id, date,
        total_work_hours, actual_work_hours, vacation_hours,
        total_work_count, regular_work_count, error_work_count,
        work_status, has_vacation, has_error, has_issues
    ) VALUES (
        v_year, v_month, p_worker_id, p_date,
        v_total_hours, v_actual_hours, v_vacation_hours,
        v_total_count, v_regular_count, v_error_count,
        v_status, v_has_vacation, v_has_error, v_has_issues
    ) ON DUPLICATE KEY UPDATE
        total_work_hours = v_total_hours,
        actual_work_hours = v_actual_hours,
        vacation_hours = v_vacation_hours,
        total_work_count = v_total_count,
        regular_work_count = v_regular_count,
        error_work_count = v_error_count,
        work_status = v_status,
        has_vacation = v_has_vacation,
        has_error = v_has_error,
        has_issues = v_has_issues,
        last_updated = CURRENT_TIMESTAMP;
        
    -- 일별 요약도 업데이트
    CALL UpdateDailySummary(p_date);
END$$

-- 일별 요약 업데이트 함수
CREATE OR REPLACE PROCEDURE UpdateDailySummary(
    IN p_date DATE
)
BEGIN
    DECLARE v_year INT;
    DECLARE v_month INT;
    
    SET v_year = YEAR(p_date);
    SET v_month = MONTH(p_date);
    
    INSERT INTO monthly_summary (
        year, month, date,
        total_workers, working_workers,
        incomplete_workers, partial_workers, complete_workers,
        overtime_workers, vacation_workers, error_workers,
        total_work_hours, total_work_count, total_error_count,
        has_issues, has_errors
    )
    SELECT 
        v_year, v_month, p_date,
        COUNT(*) as total_workers,
        COUNT(CASE WHEN work_status != 'incomplete' THEN 1 END) as working_workers,
        COUNT(CASE WHEN work_status = 'incomplete' THEN 1 END) as incomplete_workers,
        COUNT(CASE WHEN work_status = 'partial' THEN 1 END) as partial_workers,
        COUNT(CASE WHEN work_status IN ('complete') THEN 1 END) as complete_workers,
        COUNT(CASE WHEN work_status = 'overtime' THEN 1 END) as overtime_workers,
        COUNT(CASE WHEN work_status LIKE 'vacation%' THEN 1 END) as vacation_workers,
        COUNT(CASE WHEN work_status = 'error' THEN 1 END) as error_workers,
        SUM(total_work_hours) as total_work_hours,
        SUM(total_work_count) as total_work_count,
        SUM(error_work_count) as total_error_count,
        MAX(has_issues) as has_issues,
        MAX(has_error) as has_errors
    FROM monthly_worker_status 
    WHERE date = p_date
    ON DUPLICATE KEY UPDATE
        total_workers = VALUES(total_workers),
        working_workers = VALUES(working_workers),
        incomplete_workers = VALUES(incomplete_workers),
        partial_workers = VALUES(partial_workers),
        complete_workers = VALUES(complete_workers),
        overtime_workers = VALUES(overtime_workers),
        vacation_workers = VALUES(vacation_workers),
        error_workers = VALUES(error_workers),
        total_work_hours = VALUES(total_work_hours),
        total_work_count = VALUES(total_work_count),
        total_error_count = VALUES(total_error_count),
        has_issues = VALUES(has_issues),
        has_errors = VALUES(has_errors),
        last_updated = CURRENT_TIMESTAMP;
END$$

DELIMITER ;
