<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Services\ApprovalService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ApprovalApiController extends Controller
{
    public function __construct(
        private readonly ApprovalService $service
    ) {}

    // =========================================================================
    // 목록
    // =========================================================================

    /**
     * 기안함
     */
    public function drafts(Request $request): JsonResponse
    {
        $result = $this->service->getMyDrafts(
            $request->only(['search', 'status', 'is_urgent', 'date_from', 'date_to']),
            (int) $request->get('per_page', 15)
        );

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

    /**
     * 결재 대기함
     */
    public function pending(Request $request): JsonResponse
    {
        $result = $this->service->getPendingForMe(
            auth()->id(),
            $request->only(['search', 'is_urgent', 'date_from', 'date_to']),
            (int) $request->get('per_page', 15)
        );

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

    /**
     * 처리 완료함
     */
    public function completed(Request $request): JsonResponse
    {
        $result = $this->service->getCompletedByMe(
            auth()->id(),
            $request->only(['search', 'status', 'date_from', 'date_to']),
            (int) $request->get('per_page', 15)
        );

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

    /**
     * 참조함
     */
    public function references(Request $request): JsonResponse
    {
        $result = $this->service->getReferencesForMe(
            auth()->id(),
            $request->only(['search', 'date_from', 'date_to', 'is_read']),
            (int) $request->get('per_page', 15)
        );

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

    // =========================================================================
    // CRUD
    // =========================================================================

    /**
     * 상세 조회
     */
    public function show(int $id): JsonResponse
    {
        $approval = $this->service->getApproval($id);

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

    /**
     * 생성 (임시저장)
     */
    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'form_id' => 'required|exists:approval_forms,id',
            'title' => 'required|string|max:200',
            'body' => 'nullable|string',
            'is_urgent' => 'boolean',
            'steps' => 'nullable|array',
            'steps.*.user_id' => 'required_with:steps|exists:users,id',
            'steps.*.step_type' => 'required_with:steps|in:approval,agreement,reference',
        ]);

        $approval = $this->service->createApproval($request->all());

        return response()->json([
            'success' => true,
            'message' => '결재 문서가 저장되었습니다.',
            'data' => $approval,
        ], 201);
    }

    /**
     * 수정
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'title' => 'sometimes|string|max:200',
            'body' => 'nullable|string',
            'is_urgent' => 'boolean',
            'steps' => 'nullable|array',
            'steps.*.user_id' => 'required_with:steps|exists:users,id',
            'steps.*.step_type' => 'required_with:steps|in:approval,agreement,reference',
        ]);

        try {
            $approval = $this->service->updateApproval($id, $request->all());

            return response()->json([
                'success' => true,
                'message' => '결재 문서가 수정되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 삭제
     */
    public function destroy(int $id): JsonResponse
    {
        try {
            $user = auth()->user();
            $approval = $this->service->getApproval($id);

            if (! $approval->isDeletableBy($user)) {
                return response()->json([
                    'success' => false,
                    'message' => '삭제 권한이 없습니다.',
                ], 403);
            }

            $this->service->deleteApproval($id, $user);

            return response()->json([
                'success' => true,
                'message' => '결재 문서가 삭제되었습니다.',
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    // =========================================================================
    // 워크플로우
    // =========================================================================

    /**
     * 상신
     */
    public function submit(int $id): JsonResponse
    {
        try {
            $approval = $this->service->submit($id);

            return response()->json([
                'success' => true,
                'message' => '결재가 상신되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 승인
     */
    public function approve(Request $request, int $id): JsonResponse
    {
        try {
            $approval = $this->service->approve($id, $request->get('comment'));

            return response()->json([
                'success' => true,
                'message' => '승인되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 반려
     */
    public function reject(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'comment' => 'required|string|max:1000',
        ]);

        try {
            $approval = $this->service->reject($id, $request->get('comment'));

            return response()->json([
                'success' => true,
                'message' => '반려되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 회수
     */
    public function cancel(Request $request, int $id): JsonResponse
    {
        try {
            $approval = $this->service->cancel($id, $request->get('recall_reason'));

            return response()->json([
                'success' => true,
                'message' => '결재가 회수되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 보류
     */
    public function hold(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'comment' => 'required|string|max:1000',
        ]);

        try {
            $approval = $this->service->hold($id, $request->get('comment'));

            return response()->json([
                'success' => true,
                'message' => '보류되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 보류 해제
     */
    public function releaseHold(int $id): JsonResponse
    {
        try {
            $approval = $this->service->releaseHold($id);

            return response()->json([
                'success' => true,
                'message' => '보류가 해제되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 전결
     */
    public function preDecide(Request $request, int $id): JsonResponse
    {
        try {
            $approval = $this->service->preDecide($id, $request->get('comment'));

            return response()->json([
                'success' => true,
                'message' => '전결 처리되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 복사 재기안
     */
    public function copyForRedraft(int $id): JsonResponse
    {
        try {
            $approval = $this->service->copyForRedraft($id);

            return response()->json([
                'success' => true,
                'message' => '문서가 복사되었습니다.',
                'data' => $approval,
            ]);
        } catch (\InvalidArgumentException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 400);
        }
    }

    /**
     * 참조 열람 추적
     */
    public function markAsRead(int $id): JsonResponse
    {
        $this->service->markAsRead($id);

        return response()->json([
            'success' => true,
            'message' => '열람 처리되었습니다.',
        ]);
    }

    // =========================================================================
    // 유틸
    // =========================================================================

    /**
     * 결재선 템플릿 목록
     */
    public function lines(): JsonResponse
    {
        $lines = $this->service->getApprovalLines();

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

    /**
     * 결재선 템플릿 생성
     */
    public function storeLine(Request $request): JsonResponse
    {
        $request->validate([
            'name' => 'required|string|max:100',
            'steps' => 'required|array|min:1',
            'steps.*.user_id' => 'required|exists:users,id',
            'steps.*.step_type' => 'required|in:approval,agreement,reference',
            'is_default' => 'boolean',
        ]);

        $line = $this->service->createLine($request->all());

        return response()->json([
            'success' => true,
            'message' => '결재선이 저장되었습니다.',
            'data' => $line,
        ], 201);
    }

    /**
     * 결재선 템플릿 수정
     */
    public function updateLine(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'name' => 'required|string|max:100',
            'steps' => 'required|array|min:1',
            'steps.*.user_id' => 'required|exists:users,id',
            'steps.*.step_type' => 'required|in:approval,agreement,reference',
            'is_default' => 'boolean',
        ]);

        $line = $this->service->updateLine($id, $request->all());

        return response()->json([
            'success' => true,
            'message' => '결재선이 수정되었습니다.',
            'data' => $line,
        ]);
    }

    /**
     * 결재선 템플릿 삭제
     */
    public function destroyLine(int $id): JsonResponse
    {
        $this->service->deleteLine($id);

        return response()->json([
            'success' => true,
            'message' => '결재선이 삭제되었습니다.',
        ]);
    }

    /**
     * 양식 목록
     */
    public function forms(): JsonResponse
    {
        $forms = $this->service->getApprovalForms();

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

    /**
     * 미처리 건수
     */
    public function badgeCounts(): JsonResponse
    {
        $counts = $this->service->getBadgeCounts(auth()->id());

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