<?php

namespace App\Services;

use App\Models\Qualitys\PerformanceReport;
use App\Services\Audit\AuditLogger;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class PerformanceReportService extends Service
{
    private const AUDIT_TARGET = 'performance_report';

    public function __construct(
        private readonly AuditLogger $auditLogger,
        private readonly QualityDocumentService $qualityDocumentService
    ) {}

    /**
     * 목록 조회
     */
    public function index(array $params)
    {
        $tenantId = $this->tenantId();
        $perPage = (int) ($params['per_page'] ?? 20);
        $q = trim((string) ($params['q'] ?? ''));
        $year = $params['year'] ?? null;
        $quarter = $params['quarter'] ?? null;
        $confirmStatus = $params['confirm_status'] ?? null;

        $query = PerformanceReport::query()
            ->where('performance_reports.tenant_id', $tenantId)
            ->with(['qualityDocument.client', 'qualityDocument.locations', 'confirmer:id,name']);

        if ($q !== '') {
            $query->whereHas('qualityDocument', function ($qq) use ($q) {
                $qq->where('quality_doc_number', 'like', "%{$q}%")
                    ->orWhere('site_name', 'like', "%{$q}%");
            });
        }

        if ($year !== null) {
            $query->where('year', $year);
        }
        if ($quarter !== null) {
            $query->where('quarter', $quarter);
        }
        if ($confirmStatus !== null) {
            $query->where('confirmation_status', $confirmStatus);
        }

        $query->orderByDesc('performance_reports.id');
        $paginated = $query->paginate($perPage);

        $transformedData = $paginated->getCollection()->map(fn ($report) => $this->transformToFrontend($report));

        return [
            'items' => $transformedData,
            'current_page' => $paginated->currentPage(),
            'last_page' => $paginated->lastPage(),
            'per_page' => $paginated->perPage(),
            'total' => $paginated->total(),
        ];
    }

    /**
     * 통계 조회
     */
    public function stats(array $params = []): array
    {
        $tenantId = $this->tenantId();

        $query = PerformanceReport::where('performance_reports.tenant_id', $tenantId);

        if (! empty($params['year'])) {
            $query->where('performance_reports.year', $params['year']);
        }
        if (! empty($params['quarter'])) {
            $query->where('performance_reports.quarter', $params['quarter']);
        }

        $counts = (clone $query)
            ->select('confirmation_status', DB::raw('count(*) as count'))
            ->groupBy('confirmation_status')
            ->pluck('count', 'confirmation_status')
            ->toArray();

        $totalLocations = (clone $query)
            ->join('quality_documents', 'quality_documents.id', '=', 'performance_reports.quality_document_id')
            ->join('quality_document_locations', 'quality_document_locations.quality_document_id', '=', 'quality_documents.id')
            ->count('quality_document_locations.id');

        return [
            'total_count' => array_sum($counts),
            'confirmed_count' => $counts[PerformanceReport::STATUS_CONFIRMED] ?? 0,
            'unconfirmed_count' => $counts[PerformanceReport::STATUS_UNCONFIRMED] ?? 0,
            'total_locations' => $totalLocations,
        ];
    }

    /**
     * 일괄 확정
     */
    public function confirm(array $ids)
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($ids, $tenantId, $userId) {
            $reports = PerformanceReport::where('tenant_id', $tenantId)
                ->whereIn('id', $ids)
                ->with(['qualityDocument'])
                ->get();

            $errors = [];
            foreach ($reports as $report) {
                if ($report->isConfirmed() || $report->isReported()) {
                    continue;
                }

                // 필수정보 검증
                $requiredInfo = $this->qualityDocumentService->calculateRequiredInfo($report->qualityDocument);
                if ($requiredInfo !== '완료') {
                    $errors[] = [
                        'id' => $report->id,
                        'quality_doc_number' => $report->qualityDocument->quality_doc_number,
                        'reason' => $requiredInfo,
                    ];

                    continue;
                }

                $report->update([
                    'confirmation_status' => PerformanceReport::STATUS_CONFIRMED,
                    'confirmed_date' => now()->toDateString(),
                    'confirmed_by' => $userId,
                    'updated_by' => $userId,
                ]);
            }

            if (! empty($errors)) {
                throw new BadRequestHttpException(json_encode([
                    'message' => __('error.quality.confirm_failed'),
                    'errors' => $errors,
                ]));
            }

            return ['confirmed_count' => count($ids) - count($errors)];
        });
    }

    /**
     * 일괄 확정 해제
     */
    public function unconfirm(array $ids)
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        return DB::transaction(function () use ($ids, $tenantId, $userId) {
            PerformanceReport::where('tenant_id', $tenantId)
                ->whereIn('id', $ids)
                ->where('confirmation_status', PerformanceReport::STATUS_CONFIRMED)
                ->update([
                    'confirmation_status' => PerformanceReport::STATUS_UNCONFIRMED,
                    'confirmed_date' => null,
                    'confirmed_by' => null,
                    'updated_by' => $userId,
                ]);

            return ['unconfirmed_count' => count($ids)];
        });
    }

    /**
     * 일괄 메모 업데이트
     */
    public function updateMemo(array $ids, string $memo)
    {
        $tenantId = $this->tenantId();
        $userId = $this->apiUserId();

        PerformanceReport::where('tenant_id', $tenantId)
            ->whereIn('id', $ids)
            ->update([
                'memo' => $memo,
                'updated_by' => $userId,
            ]);

        return ['updated_count' => count($ids)];
    }

    /**
     * 누락체크 (출고완료 but 제품검사 미등록)
     */
    public function missing(array $params): array
    {
        $tenantId = $this->tenantId();

        // 품질관리서가 등록된 수주 ID
        $registeredOrderIds = DB::table('quality_document_orders')
            ->join('quality_documents', 'quality_documents.id', '=', 'quality_document_orders.quality_document_id')
            ->where('quality_documents.tenant_id', $tenantId)
            ->pluck('quality_document_orders.order_id');

        // 출고완료 상태이지만 품질관리서 미등록 수주
        $query = DB::table('orders')
            ->where('tenant_id', $tenantId)
            ->whereNotIn('id', $registeredOrderIds)
            ->where('status_code', 'SHIPPED'); // TODO: 출고완료 상태 추가 시 상수 확인

        if (! empty($params['year'])) {
            $query->whereYear('created_at', $params['year']);
        }
        if (! empty($params['quarter'])) {
            $quarter = (int) $params['quarter'];
            $startMonth = ($quarter - 1) * 3 + 1;
            $endMonth = $quarter * 3;
            $query->whereMonth('created_at', '>=', $startMonth)
                ->whereMonth('created_at', '<=', $endMonth);
        }

        return $query->orderByDesc('id')
            ->limit(100)
            ->get()
            ->map(fn ($order) => [
                'id' => $order->id,
                'order_number' => $order->order_no ?? '',
                'site_name' => $order->site_name ?? '',
                'client' => '', // 별도 조인 필요
                'delivery_date' => $order->delivery_date ?? '',
            ])
            ->toArray();
    }

    /**
     * DB → 프론트엔드 변환
     */
    private function transformToFrontend(PerformanceReport $report): array
    {
        $doc = $report->qualityDocument;

        return [
            'id' => $report->id,
            'quality_doc_number' => $doc?->quality_doc_number ?? '',
            'created_date' => $report->created_at?->format('Y-m-d') ?? '',
            'site_name' => $doc?->site_name ?? '',
            'client' => $doc?->client?->name ?? '',
            'location_count' => $doc?->locations?->count() ?? 0,
            'required_info' => $doc ? $this->qualityDocumentService->calculateRequiredInfo($doc) : '',
            'confirm_status' => $report->confirmation_status === PerformanceReport::STATUS_CONFIRMED ? 'confirmed' : 'unconfirmed',
            'confirm_date' => $report->confirmed_date?->format('Y-m-d'),
            'memo' => $report->memo ?? '',
            'year' => $report->year,
            'quarter' => $report->quarter,
        ];
    }
}
