<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\Documents\Document;
use App\Models\Documents\DocumentApproval;
use App\Models\Documents\DocumentData;
use App\Models\DocumentTemplate;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class DocumentApiController extends Controller
{
    /**
     * 문서 목록 조회
     */
    public function index(Request $request): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        // 슈퍼관리자 휴지통 조회
        $showTrashed = $request->filled('trashed') && auth()->user()?->is_super_admin;

        $query = Document::with(['template', 'creator'])
            ->where('tenant_id', $tenantId)
            ->orderBy('created_at', 'desc');

        if ($showTrashed) {
            $query->onlyTrashed();
        }

        // 상태 필터
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // 양식분류 필터
        if ($request->filled('category')) {
            $category = $request->category;
            $query->whereHas('template', function ($q) use ($category) {
                $q->where('category', $category);
            });
        }

        // 템플릿 필터
        if ($request->filled('template_id')) {
            $query->where('template_id', $request->template_id);
        }

        // 검색
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('document_no', 'like', "%{$search}%")
                    ->orWhere('title', 'like', "%{$search}%");
            });
        }

        // 날짜 범위 필터
        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        $documents = $query->paginate($request->input('per_page', 15));

        return response()->json($documents);
    }

    /**
     * 문서 상세 조회
     */
    public function show(int $id): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        $document = Document::with([
            'template.approvalLines',
            'template.basicFields',
            'template.sections.items',
            'template.columns',
            'approvals.user',
            'data',
            'attachments.file',
            'creator',
            'updater',
        ])->where('tenant_id', $tenantId)->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $document,
        ]);
    }

    /**
     * 문서 생성
     */
    public function store(Request $request): JsonResponse
    {
        $tenantId = session('selected_tenant_id');
        $userId = auth()->id();

        $request->validate([
            'template_id' => 'required|exists:document_templates,id',
            'title' => 'required|string|max:255',
            'data' => 'nullable|array',
            'data.*.field_key' => 'required|string',
            'data.*.field_value' => 'nullable|string',
            'data.*.section_id' => 'nullable|integer',
            'data.*.column_id' => 'nullable|integer',
            'data.*.row_index' => 'nullable|integer',
        ]);

        try {
            DB::beginTransaction();

            // 문서 번호 생성
            $documentNo = $this->generateDocumentNo($tenantId, $request->template_id);

            $document = Document::create([
                'tenant_id' => $tenantId,
                'template_id' => $request->template_id,
                'document_no' => $documentNo,
                'title' => $request->title,
                'status' => Document::STATUS_DRAFT,
                'created_by' => $userId,
                'updated_by' => $userId,
            ]);

            // 결재라인 초기화 (템플릿의 approvalLines 기반)
            $template = DocumentTemplate::with('approvalLines')->find($request->template_id);
            if ($template && $template->approvalLines->isNotEmpty()) {
                foreach ($template->approvalLines as $line) {
                    DocumentApproval::create([
                        'document_id' => $document->id,
                        'user_id' => $userId,
                        'step' => $line->sort_order + 1,
                        'role' => $line->role ?? $line->name,
                        'status' => DocumentApproval::STATUS_PENDING,
                        'created_by' => $userId,
                        'updated_by' => $userId,
                    ]);
                }
            }

            // 문서 데이터 저장 (기본필드 + 섹션 테이블 데이터)
            $this->saveDocumentData($document, $request->input('data', []));

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => '문서가 저장되었습니다.',
                'data' => $document->fresh(['template', 'data', 'approvals']),
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => '문서 생성 중 오류가 발생했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 문서 수정
     */
    public function update(int $id, Request $request): JsonResponse
    {
        $tenantId = session('selected_tenant_id');
        $userId = auth()->id();

        $document = Document::where('tenant_id', $tenantId)->findOrFail($id);

        // 작성중 또는 반려 상태에서만 수정 가능
        if (! in_array($document->status, [Document::STATUS_DRAFT, Document::STATUS_REJECTED])) {
            return response()->json([
                'success' => false,
                'message' => '현재 상태에서는 수정할 수 없습니다.',
            ], 422);
        }

        $request->validate([
            'title' => 'sometimes|required|string|max:255',
            'data' => 'nullable|array',
            'data.*.field_key' => 'required|string',
            'data.*.field_value' => 'nullable|string',
            'data.*.section_id' => 'nullable|integer',
            'data.*.column_id' => 'nullable|integer',
            'data.*.row_index' => 'nullable|integer',
        ]);

        $document->update([
            'title' => $request->input('title', $document->title),
            'updated_by' => $userId,
        ]);

        // 문서 데이터 업데이트 (기존 삭제 후 재저장)
        if ($request->has('data')) {
            $document->data()->delete();
            $this->saveDocumentData($document, $request->input('data', []));
        }

        return response()->json([
            'success' => true,
            'message' => '문서가 수정되었습니다.',
            'data' => $document->fresh(['template', 'data']),
        ]);
    }

    /**
     * 문서 삭제 (소프트 삭제)
     */
    public function destroy(int $id): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        $document = Document::where('tenant_id', $tenantId)->findOrFail($id);

        $document->update(['deleted_by' => auth()->id()]);
        $document->delete();

        return response()->json([
            'success' => true,
            'message' => '문서가 삭제되었습니다.',
        ]);
    }

    /**
     * 문서 영구삭제 (슈퍼관리자 전용)
     */
    public function forceDestroy(int $id): JsonResponse
    {
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '슈퍼관리자만 영구 삭제할 수 있습니다.',
            ], 403);
        }

        $tenantId = session('selected_tenant_id');

        $document = Document::withTrashed()->where('tenant_id', $tenantId)->findOrFail($id);

        // 관련 데이터도 영구삭제
        $document->data()->delete();
        $document->approvals()->delete();
        $document->forceDelete();

        return response()->json([
            'success' => true,
            'message' => '문서가 영구 삭제되었습니다.',
        ]);
    }

    /**
     * 삭제된 문서 복원 (슈퍼관리자 전용)
     */
    public function restore(int $id): JsonResponse
    {
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '슈퍼관리자만 복원할 수 있습니다.',
            ], 403);
        }

        $tenantId = session('selected_tenant_id');

        $document = Document::onlyTrashed()->where('tenant_id', $tenantId)->findOrFail($id);
        $document->update(['deleted_by' => null]);
        $document->restore();

        return response()->json([
            'success' => true,
            'message' => '문서가 복원되었습니다.',
        ]);
    }

    /**
     * 결재 제출 (DRAFT → PENDING)
     */
    public function submit(int $id): JsonResponse
    {
        $tenantId = session('selected_tenant_id');
        $userId = auth()->id();

        $document = Document::where('tenant_id', $tenantId)->findOrFail($id);

        if ($document->status !== Document::STATUS_DRAFT && $document->status !== Document::STATUS_REJECTED) {
            return response()->json([
                'success' => false,
                'message' => '작성중 또는 반려 상태의 문서만 제출할 수 있습니다.',
            ], 422);
        }

        $document->update([
            'status' => Document::STATUS_PENDING,
            'submitted_at' => now(),
            'updated_by' => $userId,
        ]);

        // 결재라인 상태 초기화 (반려 후 재제출 시)
        $document->approvals()->update([
            'status' => DocumentApproval::STATUS_PENDING,
            'comment' => null,
            'acted_at' => null,
        ]);

        return response()->json([
            'success' => true,
            'message' => '결재가 제출되었습니다.',
            'data' => $document->fresh(['approvals']),
        ]);
    }

    /**
     * 결재 승인 (단계별)
     */
    public function approve(Request $request, int $id): JsonResponse
    {
        $tenantId = session('selected_tenant_id');
        $userId = auth()->id();

        $document = Document::where('tenant_id', $tenantId)->findOrFail($id);

        if ($document->status !== Document::STATUS_PENDING) {
            return response()->json([
                'success' => false,
                'message' => '결재중 상태의 문서만 승인할 수 있습니다.',
            ], 422);
        }

        // 현재 단계의 미처리 결재 찾기
        $pendingApproval = $document->approvals()
            ->where('status', DocumentApproval::STATUS_PENDING)
            ->orderBy('step')
            ->first();

        if (! $pendingApproval) {
            return response()->json([
                'success' => false,
                'message' => '승인 대기 중인 결재 단계가 없습니다.',
            ], 422);
        }

        $pendingApproval->update([
            'user_id' => $userId,
            'status' => DocumentApproval::STATUS_APPROVED,
            'comment' => $request->input('comment'),
            'acted_at' => now(),
            'updated_by' => $userId,
        ]);

        // 모든 결재가 완료되었는지 확인
        $remainingPending = $document->approvals()
            ->where('status', DocumentApproval::STATUS_PENDING)
            ->count();

        if ($remainingPending === 0) {
            $document->update([
                'status' => Document::STATUS_APPROVED,
                'completed_at' => now(),
                'updated_by' => $userId,
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => $remainingPending === 0 ? '최종 승인되었습니다.' : '승인되었습니다. (다음 단계 대기)',
            'data' => $document->fresh(['approvals']),
        ]);
    }

    /**
     * 결재 반려
     */
    public function reject(Request $request, int $id): JsonResponse
    {
        $tenantId = session('selected_tenant_id');
        $userId = auth()->id();

        $request->validate([
            'comment' => 'required|string|max:500',
        ]);

        $document = Document::where('tenant_id', $tenantId)->findOrFail($id);

        if ($document->status !== Document::STATUS_PENDING) {
            return response()->json([
                'success' => false,
                'message' => '결재중 상태의 문서만 반려할 수 있습니다.',
            ], 422);
        }

        // 현재 단계 결재에 반려 기록
        $pendingApproval = $document->approvals()
            ->where('status', DocumentApproval::STATUS_PENDING)
            ->orderBy('step')
            ->first();

        if ($pendingApproval) {
            $pendingApproval->update([
                'user_id' => $userId,
                'status' => DocumentApproval::STATUS_REJECTED,
                'comment' => $request->input('comment'),
                'acted_at' => now(),
                'updated_by' => $userId,
            ]);
        }

        $document->update([
            'status' => Document::STATUS_REJECTED,
            'completed_at' => now(),
            'updated_by' => $userId,
        ]);

        return response()->json([
            'success' => true,
            'message' => '문서가 반려되었습니다.',
            'data' => $document->fresh(['approvals']),
        ]);
    }

    /**
     * 문서 데이터 저장 (기본필드 + 섹션 테이블 데이터)
     */
    private function saveDocumentData(Document $document, array $dataItems): void
    {
        foreach ($dataItems as $item) {
            if (empty($item['field_key'])) {
                continue;
            }

            // 빈 값도 저장 (섹션 데이터 편집 시 빈값으로 클리어 가능)
            DocumentData::create([
                'document_id' => $document->id,
                'section_id' => $item['section_id'] ?? null,
                'column_id' => $item['column_id'] ?? null,
                'row_index' => $item['row_index'] ?? 0,
                'field_key' => $item['field_key'],
                'field_value' => $item['field_value'] ?? '',
            ]);
        }
    }

    /**
     * 문서 번호 생성
     * 형식: {카테고리prefix}-{YYMMDD}-{순번}
     * 예: IQC-260131-01, PRD-260131-01
     */
    private function generateDocumentNo(int $tenantId, int $templateId): string
    {
        $template = DocumentTemplate::find($templateId);
        $prefix = $this->getCategoryPrefix($template?->category);
        $date = now()->format('ymd');

        $lastDocument = Document::where('tenant_id', $tenantId)
            ->where('document_no', 'like', "{$prefix}-{$date}-%")
            ->orderBy('id', 'desc')
            ->first();

        $sequence = 1;
        if ($lastDocument) {
            $parts = explode('-', $lastDocument->document_no);
            if (count($parts) >= 3) {
                $sequence = (int) end($parts) + 1;
            }
        }

        return sprintf('%s-%s-%02d', $prefix, $date, $sequence);
    }

    /**
     * 카테고리별 문서번호 prefix
     * 카테고리가 '품질/수입검사' 등 슬래시 포함 시 상위 카테고리 기준
     */
    private function getCategoryPrefix(?string $category): string
    {
        if (! $category) {
            return 'DOC';
        }

        // 상위 카테고리 추출 (슬래시 포함 시)
        $mainCategory = str_contains($category, '/') ? explode('/', $category)[0] : $category;

        return match ($mainCategory) {
            '품질' => 'IQC',
            '생산' => 'PRD',
            '영업' => 'SLS',
            '구매' => 'PUR',
            default => 'DOC',
        };
    }
}
