<?php

namespace App\Http\Controllers\HRM;

use Illuminate\Support\Str;
use App\Http\Controllers\Controller;
use App\Models\HRM\Attendancelog;
use App\Models\HRM\Employee;
use Illuminate\Http\Request;
use App\Traits\CrudTrait;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;


class AttendancelogController extends Controller
{
    use CrudTrait;
    protected string $dataType = 'object';
    protected string $modelClass = Attendancelog::class;

    public function index(Request $request)
    {
        return $this->getData($request);
    }

    public function store(Request $request)
    {
        return $this->storeData($request);
    }

    public function bulkStore(Request $request)
    {
        return $this->importAttendanceLogsFromRequest($request);
    }

    public function update(Request $request)
    {
        return $this->updateData($request);
    }

    public function bulkUpdate(Request $request)
    {
        return $this->multiUpdate($request);
    }


    public function destroy(Request $request)
    {
        return $this->destroyData($request);
    }

    public function bulkDestory(Request $request)
    {
        return $this->bulkDelete($request);
    }

    public function clone(Request $request)
    {
        return $this->cloneData($request);
    }

    public function export(Request $request)
    {
        return $this->exportData($request);
    }

    public function import(Request $request)
    {
        return $this->importData($request);
    }

    public function upload(Request $request)
    {
        return $this->uploadFile($request);
    }

    public function download(Request $request)
    {
        return $this->downloadFile($request);
    }


    public function importAttendanceLogsFromRequest(Request $request)
    {
        $logs = collect($request->all());

        if ($logs->isEmpty()) {
            return response()->json(['error' => 'No data received'], 400);
        }

        DB::beginTransaction();

        try {
            // Step 1: Normalize request logs and attach employee info
            $normalizedLogs = $logs->map(function ($log) {
                $employee = Employee::where('pid', trim($log['employee_pid']))->first();

                if (!$employee) {
                    return null; // skip logs for non-existing employees
                }
                $employeeData = $employee->only([
                    'id',
                    'uid',
                    'name',
                    'status',
                    'matricule',
                    'pid',
                ]);
                $date = Carbon::parse(trim($log['date']))->format('Y-m-d');
                $time = date('H:i:s', strtotime($log['time']));
                $logDateTime = "$date $time";

                return [
                    'uid' => (string) Str::ulid(),
                    'employee_id' => $employee->id,
                    'employee_pid' => $employee->pid,
                    'employee' => json_encode($employeeData),
                    'name' => $employee->name,
                    'date' => $date,
                    'time' => $logDateTime,
                    'isToken' => 0,
                    'type' => strtolower(trim($log['type'])),
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            })->filter()->values(); // remove nulls

            if ($normalizedLogs->isEmpty()) {
                return response()->json(['success' => false, 'message' => 'No valid logs to insert'], 400);
            }

            // Step 2: Get existing logs from DB for the employees and dates in the request
            $employeePids = $normalizedLogs->pluck('employee_pid')->unique();
            $dates = $normalizedLogs->pluck('date')->unique();

            $existingKeys = AttendanceLog::whereIn('employee_pid', $employeePids)
                ->whereIn('date', $dates)
                ->get(['employee_pid', 'date', 'type'])
                ->map(fn($e) => $e->employee_pid . '-' . $e->date . '-' . $e->type);

            // Step 3: Filter out logs that already exist in DB (prevent duplicates)
            $newLogs = $normalizedLogs->reject(function ($log) use ($existingKeys) {
                $key = $log['employee_pid'] . '-' . $log['date'] . '-' . $log['type'];
                return $existingKeys->contains($key);
            })->values();

            // Step 4: Insert only new logs
            if ($newLogs->isNotEmpty()) {
                AttendanceLog::insertOrIgnore($newLogs->toArray());
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'inserted' => $newLogs->count(),
                'skipped' => $normalizedLogs->count() - $newLogs->count(),
                'message' => 'Attendance logs imported successfully (duplicates skipped)',
            ]);
        } catch (\Throwable $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error importing logs',
                'error' => $e->getMessage(),
            ], 500);
        }
    }
}
