<?php

namespace Modules\Lpj\Http\Controllers;

use App\Http\Controllers\Controller;
use Exception;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\Penilaian;
use Modules\Lpj\Models\TeamsUsers;
use Modules\Lpj\Models\PenilaianTeam;
use Modules\Lpj\Models\StatusPermohonan;
use Modules\Lpj\Exports\PermohonanExport;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Models\Teams;
use Illuminate\Support\Facades\DB;

class ActivityController extends Controller
{
    public $user;
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $status_permohonan = StatusPermohonan::all();
        return view('lpj::activity.index', compact('status_permohonan'));
    }

    /**
     * Show the form for creating a new resource.
     */


    public function progres_activity()
    {
        // Ambil user yang sedang login dengan roles
        $user = auth()->user()->load('roles');

        // Inisialisasi regionId dan teamId
        $regionId = $teamId = null;

        if ($user->roles->pluck('name')->contains('senior-officer')) {
            $userTeam = TeamsUsers::with('team')->firstWhere('user_id', $user->id);
            $regionId = $userTeam?->team->regions_id;
            $teamId = $userTeam?->teams_id;
        }


        $teamsActivity = TeamsUsers::with(['user', 'team', 'team.regions', 'user.roles'])
            ->whereHas('team', function ($q) use ($regionId, $teamId) {
                $q->when($regionId, fn ($q) => $q->where('regions_id', $regionId))
                  ->when($teamId, fn ($q) => $q->where('id', $teamId));
            })
            ->where('user_id', '!=', $user->id)
            ->whereHas('user.roles', fn ($q) => $q->whereIn('name', ['surveyor', 'surveyor-penilai','penilai']))
            ->get();

        $teamId = is_array($teamId) ? $teamId : [$teamId];

        $teamPenilai = Teams::with(['regions', 'teamsUsers', 'teamsUsers.user'])->whereNotIn(
            'id',
            $teamId
        )->get();


        return view('lpj::activity.progres_activity.index', compact('teamsActivity', 'teamPenilai'));
    }


    public function updateTeamAssingment(Request $request)
    {
        try {

            // dd($request->all());
            $validatedData = $request->validate([
                'id' => 'required|integer', // penilaian_id
                'team_member_id' => 'nullable|integer',
                'region_id' => 'nullable|integer',
                'permohonan_id' => 'required|integer',
                'user_id' => 'required|integer',
                'team_id' => 'required|integer',
                'penugasan' => 'required|string',
            ], [
                'team_member_id.required_without' => 'Field team harus diisi.',
                '.required_without' => 'Field  harus diisi.',
            ]);


            $penilaianId = $validatedData['id'];
            $teamMemberId = $validatedData['team_member_id'] ?? null;
            $regionId = $validatedData['region_id'] ?? null;
            $permohonanId = $validatedData['permohonan_id'];
            $userId = $validatedData['user_id'];
            $teamId = $validatedData['team_id'];
            $penugasan = $validatedData['penugasan'];

            // Cek apakah permohonan ada
            $permohonan = Permohonan::findOrFail($permohonanId);

            // Validasi status permohonan
            // if ($permohonan->status !== 'assign' && $permohonan->status !== 'proses-survey' && $permohonan->status !== 'survey' && $permohonan->status !== 'proses-laporan') {
            //     return response()->json([
            //         'status' => 'error',
            //         'message' => 'Tidak dapat mengganti tim, status permohonan tidak memungkinkan.',
            //     ]);
            // }

            // Ambil tim berdasarkan penilaian_id dan user_id

            if ($penugasan === 'sama') {
                $teams = PenilaianTeam::where('penilaian_id', $penilaianId)
                ->where('user_id', $userId)
                ->get();
                // Cek apakah tim ditemukan
                if ($teams->isEmpty()) {
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Data tim tidak ditemukan.',
                    ]);
                }

                // Mulai transaksi
                DB::beginTransaction();
                $updated = false;

                $status_permohonan = $permohonan->status;

                // Proses update berdasarkan region_id
                if ($regionId) {
                    foreach ($teams as $team) {
                        if ($team->role === 'surveyor') {
                            $team->update([
                                'team_id' => $regionId,
                                'user_id' => null,
                                'status' =>  $status_permohonan,
                            ]);
                            $permohonan->update([
                                'status' =>  'reassign'
                            ]);
                            $updated = true;
                        }

                        if ($team->role === 'penilai') {
                            $team->update([
                                'team_id' => $regionId,
                                'user_id' => null,
                                'status' =>  $status_permohonan
                            ]);
                            $permohonan->update([
                                'status' =>  'reassign',
                                'region_id' => $regionId,
                            ]);
                            $updated = true;
                        }
                    }
                }

                // Proses update berdasarkan team_member_id
                if ($teamMemberId) {
                    foreach ($teams as $team) {
                        if ($team->role === 'surveyor' || $team->role === 'penilai') {
                            $team->update(['user_id' => $teamMemberId]);
                            $updated = true;
                        }
                    }
                }
            }

            if ($penugasan === 'surveyor' || $penugasan === 'penilai') {
                $teams = PenilaianTeam::where('penilaian_id', $penilaianId)
                ->where('user_id', $userId)
                ->where('role', $penugasan)
                ->first();

                // Cek apakah tim ditemukan
                if (!$teams) {
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Data tim tidak ditemukan.',
                    ]);
                }

                // Mulai transaksi
                DB::beginTransaction();
                $updated = false;

                // Proses update berdasarkan region_id
                if ($regionId) {
                    $teams->update([
                        'team_id' => $regionId,
                        'user_id' => null
                    ]);
                    $permohonan->update([
                        'status' => $status_permohonan,
                        'region_id' => $regionId,
                    ]);
                    $updated = true;
                }

                // Proses update berdasarkan team_member_id
                if ($teamMemberId) {
                    $teams->update(['user_id' => $teamMemberId]);
                    $updated = true;
                }
            }


            if ($updated) {
                DB::commit();
                return response()->json([
                    'status' => 'success',
                    'message' => 'Data tim berhasil diperbarui.',
                ]);
            }

            DB::rollBack();
            return response()->json([
                'status' => 'error',
                'message' => 'Tidak ada perubahan yang dilakukan.',
            ]);
        } catch (\Throwable $th) {
            // Rollback transaksi jika terjadi error
            DB::rollBack();
            return response()->json([
                'status' => 'error',
                'message' => 'Terjadi kesalahan: ' . $th->getMessage(),
            ], 500);
        }
    }





    public function senior()
    {
        return view('lpj::activity.senior_officer.index');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): RedirectResponse
    {
        //
    }

    /**
     * Show the specified resource.
     */
    public function show($id)
    {

        $status_permohonan = StatusPermohonan::orderBy('id')->get()->reverse();

        $permohonan = Permohonan::with(
            [
                'user',
                'debiture.province',
                'debiture.city',
                'debiture.district',
                'debiture.village',
                'branch',
                'tujuanPenilaian',
                'penilaian'
            ],
        )->findOrFail($id);

        return view('lpj::activity.activitydetail', compact('id', 'status_permohonan', 'permohonan'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        return view('lpj::edit');
    }

    /**
     * Update the specified resource in storage.
     */public function dataForDatatables(Request $request)
    {

        $user = auth()->user();


        // Check permissions
        if (is_null($this->user) || !$this->user->can('debitur.view')) {
            // abort(403, 'Sorry! You are not allowed to view users.');
        }

        $userRole = $user->roles->pluck('name')->first();
        $regionId = null;

        // If user is senior-officer, get their regionId
        if ($userRole === 'senior-officer') {
            $userTeam = TeamsUsers::with('team')->firstWhere('user_id', $user->id);
            $regionId = $userTeam?->team->regions_id;
        }

        // Retrieve data from the database
        $query = Permohonan::query();

        // Apply search filter if provided
        $query = $query->orderBy('nomor_registrasi', 'desc');
        if ($request->has('search') && !empty($request->get('search'))) {
            $search = $request->get('search');
            $query->where(function ($q) use ($search) {
                $q->where('nomor_registrasi', 'LIKE', '%' . $search . '%')
                  ->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%')
                  ->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%')
                  ->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%')
                  ->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%')
                  ->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');

                // Split search term by comma to allow multiple statuses
                $statusKeywords = explode(',', $search);
                foreach ($statusKeywords as $keyword) {
                    $q->orWhere('status', 'LIKE', '%' . trim($keyword) . '%');
                }
            });
        }



        // Apply sorting if provided
        if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
            $order  = $request->get('sortOrder');
            $column = $request->get('sortField');
            $query->orderBy($column, $order);
        } else {
            $query->orderBy('nomor_registrasi', 'asc');
        }

        // Get total count of records before pagination
        $totalRecords = $query->count();

        // Pagination
        if ($request->has('page') && $request->has('size')) {
            $page = (int) $request->get('page', 1);
            $size = (int) $request->get('size', 10);
            $offset = ($page - 1) * $size;
            $query->skip($offset)->take($size);
        }

        // Get filtered count
        $filteredRecords = $query->count();

        // Filter by region if user is senior-officer
        if ($regionId) {
            $query->whereHas('region', function ($q) use ($regionId) {
                $q->where('region_id', $regionId);
            });
        }

        // Filter for specific roles
        if (in_array($userRole, ['surveyor', 'penilai'])) {
            $query->whereHas('penilaian.userPenilai', function ($q) use ($user) {
                $q->where('user_id', $user->id);
            });
        }

        $totalRecords = $query->count();

        // Pagination
        if ($request->has('page') && $request->has('size')) {
            $page = (int) $request->get('page', 1);
            $size = (int) $request->get('size', 10);
            $offset = ($page - 1) * $size;
            $query->skip($offset)->take($size);
        }

        // Get filtered count
        $filteredRecords = $query->count();

        // Get data with necessary relationships
        $data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian', 'dokumenjaminan','nilaiPlafond'])->get();

        // Calculate total pages
        $pageCount = ceil($totalRecords / $request->get('size', 10));




        // Calculate total pages
        $pageCount = ceil($totalRecords / $request->get('size', 10));

        return response()->json([
            'draw'            => $request->get('draw'),
            'recordsTotal'    => $totalRecords,
            'recordsFiltered' => $filteredRecords,
            'pageCount'       => $pageCount,
            'page'            => $request->get('page', 1),
            'totalCount'      => $totalRecords,
            'data'            => $data,
        ]);
    }



    /**
     * Download the specified resource from storage.
     */
    public function download($id)
    {
        $document = Permohonan::find($id);
        return response()->download(storage_path('app/public/' . $document->dokumen));
    }

    public function export()
    {
        return Excel::download(new PermohonanExport(), 'activity.xlsx');
    }




    public function dataTablesForActivity(Request $request, $id)
    {

        if (is_null($this->user) || !$this->user->can('debitur.view')) {
            // abort(403, 'Sorry! You are not allowed to view users.');
        }
        // Query Penilaian dengan relasi yang diperlukan
        $query = Penilaian::with([
            'permohonan',
            'permohonan.debiture',
            'permohonan.tujuanPenilaian',
            'permohonan.debiture.documents.jenisJaminan',
            'userPenilai' => function ($query) use ($id) {
                $query->where('user_id', $id);
            },
            'permohonan.penilai',
            'permohonan.approveEo',
            'permohonan.approveDd',
            'permohonan.approveSo',

        ])
        ->whereHas('userPenilai', function ($q) use ($id) {
            $q->where('user_id', $id);
        })
        ->whereHas('permohonan', function ($q) {
            $q->whereIn('status', [
                'assign',
                'survey-completed',
                'proses-laporan',
                'paparan',
                'proses-paparan',
                'revisi-laporan',
                'revisi-paparan',
                'survey',
                'proses-survey',
                'request-reschedule',
                'reschedule',
                'rejected-reschedule',
                'approved-reschedule',
                'revisi-survey',
                'revisi-pembayaran'
            ]);
        });



        // Filter pencarian
        if ($request->has('search') && !empty($request->get('search'))) {
            $search = $request->get('search');
            $query->where(function ($q) use ($search) {
                $q->where('nomor_registrasi', 'LIKE', "%$search%")
                  ->orWhere('status', 'LIKE', "%$search%");
            });
        }

        // Sorting
        if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
            $order  = $request->get('sortOrder');
            $column = $request->get('sortField');
            $query->orderBy($column, $order);
        }

        // Hitung total records
        $totalRecords = $query->count();

        // Pagination
        $size = $request->get('size', 10);
        $page = $request->get('page', 1);
        $offset = ($page - 1) * $size;

        // Ambil data dengan pagination
        $data = $query->skip($offset)->take($size)->get();

        $data = $data->map(function ($item) {
            $jeniAsset = null;
            $statusPembayaran = trim(strtolower($item->permohonan->status_bayar ?? ''));
            $tujuanPenilaian = $item->permohonan->tujuanPenilaian->name ?? null;
            $plafond = $item->permohonan->nilaiPlafond->name ?? null;

            $now = Carbon::now();
            $type_report = $item->permohonan->penilai->type ?? "";

            $hari = $hariPaparan = 0;

            if ($type_report == "sederhana") {
                $hari = 2;
                $item->paparan = 'Tidak Ada';
            } else {
                if ($plafond == '< 2M') {
                    $item->paparan = 'Tidak Ada';
                    $hari = 3;
                } elseif ($plafond == '2 M - 5 M') {
                    $hari = 3;
                    $hariPaparan = 2;
                } else {
                    $hari = 5;
                    $hariPaparan = 3;
                }
            }

            if ($tujuanPenilaian == 'RAP') {
                $hari = 2;
                $hariPaparan = 2;
            }


            if ($item->permohonan && $item->permohonan->debiture) {
                $jeniAsset = $item->permohonan->debiture->documents->first() ?? null;
            }

            /*$hariTambahan = 0;

            if ($tujuanPenilaian == 'RAP') {
                $hariTambahan = 2;
            } else {
                if ($statusPembayaran == 'sudah_bayar') {
                    $hariTambahan = 1; // H+1 untuk yang sudah bayar
                } else {
                    $hariTambahan = 2; // H+2 untuk yang belum bayar
                }
            }*/

            $tanggalMulai = $item->waktu_penilaian;

            if ($tanggalMulai) {
                if (!$tanggalMulai instanceof Carbon) {
                    $tanggalMulai = Carbon::parse($tanggalMulai);
                }
                $hariKerjaBerikutnya = hitungHariKerja($tanggalMulai->toDateString(), $tanggalMulai->copy()->addDays(1));
                $hariKerjaBerikutnya = max($hariKerjaBerikutnya, 1);
                $tanggalMulai = $tanggalMulai->copy()->addDays($hariKerjaBerikutnya);

                // Konversi string tanggal ke objek Carbon jika belum
                if (!$tanggalMulai instanceof Carbon) {
                    $tanggalMulai = Carbon::parse($tanggalMulai);
                }

                // Hitung tanggal selesai berdasarkan hari tambahan
                $tanggalSelesai = $tanggalMulai->copy()->addDays($hari);
                $tanggalPaparan = $tanggalMulai->copy()->addDays($hariPaparan);

                // Hitung hari kerja
                $hariKerja = hitungHariKerja($tanggalMulai->toDateString(), $tanggalSelesai->toDateString());
                $hariKerja = max($hariKerja, $hari);

                $hariKerjaPaparan = hitungHariKerja($tanggalMulai->toDateString(), $tanggalPaparan->toDateString());
                $hariKerjaPaparan = max($hariKerjaPaparan, $hariPaparan);

                // Set due date SLA
                $dueDateSla = $tanggalMulai->copy()->addDays($hariKerja);
                $dueDateSlaPaparan = $tanggalMulai->copy()->addDays($hariKerjaPaparan);

                // Cek apakah sudah melewati due date
                /*if ($now->greaterThan($dueDateSla)) {
                    $item->due_date_sla = null;
                } else {
                    $item->due_date_sla = $dueDateSla->toDateString();
                }*/

                $item->due_date_sla = $dueDateSla->toDateString();
                $item->paparan = $dueDateSlaPaparan->toDateString();
            } else {
                $item->due_date_sla = null;
                $item->paparan = null;

            }

            return $item;
        });

        $filteredRecords = $data->count();
        $pageCount = ceil($totalRecords / $size);

        // Return data dalam bentuk JSON
        return response()->json([
            'draw'            => $request->get('draw'),
            'recordsTotal'    => $totalRecords,
            'recordsFiltered' => $filteredRecords,
            'pageCount'       => $pageCount,
            'page'            => $page,
            'totalCount'      => $totalRecords,
            'data'            => $data
        ]);
    }

}
