<?php

namespace App\Http\Controllers\Api\Admin\HR;

use App\Http\Controllers\Controller;
use App\Models\HR\Attendance;
use App\Services\HR\AttendanceService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AttendanceController extends Controller
{
    public function __construct(
        private AttendanceService $attendanceService
    ) {}

    /**
     * 근태 목록 조회 (HTMX → HTML / 일반 → JSON)
     */
    public function index(Request $request): JsonResponse|Response
    {
        $attendances = $this->attendanceService->getAttendances(
            $request->all(),
            $request->integer('per_page', 20)
        );

        if ($request->header('HX-Request')) {
            $viewName = $request->input('view') === 'manage'
                ? 'hr.attendances.partials.table-manage'
                : 'hr.attendances.partials.table';

            return response(view($viewName, compact('attendances')));
        }

        return response()->json([
            'success' => true,
            'data' => $attendances->items(),
            'meta' => [
                'current_page' => $attendances->currentPage(),
                'last_page' => $attendances->lastPage(),
                'per_page' => $attendances->perPage(),
                'total' => $attendances->total(),
            ],
        ]);
    }

    /**
     * 월간 통계 (HTMX → HTML / 일반 → JSON)
     */
    public function stats(Request $request): JsonResponse|Response
    {
        $stats = $this->attendanceService->getMonthlyStats(
            $request->integer('year') ?: null,
            $request->integer('month') ?: null
        );

        if ($request->header('HX-Request')) {
            return response(view('hr.attendances.partials.stats', compact('stats')));
        }

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

    /**
     * 월간 캘린더 (HTMX → HTML)
     */
    public function calendar(Request $request): JsonResponse|Response
    {
        $year = $request->integer('year') ?: now()->year;
        $month = $request->integer('month') ?: now()->month;
        $userId = $request->integer('user_id') ?: null;

        $attendances = $this->attendanceService->getMonthlyCalendarData($year, $month, $userId);
        $calendarData = $attendances->groupBy(fn ($att) => $att->base_date->format('Y-m-d'));
        $employees = $this->attendanceService->getActiveEmployees();

        if ($request->header('HX-Request')) {
            return response(view('hr.attendances.partials.calendar', compact(
                'year', 'month', 'calendarData', 'employees'
            ))->with('selectedUserId', $userId));
        }

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

    /**
     * 사원별 월간 요약 (HTMX → HTML)
     */
    public function summary(Request $request): JsonResponse|Response
    {
        $year = $request->integer('year') ?: now()->year;
        $month = $request->integer('month') ?: now()->month;

        $summary = $this->attendanceService->getEmployeeMonthlySummary($year, $month);

        if ($request->header('HX-Request')) {
            return response(view('hr.attendances.partials.summary', compact('summary', 'year', 'month')));
        }

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

    /**
     * 초과근무 알림 (HTMX → HTML)
     */
    public function overtimeAlerts(Request $request): JsonResponse|Response
    {
        $alerts = $this->attendanceService->getOvertimeAlerts();

        if ($request->header('HX-Request')) {
            return response(view('hr.attendances.partials.overtime-alerts', compact('alerts')));
        }

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

    /**
     * 잔여 연차 조회
     */
    public function leaveBalance(Request $request, int $userId): JsonResponse
    {
        $balance = $this->attendanceService->getLeaveBalance($userId);

        return response()->json([
            'success' => true,
            'data' => [
                'total' => $balance?->total ?? 0,
                'used' => $balance?->used ?? 0,
                'remaining' => $balance?->remaining ?? 0,
            ],
        ]);
    }

    /**
     * 엑셀(CSV) 내보내기
     */
    public function export(Request $request): StreamedResponse
    {
        $attendances = $this->attendanceService->getExportData($request->all());
        $tenantId = session('selected_tenant_id');

        $filename = '근태현황_'.now()->format('Ymd').'.csv';

        return response()->streamDownload(function () use ($attendances) {
            $file = fopen('php://output', 'w');
            fwrite($file, "\xEF\xBB\xBF"); // UTF-8 BOM

            fputcsv($file, ['날짜', '사원명', '부서', '상태', '출근', '퇴근', '비고']);

            foreach ($attendances as $att) {
                $profile = $att->user?->tenantProfiles?->first();
                $displayName = $profile?->display_name ?? $att->user?->name ?? '-';
                $department = $profile?->department?->name ?? '-';
                $statusLabel = Attendance::STATUS_MAP[$att->status] ?? $att->status;
                $checkIn = $att->check_in ? substr($att->check_in, 0, 5) : '';
                $checkOut = $att->check_out ? substr($att->check_out, 0, 5) : '';

                fputcsv($file, [
                    $att->base_date->format('Y-m-d'),
                    $displayName,
                    $department,
                    $statusLabel,
                    $checkIn,
                    $checkOut,
                    $att->remarks ?? '',
                ]);
            }

            fclose($file);
        }, $filename, [
            'Content-Type' => 'text/csv; charset=UTF-8',
        ]);
    }

    /**
     * 일괄 삭제
     */
    public function bulkDestroy(Request $request): JsonResponse|Response
    {
        $validated = $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'integer',
        ]);

        try {
            $count = $this->attendanceService->bulkDelete($validated['ids']);

            if ($request->header('HX-Request')) {
                $attendances = $this->attendanceService->getAttendances(
                    $request->except('ids'),
                    $request->integer('per_page', 20)
                );

                return response(view('hr.attendances.partials.table', compact('attendances')));
            }

            return response()->json([
                'success' => true,
                'message' => "{$count}건의 근태가 삭제되었습니다.",
            ]);
        } catch (\Throwable $e) {
            report($e);

            return response()->json([
                'success' => false,
                'message' => '일괄 삭제 중 오류가 발생했습니다.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * 근태 등록
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'user_id' => 'required|integer|exists:users,id',
            'base_date' => 'required|date',
            'status' => 'required|string|in:onTime,late,absent,vacation,businessTrip,fieldWork,overtime,remote',
            'check_in' => 'nullable|date_format:H:i',
            'check_out' => 'nullable|date_format:H:i',
            'remarks' => 'nullable|string|max:500',
        ]);

        try {
            $attendance = $this->attendanceService->storeAttendance($validated);

            return response()->json([
                'success' => true,
                'message' => '근태가 등록되었습니다.',
                'data' => $attendance,
            ], 201);
        } catch (\Throwable $e) {
            report($e);

            return response()->json([
                'success' => false,
                'message' => '근태 등록 중 오류가 발생했습니다.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * 일괄 등록
     */
    public function bulkStore(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'user_ids' => 'required|array|min:1',
            'user_ids.*' => 'integer|exists:users,id',
            'base_date' => 'required|date',
            'status' => 'required|string|in:onTime,late,absent,vacation,businessTrip,fieldWork,overtime,remote',
            'check_in' => 'nullable|date_format:H:i',
            'check_out' => 'nullable|date_format:H:i',
            'remarks' => 'nullable|string|max:500',
        ]);

        try {
            $result = $this->attendanceService->bulkStore($validated);

            return response()->json([
                'success' => true,
                'message' => "신규 {$result['created']}건, 수정 {$result['updated']}건 처리되었습니다.",
                'data' => $result,
            ], 201);
        } catch (\Throwable $e) {
            report($e);

            return response()->json([
                'success' => false,
                'message' => '일괄 등록 중 오류가 발생했습니다.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * 근태 수정
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'status' => 'sometimes|required|string|in:onTime,late,absent,vacation,businessTrip,fieldWork,overtime,remote',
            'check_in' => 'nullable|date_format:H:i',
            'check_out' => 'nullable|date_format:H:i',
            'remarks' => 'nullable|string|max:500',
        ]);

        try {
            $attendance = $this->attendanceService->updateAttendance($id, $validated);

            if (! $attendance) {
                return response()->json([
                    'success' => false,
                    'message' => '근태 정보를 찾을 수 없습니다.',
                ], 404);
            }

            return response()->json([
                'success' => true,
                'message' => '근태가 수정되었습니다.',
                'data' => $attendance,
            ]);
        } catch (\Throwable $e) {
            report($e);

            return response()->json([
                'success' => false,
                'message' => '근태 수정 중 오류가 발생했습니다.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }

    /**
     * 근태 삭제
     */
    public function destroy(Request $request, int $id): JsonResponse|Response
    {
        try {
            $result = $this->attendanceService->deleteAttendance($id);

            if (! $result) {
                return response()->json([
                    'success' => false,
                    'message' => '근태 정보를 찾을 수 없습니다.',
                ], 404);
            }

            if ($request->header('HX-Request')) {
                $attendances = $this->attendanceService->getAttendances(
                    $request->all(),
                    $request->integer('per_page', 20)
                );

                return response(view('hr.attendances.partials.table', compact('attendances')));
            }

            return response()->json([
                'success' => true,
                'message' => '근태가 삭제되었습니다.',
            ]);
        } catch (\Throwable $e) {
            report($e);

            return response()->json([
                'success' => false,
                'message' => '근태 삭제 중 오류가 발생했습니다.',
                'error' => config('app.debug') ? $e->getMessage() : null,
            ], 500);
        }
    }
}
