<?php

namespace App\Services\Stats;

use App\Models\Stats\Daily\StatSalesDaily;
use App\Models\Stats\Monthly\StatSalesMonthly;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

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

        // 수주 집계 (orders)
        $orderStats = DB::connection('mysql')
            ->table('orders')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->whereNull('deleted_at')
            ->selectRaw('
                COUNT(*) as order_count,
                COALESCE(SUM(total_amount), 0) as order_amount,
                COALESCE(SUM(quantity), 0) as order_item_count,
                SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as order_draft_count,
                SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as order_confirmed_count,
                SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as order_in_progress_count,
                SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as order_completed_count,
                SUM(CASE WHEN status_code = ? THEN 1 ELSE 0 END) as order_cancelled_count
            ', ['draft', 'confirmed', 'in_progress', 'completed', 'cancelled'])
            ->first();

        // 매출 집계 (sales)
        $salesStats = DB::connection('mysql')
            ->table('sales')
            ->where('tenant_id', $tenantId)
            ->where('sale_date', $dateStr)
            ->whereNull('deleted_at')
            ->selectRaw('
                COUNT(*) as sales_count,
                COALESCE(SUM(supply_amount), 0) as sales_amount,
                COALESCE(SUM(tax_amount), 0) as sales_tax_amount
            ')
            ->first();

        // 신규 고객 (당일 생성된 고객)
        $newClientCount = DB::connection('mysql')
            ->table('clients')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->count();

        // 활성 고객 (당일 수주/매출에 연결된 고유 고객)
        $activeClientCount = DB::connection('mysql')
            ->table('orders')
            ->where('tenant_id', $tenantId)
            ->whereDate('created_at', $dateStr)
            ->whereNull('deleted_at')
            ->whereNotNull('client_id')
            ->distinct('client_id')
            ->count('client_id');

        // 출하 집계 (shipments)
        $shipmentStats = DB::connection('mysql')
            ->table('shipments')
            ->where('tenant_id', $tenantId)
            ->where('scheduled_date', $dateStr)
            ->where('status', 'completed')
            ->whereNull('deleted_at')
            ->selectRaw('
                COUNT(*) as shipment_count,
                COALESCE(SUM(shipping_cost), 0) as shipment_amount
            ')
            ->first();

        StatSalesDaily::updateOrCreate(
            ['tenant_id' => $tenantId, 'stat_date' => $dateStr],
            [
                'order_count' => $orderStats->order_count ?? 0,
                'order_amount' => $orderStats->order_amount ?? 0,
                'order_item_count' => $orderStats->order_item_count ?? 0,
                'sales_count' => $salesStats->sales_count ?? 0,
                'sales_amount' => $salesStats->sales_amount ?? 0,
                'sales_tax_amount' => $salesStats->sales_tax_amount ?? 0,
                'new_client_count' => $newClientCount,
                'active_client_count' => $activeClientCount,
                'order_draft_count' => $orderStats->order_draft_count ?? 0,
                'order_confirmed_count' => $orderStats->order_confirmed_count ?? 0,
                'order_in_progress_count' => $orderStats->order_in_progress_count ?? 0,
                'order_completed_count' => $orderStats->order_completed_count ?? 0,
                'order_cancelled_count' => $orderStats->order_cancelled_count ?? 0,
                'shipment_count' => $shipmentStats->shipment_count ?? 0,
                'shipment_amount' => $shipmentStats->shipment_amount ?? 0,
            ]
        );

        return 1;
    }

    public function aggregateMonthly(int $tenantId, int $year, int $month): int
    {
        // 일간 데이터를 합산하여 월간 통계 생성
        $dailySum = StatSalesDaily::where('tenant_id', $tenantId)
            ->whereYear('stat_date', $year)
            ->whereMonth('stat_date', $month)
            ->selectRaw('
                SUM(order_count) as order_count,
                SUM(order_amount) as order_amount,
                SUM(sales_count) as sales_count,
                SUM(sales_amount) as sales_amount,
                SUM(shipment_count) as shipment_count,
                SUM(shipment_amount) as shipment_amount
            ')
            ->first();

        // 월간 고유 거래 고객 수
        $startDate = Carbon::create($year, $month, 1)->format('Y-m-d');
        $endDate = Carbon::create($year, $month, 1)->endOfMonth()->format('Y-m-d');

        $uniqueClientCount = DB::connection('mysql')
            ->table('orders')
            ->where('tenant_id', $tenantId)
            ->whereBetween(DB::raw('DATE(created_at)'), [$startDate, $endDate])
            ->whereNull('deleted_at')
            ->whereNotNull('client_id')
            ->distinct('client_id')
            ->count('client_id');

        // 평균 수주 금액
        $orderCount = $dailySum->order_count ?? 0;
        $orderAmount = $dailySum->order_amount ?? 0;
        $avgOrderAmount = $orderCount > 0 ? $orderAmount / $orderCount : 0;

        // 최다 거래 고객
        $topClient = DB::connection('mysql')
            ->table('orders')
            ->where('tenant_id', $tenantId)
            ->whereBetween(DB::raw('DATE(created_at)'), [$startDate, $endDate])
            ->whereNull('deleted_at')
            ->whereNotNull('client_id')
            ->groupBy('client_id')
            ->orderByRaw('SUM(total_amount) DESC')
            ->selectRaw('client_id, SUM(total_amount) as total')
            ->first();

        // 전월 대비 성장률
        $prevMonth = StatSalesMonthly::where('tenant_id', $tenantId)
            ->where(function ($q) use ($year, $month) {
                $prev = Carbon::create($year, $month, 1)->subMonth();
                $q->where('stat_year', $prev->year)->where('stat_month', $prev->month);
            })
            ->first();

        $salesAmount = $dailySum->sales_amount ?? 0;
        $momGrowthRate = null;
        if ($prevMonth && $prevMonth->sales_amount > 0) {
            $momGrowthRate = (($salesAmount - $prevMonth->sales_amount) / $prevMonth->sales_amount) * 100;
        }

        // 전년동월 대비
        $prevYear = StatSalesMonthly::where('tenant_id', $tenantId)
            ->where('stat_year', $year - 1)
            ->where('stat_month', $month)
            ->first();

        $yoyGrowthRate = null;
        if ($prevYear && $prevYear->sales_amount > 0) {
            $yoyGrowthRate = (($salesAmount - $prevYear->sales_amount) / $prevYear->sales_amount) * 100;
        }

        StatSalesMonthly::updateOrCreate(
            ['tenant_id' => $tenantId, 'stat_year' => $year, 'stat_month' => $month],
            [
                'order_count' => $dailySum->order_count ?? 0,
                'order_amount' => $orderAmount,
                'sales_count' => $dailySum->sales_count ?? 0,
                'sales_amount' => $salesAmount,
                'shipment_count' => $dailySum->shipment_count ?? 0,
                'shipment_amount' => $dailySum->shipment_amount ?? 0,
                'unique_client_count' => $uniqueClientCount,
                'avg_order_amount' => $avgOrderAmount,
                'top_client_id' => $topClient->client_id ?? null,
                'top_client_amount' => $topClient->total ?? 0,
                'mom_growth_rate' => $momGrowthRate,
                'yoy_growth_rate' => $yoyGrowthRate,
            ]
        );

        return 1;
    }
}
