<?php
namespace App\Http\Controllers;
use App\Models\{AttendanceEntry,AttendanceSession,Activity,Organization};
use App\Services\{ImageOptimizerService,OrganizationAccess};
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class AttendanceController extends Controller {
    public function index(Request $request){
        $sessions=OrganizationAccess::apply(AttendanceSession::with(['organization','activity'])->withCount('entries')->latest(),$request->user())->paginate(20);
        $orgs=$request->user()->isSuperAdmin()?Organization::where('is_active',true)->orderBy('name')->get():Organization::whereKey($request->user()->organization_id)->get();
        $activities=OrganizationAccess::apply(Activity::query(),$request->user())->latest('start_at')->limit(100)->get();
        return view('admin.attendance.index',compact('sessions','orgs','activities'));
    }
    public function store(Request $request){
        $data=$request->validate(['organization_id'=>'required|exists:organizations,id','activity_id'=>'nullable|exists:activities,id','title'=>'required|max:200','opens_at'=>'nullable|date','closes_at'=>'nullable|date|after_or_equal:opens_at','location_name'=>'nullable|max:200','latitude'=>'nullable|numeric','longitude'=>'nullable|numeric','radius_meters'=>'required|integer|min:10|max:10000','retention_months'=>'required|integer|min:1|max:36']);
        if(!$request->user()->isSuperAdmin())$data['organization_id']=$request->user()->organization_id;
        $data['token']=Str::upper(Str::random(10)); $data['require_location']=$request->boolean('require_location'); $data['require_photo']=$request->boolean('require_photo'); $data['one_device_one_person']=$request->boolean('one_device_one_person'); $data['allow_public']=true; $data['is_active']=true;
        AttendanceSession::create($data); return back()->with('success','Link presensi berhasil dibuat.');
    }
    public function publicForm(string $token){ $session=AttendanceSession::with('organization')->where('token',$token)->firstOrFail(); return view('public.attendance',compact('session')); }
    public function submit(Request $request, string $token, ImageOptimizerService $images){
        $session=AttendanceSession::where('token',$token)->firstOrFail(); if(!$session->isOpen()) return back()->withErrors(['presensi'=>'Presensi sedang tidak dibuka.']);
        $rules=['full_name'=>'required|max:180','nickname'=>'nullable|max:80','organization_name'=>'nullable|max:150','position'=>'nullable|max:120','whatsapp'=>'nullable|max:40','device_id'=>'required|max:255','latitude'=>'nullable|numeric','longitude'=>'nullable|numeric'];
        if($session->require_photo)$rules['photo']='required|image|max:10240'; else $rules['photo']='nullable|image|max:10240';
        $data=$request->validate($rules); $deviceHash=hash('sha256',$data['device_id']);
        if($session->one_device_one_person && AttendanceEntry::where('attendance_session_id',$session->id)->where('device_hash',$deviceHash)->exists()) return back()->withErrors(['device_id'=>'Perangkat ini sudah digunakan untuk satu peserta pada presensi ini.']);
        $distance=null;
        if($session->require_location){
            if($data['latitude']===null || $data['longitude']===null) return back()->withErrors(['location'=>'Lokasi wajib diaktifkan.']);
            if($session->latitude===null || $session->longitude===null) return back()->withErrors(['location'=>'Koordinat lokasi kegiatan belum diatur admin.']);
            $distance=$this->distanceMeters((float)$session->latitude,(float)$session->longitude,(float)$data['latitude'],(float)$data['longitude']);
            if($distance>$session->radius_meters) return back()->withErrors(['location'=>'Anda berada di luar radius presensi. Jarak terdeteksi '.number_format($distance).' meter.']);
        }
        $photoPath=$request->hasFile('photo')?$images->storeWebp($request->file('photo'),'attendance',1200,78):null;
        AttendanceEntry::create(['attendance_session_id'=>$session->id,'full_name'=>$data['full_name'],'nickname'=>$data['nickname']??null,'organization_name'=>$data['organization_name']??null,'position'=>$data['position']??null,'whatsapp'=>$data['whatsapp']??null,'device_hash'=>$deviceHash,'latitude'=>$data['latitude']??null,'longitude'=>$data['longitude']??null,'distance_meters'=>$distance,'photo_path'=>$photoPath,'status'=>'present','attended_at'=>now(),'ip_address'=>$request->ip(),'user_agent'=>substr((string)$request->userAgent(),0,500)]);
        return redirect()->route('attendance.public',$session->token)->with('success','Presensi berhasil. Terima kasih.');
    }
    public function entries(Request $request, AttendanceSession $session){
        abort_unless($request->user()->isSuperAdmin() || $request->user()->organization_id===$session->organization_id,403);
        $entries=$session->entries()->latest('attended_at')->paginate(50); return view('admin.attendance.entries',compact('session','entries'));
    }
    public function toggle(Request $request, AttendanceSession $session){ abort_unless($request->user()->isSuperAdmin() || $request->user()->organization_id===$session->organization_id,403); $session->update(['is_active'=>!$session->is_active]); return back()->with('success','Status presensi diperbarui.'); }
    private function distanceMeters(float $lat1,float $lon1,float $lat2,float $lon2): int { $r=6371000; $p1=deg2rad($lat1); $p2=deg2rad($lat2); $dp=deg2rad($lat2-$lat1); $dl=deg2rad($lon2-$lon1); $a=sin($dp/2)**2+cos($p1)*cos($p2)*sin($dl/2)**2; return (int)round($r*2*atan2(sqrt($a),sqrt(1-$a))); }
}
