<?php

namespace App\Http\Controllers\Api;

use App\Models\Anak;
use App\Models\StatistikAnak;
use App\Http\Resources\StatistikResource;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
use DateTime;
use DB;

class AnakController extends ApiBaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function indexWithOrangTua()
    {
        $orangTua = User::getUser(Auth::user());
        $fiveNineMonthsAgo = Carbon::now()->subMonths(60)->format('Y-m-d');
        $anak = $orangTua->anak()->whereDate('tanggal_lahir', '>', $fiveNineMonthsAgo)->orderBy('tanggal_lahir', 'asc')->get();

        foreach ($anak as $key => $item) {
            $item->anak_ke = $key + 1;
        }

        return $this->successResponse("data anak", $anak);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
   public function indexWithKaderPosyandu()
    {
        $kaderPosyandu = User::getUser(Auth::user());
        $fiveNineMonthsAgo = Carbon::now()->subMonths(60)->format('Y-m-d');
    
        // Eager load the orangTua relationship and filter only approved children
        $anak = $kaderPosyandu->posyandu->anak()
            ->whereDate('tanggal_lahir', '>', $fiveNineMonthsAgo)
            ->where('status', 1) // Filter hanya anak yang di-approve
            ->with('orangTua') // Use correct relationship name
            ->get();
    
        foreach ($anak as $item) {
            $statistik = $item->statistik()->orderBy('date', 'desc')->get();
            if (count($statistik) == 0) {
                $item->status_berat_terakhir = null;
                $item->status_tinggi_terakhir = null;
                $item->status_lingkaran_kepala_terakhir = null;
                $item->status_gizi_terakhir = null;
                // Use nama_orang_tua from Anak, fallback to orangTua->nama
                $item->nama_ortu = $item->nama_orang_tua ?? ($item->orangTua ? $item->orangTua->nama : null);
                continue;
            }
    
            $statistik = StatistikResource::collection($statistik);
            $json = json_encode($statistik[0]);
            $statik = json_decode($json);
    
            $item->status_berat_terakhir = $statik->statistik->berat;
            $item->status_tinggi_terakhir = $statik->statistik->tinggi;
            $item->status_lingkaran_kepala_terakhir = $statik->statistik->lingkar_kepala;
            $item->status_gizi_terakhir = $statik->statistik->gizi;
            // Use nama_orang_tua from Anak, fallback to orangTua->nama
            $item->nama_ortu = $item->nama_orang_tua ?? ($item->orangTua ? $item->orangTua->nama : null);
        }
    
        return $this->successResponse("data anak", $anak);
    }

    public function showOrangTua()
    {
        $kader = User::getUser(Auth::user());

        if (!$kader->posyandu) {
            return $this->errorResponse("Kader tidak terkait dengan posyandu", 404);
        }

        // Get parents with role 'ORANG_TUA' and associated with the kader's posyandu
        $orangTua = User::whereHas('posyandu', function ($query) use ($kader) {
            $query->where('id', $kader->posyandu->id);
        })
            ->whereHas('role', function ($query) {
                $query->where('role', 'ORANG_TUA');
            })
            ->where('id', '!=', $kader->id)
            ->get();

        if ($orangTua->isEmpty()) {
            return $this->successResponse("Tidak ada data orang tua", []);
        }

        return $this->successResponse("data orang tua", $orangTua);
    }

    public function approveOrangTua(Request $request, $id)
    {
        $kader = User::getUser(Auth::user());

        if (!$kader->posyandu) {
            return $this->errorResponse("Kader tidak terkait dengan posyandu", 404);
        }

        // Find the parent with the same posyandu and role 'ORANG_TUA'
        $orangTua = User::whereHas('posyandu', function ($query) use ($kader) {
            $query->where('id', $kader->posyandu->id);
        })
            ->whereHas('role', function ($query) {
                $query->where('role', 'ORANG_TUA');
            })
            ->where('id', $id)
            ->firstOrFail();

        // Validate the status input
        $request->validate([
            'status' => 'required|in:0,1',
        ]);

        // Update the status
        $orangTua->status = $request->status;
        $orangTua->save();

        return $this->successResponse("Status orang tua berhasil diperbarui", $orangTua);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storeWithOrangTua(Request $request)
    {
        $user = Auth::user();
        $validator = validator($request->all(), [
            'nama' => ['required', 'string', 'min:3'],
            'panggilan' => ['string'],
            'tanggal_lahir' => ['required', 'date'],
            'gender' => ['required', Rule::in(['LAKI_LAKI', 'PEREMPUAN'])],
            'image' => ['string'],
        ]);

        if ($validator->fails()) {
            return $this->errorValidationResponse("Gagal Input Data Anak", $validator->errors());
        }

        $anak = Anak::create([
            'nama' => $request->nama,
            'panggilan' => $request->panggilan,
            'tanggal_lahir' => $request->tanggal_lahir,
            'alamat' => $request->alamat,
            'gender' => $request->gender,
            'image' => $request->image,
            'id_posyandu' => $user->id_posyandu,
            'id_desa' => $user->id_desa,
            'id_orang_tua' => $user->id,
            'status'=>false
        ]);

        $anak->save();

        return $this->successResponse("Success");
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storeWithKaderPosyanduExcel(Request $request)
    {
        $user = Auth::user();
        $validator = validator($request->all(), [
            'file' => ['required', 'file', 'mimes:xlsx,xls,csv'],
        ]);

        if ($validator->fails()) {
            return $this->errorValidationResponse("validation failed", $validator->errors());
        }

        $file = $request->file('file');
        \Log::info('Uploaded file details:', [
            'name' => $file->getClientOriginalName(),
            'extension' => $file->getClientOriginalExtension(),
            'mime' => $file->getMimeType(),
        ]);

        $extension = strtolower($file->getClientOriginalExtension());
        $path = $file->storeAs('temp', $file->getClientOriginalName(), 'local');
        $fullPath = storage_path('app/' . $path);

        try {
            // Use the injected Excel instance
            $data = $this->excel->toArray(null, $fullPath, null, $readerType = null);

            if (empty($data) || empty($data[0])) {
                return $this->errorValidationResponse("Invalid file", ["File is empty or not in the expected format."]);
            }

            $z_score = new HitungZScoreController();

            foreach ($data[0] as $row) {
                if ($row[0] != 'No' && !empty($row[0])) {
                    $id_ortu = DB::table('users')->where('nama', '=', $row[6])->value('id');
                    if (!$id_ortu) {
                        \Log::error("Parent not found for name: {$row[6]}");
                        continue;
                    }

                    $gender = '';
                    if (strtolower($row[5]) === 'l') {
                        $gender = 'LAKI_LAKI';
                    } elseif (strtolower($row[5]) === 'p') {
                        $gender = 'PEREMPUAN';
                    }

                    $birthDate = DateTime::createFromFormat('Y-m-d', $row[3]);
                    $statDate = DateTime::createFromFormat('Y-m-d', $row[7]);
                    if (!$birthDate || !$statDate) {
                        \Log::error("Invalid date format for row: " . json_encode($row));
                        continue;
                    }

                    DB::beginTransaction();
                    try {
                        $anak = Anak::create([
                            'nama' => $row[1],
                            'panggilan' => $row[2],
                            'tanggal_lahir' => $birthDate,
                            'alamat' => $row[4],
                            'gender' => $gender,
                            'id_orang_tua' => $id_ortu,
                            'id_posyandu' => $user->id_posyandu,
                            'id_desa' => $user->id_desa,
                        ]);

                        $hitung_berat = $z_score->HitungZScoreBerat($row[8]);
                        $hitung_tinggi = $z_score->HitungZScoreTinggi($row[9]);
                        $hitung_LiLA = $z_score->HitungZScoreLiLA($row[10]);

                        StatistikAnak::create([
                            'id_anak' => $anak->id,
                            'date' => $statDate,
                            'berat' => $row[8],
                            'tinggi' => $row[9],
                            'lingkar_kepala' => $row[10],
                            'z_score_berat' => $hitung_berat['z_score_berat'],
                            'z_score_tinggi' => $hitung_tinggi['z_score_tinggi'],
                            'z_score_lingkar_kepala' => $hitung_LiLA['z_score_lingkar_kepala'],
                            'status_berat_badan' => $hitung_berat['status_berat_badan'],
                            'status_tinggi_badan' => $hitung_tinggi['status_tinggi_badan'],
                            'status_lingkar_kepala' => $hitung_LiLA['status_lingkar_kepala'],
                        ]);

                        DB::commit();
                    } catch (\Exception $e) {
                        DB::rollBack();
                        \Log::error("Error processing row: " . $e->getMessage());
                        continue;
                    }
                }
            }

            \File::delete($fullPath);
            return $this->successResponse("Success");
        } catch (\Exception $e) {
            \File::delete($fullPath);
            \Log::error("Excel processing error: " . $e->getMessage());
            return $this->errorValidationResponse("Error processing file", [$e->getMessage()]);
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storeWithKaderPosyandu(Request $request)
    {
        $user = Auth::user();
        $validator = validator($request->all(), [
            'nama' => ['required', 'string', 'min:3'],
            'panggilan' => ['string'],
            'tanggal_lahir' => ['required', 'date'],
            'alamat' => ['string'],
            'gender' => ['required', Rule::in(['LAKI_LAKI', 'PEREMPUAN'])],
            'image' => ['string'],
            'id_orang_tua' => ['required'],
        ]);

        if ($validator->fails()) {
            return $this->errorValidationResponse("Gagal Input Data Anak", $validator->errors());
        }

        $anak = new Anak;

        $anak->fill([
            'nama' => $request->nama,
            'panggilan' => $request->panggilan,
            'tanggal_lahir' => $request->tanggal_lahir,
            'alamat' => $request->alamat,
            'gender' => $request->gender,
            'image' => $request->image,
            'id_orang_tua' => $request->id_orang_tua,
            'id_posyandu' => $user->id_posyandu,
            'id_desa' => $user->id_desa,
            'status' => true, // Set status to true by default
        ]);

        $anak->save();

        return $this->successResponse("Success");
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Anak  $anak
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $anak = Anak::findOrFail($id);

        return $this->successResponse("Data Anak", $anak);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Anak  $anak
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $anak = Anak::findOrFail($id);
        $anak->fill($request->all());
        $anak->save();

        return $this->successResponse("Success Update Data Anak", $anak);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Anak  $anak
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $statistik = StatistikAnak::where('id_anak', $id);
        $statistik->delete();

        $anak = Anak::findOrFail($id);
        $anak->delete();

        return $this->successResponse("Success Delete Data Anak");
    }

    /**
     * Export data anak to CSV without statistics.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function exportDataAnakCSV2(Request $request)
    {
        $kaderPosyandu = User::getUser(Auth::user());
        $fiveNineMonthsAgo = Carbon::now()->subMonths(60)->format('Y-m-d');

        // Query anak data
        $query = $kaderPosyandu->posyandu->anak()
            ->whereDate('tanggal_lahir', '>', $fiveNineMonthsAgo)
            ->with('orangTua');

        $anak = $query->get();

        if ($anak->isEmpty()) {
            return $this->errorNotFound("Data anak tidak tersedia untuk diekspor");
        }

        // Get posyandu name
        $posyanduName = $kaderPosyandu->posyandu->nama ?? 'Posyandu Tidak Diketahui';

        // Format data for export
        $data = $anak->map(function ($item) {
            return [
                'nama' => $item->nama,
                'tanggal_lahir' => $item->tanggal_lahir,
                'umur' => Carbon::now()->diffInMonths(Carbon::parse($item->tanggal_lahir)) . ' Bulan',
                'gender' => $item->gender === 'LAKI_LAKI' ? 'Laki-laki' : 'Perempuan',
                'alamat' => $item->alamat,
                'nama_ortu' => $item->nama_orang_tua ?? ($item->orangTua ? $item->orangTua->nama : null),
            ];
        });

        $fileName = 'data-anak.csv';

        $headers = [
            "Content-type" => "text/csv",
            "Content-Disposition" => "attachment; filename=$fileName",
            "Pragma" => "no-cache",
            "Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
            "Expires" => "0",
        ];

        $columns = [
            'Nama Anak',
            'Tanggal Lahir',
            'Umur',
            'Jenis Kelamin',
            'Alamat',
            'Nama Orang Tua',
        ];

        $callback = function () use ($posyanduName, $columns, $data) {
            $file = fopen('php://output', 'w');
            // Write posyandu name
            fputcsv($file, ['Posyandu: ' . $posyanduName]);
            // Write empty row
            fputcsv($file, []);
            // Write column headers
            fputcsv($file, $columns);
            // Write data
            foreach ($data as $row) {
                fputcsv($file, [
                    $row['nama'],
                    $row['tanggal_lahir'],
                    $row['umur'],
                    $row['gender'],
                    $row['alamat'],
                    $row['nama_ortu'],
                ]);
            }
            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    public function exportDataAnakCSV(Request $request)
    {
        // Validate input
        $validator = validator($request->all(), [
            'desa' => ['required', 'integer'], // Ensure desa is provided
            'bulan' => ['required', 'string'], // Ensure bulan is provided
            'tahun' => ['required', 'string'], // Ensure tahun is provided
            'id' => ['nullable', 'string'], // Allow id to be nullable or string (for "all" or specific id_posyandu)
        ]);
    
        if ($validator->fails()) {
            return $this->errorValidationResponse("Gagal Ekspor Data", $validator->errors());
        }
    
        // Query children based on desa (village)
        $anak = Anak::where('id_desa', $request->desa);
    
        // If id is provided and not "all", filter by specific posyandu
        if (!is_null($request->id) && $request->id !== 'all') {
            $anak = $anak->where('id_posyandu', $request->id);
        }
    
        // Fetch the data
        $anak = $anak->get();
    
        // Collect statistics for the specified month and year
        $collection = [];
        foreach ($anak as $data) {
            foreach ($data->statistik as $statistik) {
                if (Carbon::parse($statistik->date)->month == $request->bulan && Carbon::parse($statistik->date)->year == $request->tahun) {
                    array_push($collection, $statistik);
                }
            }
        }
    
        // Check if data is available
        if (empty($collection)) {
            return $this->errorNotFound("Data Export tidak tersedia");
        }
    
        // Define CSV filename and headers
        $fileName = 'data-anak.csv';
        $headers = [
            "Content-type" => "text/csv",
            "Content-Disposition" => "attachment; filename=$fileName",
            "Pragma" => "no-cache",
            "Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
            "Expires" => "0"
        ];
    
        // Define CSV columns
        $columns = [
            'Nama',
            'JK',
            'Tanggal Lahir',
            'Nama Orang Tua',
            'Posyandu',
            'Alamat',
            'Tanggal Pengukuran',
            'Berat',
            'Tinggi',
            'Lingkar Kepala',
            'BB/U',
            'Z - BB/U',
            'TB/U',
            'Z - TB/U',
            'LK/U',
            'Z - LK/U'
        ];
    
        // Stream the CSV
        $callback = function () use ($collection, $columns) {
            $file = fopen('php://output', 'w');
            fputcsv($file, $columns);
    
            foreach ($collection as $data) {
                $row = [
                    'Nama' => $data->anak->nama ?? 'N/A',
                    'JK' => $data->anak->gender ?? 'N/A',
                    'Tanggal Lahir' => $data->anak->tanggal_lahir ?? 'N/A',
                    'Nama Orang Tua' => $data->anak->orangTua->nama ?? 'N/A',
                    'Posyandu' => $data->anak->posyandu->nama ?? 'N/A',
                    'Alamat' => $data->anak->posyandu->alamat ?? 'N/A',
                    'Tanggal Pengukuran' => $data->date ?? 'N/A',
                    'Berat' => $data->berat ?? 'N/A',
                    'Tinggi' => $data->tinggi ?? 'N/A',
                    'Lingkar Kepala' => $data->lingkar_kepala ?? 'N/A',
                    'BB/U' => $this->beratBadan($data->z_score_berat) ?? 'N/A',
                    'ZS - BB/U' => $data->z_score_berat ?? 'N/A',
                    'TB/U' => $this->tinggiBadan($data->z_score_tinggi) ?? 'N/A',
                    'ZS - TB/U' => $data->z_score_tinggi ?? 'N/A',
                    'LK/U' => $this->lingkarKepala($data->z_score_lingkar_kepala) ?? 'N/A',
                    'ZS - LK/U' => $data->z_score_lingkar_kepala ?? 'N/A'
                ];
    
                fputcsv($file, [
                    $row['Nama'],
                    $row['JK'],
                    $row['Tanggal Lahir'],
                    $row['Nama Orang Tua'],
                    $row['Posyandu'],
                    $row['Alamat'],
                    $row['Tanggal Pengukuran'],
                    $row['Berat'],
                    $row['Tinggi'],
                    $row['Lingkar Kepala'],
                    $row['BB/U'],
                    $row['ZS - BB/U'],
                    $row['TB/U'],
                    $row['ZS - TB/U'],
                    $row['LK/U'],
                    $row['ZS - LK/U']
                ]);
            }
    
            fclose($file);
        };
    
        return response()->stream($callback, 200, $headers);
    }

    public function beratBadan($ZScoreBerat)
    {
        if ($ZScoreBerat <= -3) {
            return 'Sangat Kurus';
        } else if ($ZScoreBerat > -3 && $ZScoreBerat <= -2) {
            return 'Kurus';
        } else if ($ZScoreBerat > -2 && $ZScoreBerat <= 2) {
            return 'Normal';
        } else if ($ZScoreBerat > 2) {
            return 'Gemuk';
        }
    }

    public function tinggiBadan($ZScoreTinggi)
    {
        if ($ZScoreTinggi <= -3) {
            return 'Sangat Pendek';
        } else if ($ZScoreTinggi > -3 && $ZScoreTinggi <= -2) {
            return 'Pendek';
        } else if ($ZScoreTinggi > -2 && $ZScoreTinggi <= 2) {
            return 'Normal';
        } else if ($ZScoreTinggi > 2) {
            return 'Tinggi';
        }
    }

    public function lingkarKepala($ZScoreLingkarKepala)
    {
        if ($ZScoreLingkarKepala > 2) {
            return 'Makrosefali';
        } else if ($ZScoreLingkarKepala > -2 && $ZScoreLingkarKepala <= 2) {
            return 'Normal';
        } else if ($ZScoreLingkarKepala < -2) {
            return 'Mikrosefali';
        }
    }
    public function approveAllAnak()
    {
        try {
            // Update semua anak menjadi status = true (1)
            Anak::query()->update(['status' => true]);

            return $this->successResponse("Semua data anak berhasil disetujui (status = true).");
        } catch (\Exception $e) {
            return $this->errorResponse("Gagal mengupdate status anak", 500, $e->getMessage());
        }
    }
    public function approveAnak($id)
    {
        try {
            // Find the child by ID
            $anak = Anak::find($id);

            // Check if the child exists
            if (!$anak) {
                return $this->errorResponse("Data anak tidak ditemukan", 404);
            }

            // Update the child's status to true (1)
            $anak->update(['status' => true]);

            return $this->successResponse("Data anak berhasil disetujui (status = true).");
        } catch (\Exception $e) {
            return $this->errorResponse("Gagal mengupdate status anak", 500, $e->getMessage());
        }
    }
    public function getAnakBelumDisetujui()
    {
        try {
            $user = User::getUser(Auth::user());

            if (!$user) {
                return $this->errorResponse("User tidak ditemukan", 401);
            }

            $anak = Anak::where('status', false)
                ->where('id_posyandu', $user->id_posyandu)
                ->with(['orangTua', 'posyandu', 'desa'])
                ->get();

            if ($anak->isEmpty()) {
                return $this->successResponse("Tidak ada anak yang belum disetujui.", []);
            }

            return $this->successResponse("Daftar anak yang belum disetujui", $anak);
        } catch (\Exception $e) {
            return $this->errorResponse("Gagal mengambil data anak", 500, $e->getMessage());
        }
    }
}
