<?php

namespace App\Helpers;

use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use PHPMailer\PHPMailer\PHPMailer;
use Illuminate\Support\Facades\DB;
use App\Models\Member;
use App\Models\User;
use App\Models\Service;

class Helper
{
    public static function genderNormalization($anyGenderCode = '-')
    {

        if ($anyGenderCode == 'M') {
            return 'male';
        } else if ($anyGenderCode == 'F') {
            return 'female';
        } else if ($anyGenderCode == 'O') {
            return 'others';
        } else if ($anyGenderCode == 'U') {
            return 'unknown';
        } else {
            return '-';
        }
    }

    public static function maritalNormalization($code)
    {
        if ($code == 'M') {
            return 'Married';
        } else if ($code == 'D') {
            return 'Divorced';
        } else if ($code == 'S') {
            return 'Single';
        } else {
            return '-';
        }
    }

    public static function genderPerson($anyGenderCode)
    {
        if ($anyGenderCode == 'M') {
            return 'L';
        } else if ($anyGenderCode == 'F') {
            return 'P';
        } else if ($anyGenderCode == 'O') {
            return 'others';
        } else if ($anyGenderCode == 'U') {
            return 'unknown';
        } else {
            return '-';
        }
    }

    public static function memberType($code)
    {
        if ($code == 'P') {
            return 'Principal';
        } else if ($code == 'D') {
            return 'Dependent';
        } else {
            '-';
        }
    }

    public static function relationWithPrincipal($code)
    {
        if ($code == 'H') {
            return 'Husbund';
        } else if ($code == 'W') {
            return 'Wife';
        } else if ($code == 'S') {
            return 'Son';
        } else if ($code == 'D') {
            return 'Daughter';
        } else {
            '-';
        }
    }

    public static function principalName($code)
    {
        $principalName = Member::where('member_id', $code)->get()->first();
        return $principalName->name;
    }

    public static function userName($id)
    {
        $user = User::find($id);
        if ($user) {
            $person = $user->person;
            if ($person) {
                return $person->name;
            } else {
                return 'Person not found for this user.';
            }
        } else {
            return 'User not found.';
        }
        
    }

    public static function serviceName($code)
    {
        $serviceName = Service::where('code', $code)->get()->first();
        if ($serviceName){
            return $serviceName->name;
        } else {
            return '-';
        }
    }

    public static function paginateResources($resource)
    {
        return [
            'current_page' => $resource->currentPage(),
            'data' => $resource->items(),
            'first_page_url' => '',
            'from' => $resource->firstItem(),
            'last_page' => $resource->lastPage(),
            'last_page_url' => '',
            'links' => $resource->links(null, $resource->items()),
            'next_page_url' => $resource->nextPageUrl(),
            'per_page' => $resource->perPage(),
            'total' => $resource->total()
        ];
    }

    public static function dailyAvailabilitiesToDate($dailyAvailabilities, $startDate, $endDate = null)
    {

        Carbon::setLocale('id');

        $startDate = Carbon::parse($startDate);
        if (empty($endDate)) {
            $endDate = $startDate;
        } else {
            $endDate = Carbon::parse($endDate);
        }
        $ranges = CarbonPeriod::create($startDate, $endDate);

        $datesAvailabilities = [];
        foreach ($ranges as $date) {

            $datesAvailabilities[$date->format('Y-m-d')][] = [
                'date' => $date->format('Y-m-d'),
                'day' => $date->dayName,
                'slot' => $dailyAvailabilities[$date->dayName],
                'timezone' => 'WIB'
            ];
        }

        return $datesAvailabilities;
    }

    public static function differenceTime($startDate, $endDate){
        $startTime = Carbon::parse($startDate);
        $endTime = Carbon::parse($endDate);

        $interval = $endTime->diff($startTime);
        return $interval->format('%d days, %h hours and %i minutes');
    }

    public static function dailyAvailabilities($availabilities)
    {
        $hours = [
            'Pagi' => [],
            'Siang' => [],
            'Sore' => [],
            'Petang' => [],
            'Malam' => []
        ];

        foreach ($availabilities as $availability) {
            $time = explode(':', $availability->start_time);

            if (count($availability->days)) {
                foreach ($availability->days as $key => $day) {
                    $periods = CarbonPeriod::create(now(), now()->lastOfMonth()->addDays(1))
                        ->filter(function (Carbon $date) use ($day) {
                            switch ($day->day) {
                                case 'Senin':
                                    return $date->isMonday();
                                    break;
                                case 'Selasa':
                                    return $date->isTuesday();
                                    break;
                                case 'Rabu':
                                    return $date->isWednesday();
                                    break;
                                case 'Kamis':
                                    return $date->isThursday();
                                    break;
                                case 'Jumat':
                                    return $date->isFriday();
                                    break;
                                case 'Sabtu':
                                    return $date->isSaturday();
                                    break;
                                case 'Minggu':
                                    return $date->isSunday();
                                    break;
                            }
                        })->toArray();
                }

                foreach ($periods as $day) {
                    foreach ($hours as $hour => $value) {
                        if (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(05, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(10, 59, 00)->timestamp && $hour === "Pagi") {
                            $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(11, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(15, 00, 00)->timestamp && $hour === "Siang") {
                            $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(15, 01, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(18, 00, 00)->timestamp && $hour === "Sore") {
                            $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(18, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(19, 00, 00)->timestamp && $hour === "Petang") {
                            $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(19, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(24, 00, 00)->timestamp && $hour === "Malam") {
                            $schedules[Carbon::create($day)->day][$hour][] = substr($availability->start_time, 0, -3);
                        }
                    }
                }
            } else {
                foreach ($hours as $hour => $value) {
                    for ($i = Carbon::now()->day; $i <= Carbon::now()->daysInMonth; $i++) {
                        if (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(05, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(10, 59, 00)->timestamp && $hour === "Pagi") {
                            $schedules[$i][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(11, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(15, 00, 00)->timestamp && $hour === "Siang") {
                            $schedules[$i][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(15, 01, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(18, 00, 00)->timestamp && $hour === "Sore") {
                            $schedules[$i][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(18, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(19, 00, 00)->timestamp && $hour === "Petang") {
                            $schedules[$i][$hour][] = substr($availability->start_time, 0, -3);
                        } elseif (Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp >= Carbon::createFromTime(19, 00, 00)->timestamp && Carbon::createFromTime($time[0], $time[1], $time[2])->timestamp <= Carbon::createFromTime(24, 00, 00)->timestamp && $hour === "Malam") {
                            $schedules[$i][$hour][] = substr($availability->start_time, 0, -3);
                        }
                    }
                }
            }
        }

        return (object) $schedules;
    }

    public static function currencyIdrFormat(int $price)
    {
        return "Rp. " . number_format($price, 0, ',', '.');
    }

    /**
     * Helper Response Json.
     *
     * @param  array|object  $data
     * @param  int  $statusCode
     * @param  string  $message
     * @return JsonResponse
     */
    public static function responseJson(array|object $data = [], string $status = 'success', int $statusCode = Response::HTTP_OK, string $message = 'Data berhasil di ambil'): JsonResponse
    {
        return response()->json([
            'status' => $status,
            'statusCode' => $statusCode,
            'message' => $message,
            'data' => $data,
        ], $statusCode);
    }

    public static function validatePhoneNumber($phoneNumber)
    {
        // Menghapus semua karakter selain angka dan +
        $cleanedNumber = preg_replace('/[^0-9+]/', '', $phoneNumber);

        // Memeriksa apakah nomor telepon hanya terdiri dari angka dan +
        if ($cleanedNumber == $phoneNumber) {
            // Nomor telepon valid
            return true;
        } else {
            // Nomor telepon tidak valid
            return false;
        }
    }

    public static function formatRupiah($angka)
    {
        return "Rp " . number_format($angka, 0, ',', '.');
    }

    public static function sPaymentMethod($id)
    {
        $sPaymentMethod = [
            1 => 'Pribadi',
            2 => 'On-Site Payment',
            3 => 'OVO',
            4 => 'Asuransi',
            5 => 'Voucher',
            6 => 'ASO'
        ];

        return $sPaymentMethod[$id];
    }

    public static function formatDateDB($date)
    {
        $convertedDate = Carbon::createFromFormat('d-m-Y', $date)->format('Y-m-d H:i:s');
        return $convertedDate;
    }


    public static function formatDateOnly($date)
    {
        // Membuat objek Carbon dengan tanggal asli dan zona waktu UTC
        $carbonDate = Carbon::createFromFormat('Y-m-d\TH:i:s.u\Z', $date, 'UTC');

        // Mengonversi tanggal ke zona waktu yang diinginkan
        $carbonDate->setTimezone('Asia/Jakarta');

        $convertedDate = $carbonDate->toDateString();
        return $convertedDate;
    }

    public static function formatTimeOnly($date)
    {
        // Membuat objek Carbon dengan tanggal asli dan zona waktu UTC
        $carbonDate = Carbon::createFromFormat('Y-m-d\TH:i:s.u\Z', $date, 'UTC');

        // Mengonversi tanggal ke zona waktu yang diinginkan
        $carbonDate->setTimezone('Asia/Jakarta');

        $convertedDate = $carbonDate->toTimeString();
        return $convertedDate;
    }

    public static function insertNotification($data = array())
    {
        try {
            DB::beginTransaction();
            DB::table('notifications')->insert($data);
            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollback();
            return $e->getMessage();
        }
    }

    public static function sendEmail($data = array())
    {
        // Buat instance PHPMailer
        $mail = new PHPMailer(true);
        try {
            // Server settings
            $mail->isSMTP();
            $mail->Host       = 'smtp.gmail.com';
            $mail->SMTPAuth   = true;
            $mail->Username   = env('EMAIL');
            $mail->Password   = env('PW_EMAIL');
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = 465;
            $mail->SMTPSecure = "ssl";

            // Penerima email
            $mail->setFrom(env('EMAIL'), env('NAME_EMAIL'));
            $mail->addAddress($data['email'], $data['name']);

            // Konten email
            $mail->isHTML(true);
            $mail->Subject = $data['subject'];
            $mail->Body    = $data['body'];

            // Kirim email
            $mail->send();
            return true;
        } catch (\Exception $e) {
            dd($e);
            return ($mail->ErrorInfo);
            return false;
        }
    }

    public static function sendEmailattachData($data = array())
    {
        // Buat instance PHPMailer
        $mail = new PHPMailer(true);
        try {
            // Server settings
            $mail->isSMTP();
            $mail->Host       = 'smtp.gmail.com';
            $mail->SMTPAuth   = true;
            $mail->Username   = env('EMAIL');
            $mail->Password   = env('PW_EMAIL');
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = 465;
            $mail->SMTPSecure = "ssl";

            // Penerima email
            $mail->setFrom(env('EMAIL'), env('NAME_EMAIL'));
            $mail->addAddress($data['email'], $data['name']);

            // Konten email
            $mail->isHTML(true);
            $mail->Subject = $data['subject'];
            $mail->Body    = $data['body'];
            $mail->addAttachment($data['attach'], 'e-card.pdf');

            // Kirim email
            $mail->send();
            return true;
        } catch (\Exception $e) {
            dd($mail->ErrorInfo);
            return ($mail->ErrorInfo);
            return false;
        }
    }

    public static function setCustomPHPIniSettings()
    {
        ini_set('max_execution_time', '-1'); // Waktu untuk execution suatu function atau script
        ini_set('post_max_size', '100M'); // Batas post Yang di Upload
        ini_set('upload_max_filesize', '100M'); // Batas File yang di Upload
        ini_set('max_input_time ', '-1'); // Batas max time menunggu input max 5 menit
        ini_set('memory_limit', '256M');
    }

}
