<?php

namespace App\Services\Stats;

use App\Models\Stats\Daily\StatProductionDaily;
use App\Models\Stats\Monthly\StatProductionMonthly;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class ProductionStatService implements StatDomainServiceInterface
{
    public function aggregateDaily(int $tenantId, Carbon $date): int
    {
        $dateStr = $date->format('Y-m-d');

        // 작업지시 (work_orders)
        $woCreated = DB::connection('mysql')
            ->table('work_orders')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->whereNull('deleted_at')
            ->count();

        $woCompleted = DB::connection('mysql')
            ->table('work_orders')
            ->where('tenant_id', $tenantId)
            ->whereDate('completed_at', $dateStr)
            ->whereNull('deleted_at')
            ->count();

        $woInProgress = DB::connection('mysql')
            ->table('work_orders')
            ->where('tenant_id', $tenantId)
            ->where('status', 'in_progress')
            ->whereNull('deleted_at')
            ->count();

        // 납기 초과 (scheduled_date < today && status not completed/shipped)
        $woOverdue = DB::connection('mysql')
            ->table('work_orders')
            ->where('tenant_id', $tenantId)
            ->where('scheduled_date', '<', $dateStr)
            ->whereNotIn('status', ['completed', 'shipped', 'cancelled'])
            ->whereNull('deleted_at')
            ->count();

        // 생산 실적 (work_results)
        $productionStats = DB::connection('mysql')
            ->table('work_results')
            ->where('tenant_id', $tenantId)
            ->where('work_date', $dateStr)
            ->whereNull('deleted_at')
            ->selectRaw('
                COALESCE(SUM(production_qty), 0) as production_qty,
                COALESCE(SUM(defect_qty), 0) as defect_qty,
                COUNT(DISTINCT worker_id) as active_worker_count
            ')
            ->first();

        $productionQty = $productionStats->production_qty ?? 0;
        $defectQty = $productionStats->defect_qty ?? 0;
        $defectRate = $productionQty > 0 ? ($defectQty / $productionQty) * 100 : 0;

        // 납기 준수 (당일 완료된 작업지시 중 scheduled_date >= completed_at인 것)
        $onTimeCount = DB::connection('mysql')
            ->table('work_orders')
            ->where('tenant_id', $tenantId)
            ->whereDate('completed_at', $dateStr)
            ->whereNull('deleted_at')
            ->whereRaw('DATE(completed_at) <= scheduled_date')
            ->count();

        $lateCount = $woCompleted - $onTimeCount;
        $deliveryRate = $woCompleted > 0 ? ($onTimeCount / $woCompleted) * 100 : 0;

        StatProductionDaily::updateOrCreate(
            ['tenant_id' => $tenantId, 'stat_date' => $dateStr],
            [
                'wo_created_count' => $woCreated,
                'wo_completed_count' => $woCompleted,
                'wo_in_progress_count' => $woInProgress,
                'wo_overdue_count' => $woOverdue,
                'production_qty' => $productionQty,
                'defect_qty' => $defectQty,
                'defect_rate' => round($defectRate, 2),
                'planned_hours' => 0, // 계획 공수 필드 없음 - 추후 확장
                'actual_hours' => 0,
                'efficiency_rate' => 0,
                'active_worker_count' => $productionStats->active_worker_count ?? 0,
                'issue_count' => 0, // work_order_issues 테이블 확인 필요
                'on_time_delivery_count' => $onTimeCount,
                'late_delivery_count' => max(0, $lateCount),
                'delivery_rate' => round($deliveryRate, 2),
            ]
        );

        return 1;
    }

    public function aggregateMonthly(int $tenantId, int $year, int $month): int
    {
        $dailyData = StatProductionDaily::where('tenant_id', $tenantId)
            ->whereYear('stat_date', $year)
            ->whereMonth('stat_date', $month)
            ->selectRaw('
                SUM(wo_created_count) as wo_total_count,
                SUM(wo_completed_count) as wo_completed_count,
                SUM(production_qty) as production_qty,
                SUM(defect_qty) as defect_qty,
                SUM(planned_hours) as total_planned_hours,
                SUM(actual_hours) as total_actual_hours,
                SUM(issue_count) as issue_total_count
            ')
            ->first();

        $productionQty = $dailyData->production_qty ?? 0;
        $defectQty = $dailyData->defect_qty ?? 0;
        $avgDefectRate = $productionQty > 0 ? ($defectQty / $productionQty) * 100 : 0;

        // 월평균 효율/납기 (일간 데이터의 평균)
        $avgRates = StatProductionDaily::where('tenant_id', $tenantId)
            ->whereYear('stat_date', $year)
            ->whereMonth('stat_date', $month)
            ->where('wo_completed_count', '>', 0)
            ->selectRaw('
                AVG(efficiency_rate) as avg_efficiency_rate,
                AVG(delivery_rate) as avg_delivery_rate
            ')
            ->first();

        StatProductionMonthly::updateOrCreate(
            ['tenant_id' => $tenantId, 'stat_year' => $year, 'stat_month' => $month],
            [
                'wo_total_count' => $dailyData->wo_total_count ?? 0,
                'wo_completed_count' => $dailyData->wo_completed_count ?? 0,
                'production_qty' => $productionQty,
                'defect_qty' => $defectQty,
                'avg_defect_rate' => round($avgDefectRate, 2),
                'avg_efficiency_rate' => round($avgRates->avg_efficiency_rate ?? 0, 2),
                'avg_delivery_rate' => round($avgRates->avg_delivery_rate ?? 0, 2),
                'total_planned_hours' => $dailyData->total_planned_hours ?? 0,
                'total_actual_hours' => $dailyData->total_actual_hours ?? 0,
                'issue_total_count' => $dailyData->issue_total_count ?? 0,
            ]
        );

        return 1;
    }
}
