<?php

namespace App\Http\Controllers;

use App\Models\Notification;
use App\Models\Customer;
use App\Models\TipeNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Yajra\DataTables\DataTables;
use App\Exports\NotifikasiExport;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use DateTime;
use App\Imports\PenerimaImport;
use App\Exports\PenerimaExport;

class NotificationController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('permission:view-notification', ['only' => ['index', 'show', 'listdata']]);
        $this->middleware('permission:create-notification', ['only' => ['create', 'store']]);
        $this->middleware('permission:edit-notification', ['only' => ['edit', 'update']]);
        $this->middleware('permission:delete-notification', ['only' => ['destroy']]);
    }

    public function index(Request $request)
    {
        return view('notification.index');
    }

    public function getParameter(Request $request, $id)
    {
        $tipe = TipeNotification::find($id);

        return response()->json(['parameter' => $tipe->parameter]);
    }

    public function listdata()
    {
        $data = Notification::select('notification.subject as subject', 'notification.description as desc', 'notification.id as id', 'notification.schedule as jam', DB::raw("to_char(notification.schedule_day, 'DD-MM-YYYY') as day"), 'tipe_notification.tipe as tipe')
            ->join('tipe_notification', 'notification.type_id', 'tipe_notification.id')
            ->get();

        return DataTables::of($data)->make(true);
    }
    public function create()
    {
        $notification = new Notification();
        $tipe = TipeNotification::all();
        $schedule = '';
        $hari = [
            0 => 'Hari-H',
            1 => 'H-1',
            2 => 'H-2',
            3 => 'H-3',
            4 => 'H-4',
            5 => 'H-5',
            6 => 'H-6',
            7 => 'H-7',
        ];

        $customers = [];
        return view('notification.create', compact('notification', 'tipe', 'schedule', 'hari', 'customers'));
    }


    public function store(Request $request)
    {

        $schedule_day = $request->input('schedule_day');

        $schedule_day_converted = DateTime::createFromFormat('d-m-Y', $schedule_day);

        if ($schedule_day_converted) {
            $request->merge(['schedule_day' => $schedule_day_converted->format('Y-m-d')]);
        }

        $validateData = $request->validate([
            'type_id' => [
                'required',
                function ($attribute, $value, $fail) {
                    $existingRecord = Notification::withoutTrashed()
                        ->where('type_id', $value)
                        ->where('type_id', [1, 2, 3])
                        ->first();

                    if ($existingRecord) {
                        $fail("Tipe Notifikasi sudah digunakan");
                    }
                },
            ],
            'description' => 'required',
            'subject' => 'required',
            'schedule' => 'required_if:type_id,1,4,5',
            'schedule_day' => 'required_if:type_id,5',
            'reminder' => 'required_if:type_id,4,7',
        ], [
            'type_id.required' => 'Tipe Notifikasi belum diisi',
            'description.required' => 'Deskripsi belum diisi',
            'subject.required' => 'Subjek belum diisi',
            'schedule.required_if' => 'Jam Tayang belum diisi',
            'schedule_day.required_if' => 'Tanggal belum diisi',
            'reminder.required_if' => 'Reminder belum diisi'
        ]);

        $customerIds = $request->has('customer_ids') && is_array($request->customer_ids) ? array_values($request->customer_ids) : null;
        if ($request->type_id == 1) {
            $notification = Notification::create([
                'customer_ids' => $customerIds,
                'subject' => $request->subject,
                'description' => $request->description,
                'type_id' => $request->type_id,
                'created_who' => Auth::user()->name,
                'schedule' => $request->schedule,
            ]);
        } elseif ($request->type_id == 4 || $request->type_id == 7) {
            $notification = Notification::create([
                'customer_ids' => $customerIds,
                'subject' => $request->subject,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'created_who' => Auth::user()->name,
                'schedule' => $request->schedule,
                'reminder' => $request->reminder
            ]);
        } elseif ($request->type_id == 5) {
            $notification = Notification::create([
                'customer_ids' => $customerIds,
                'subject' => $request->subject,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'created_who' => Auth::user()->name,
                'schedule' => $request->schedule,
                'schedule_day' => $request->schedule_day
            ]);
        } elseif ($request->type_id == 2 || $request->type_id == 3 || $request->type_id == 6 || $request->type_id == 8) {
            $notification = Notification::create([
                'customer_ids' => $customerIds,
                'subject' => $request->subject,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'created_who' => Auth::user()->name,
            ]);
        }

        if ($request->action == 'save_and_close') {
            return redirect()->route('notification.index')
                ->with('success', 'Data Berhasil Disimpan');
        } else {
            return redirect()->route('notification.create')
                ->with('success', 'Data Berhasil Disimpan');
        }
    }


    public function show($id)
    {
        $notification = Notification::with('tipe_notifikasi')->where('id', $id)->first();
        if ($notification->schedule_day != null) {
            $day = Carbon::parse($notification->schedule_day)->format('d-m-Y');
        } else {
            $day = ' ';
        }
        $hari = [
            0 => 'Hari-H',
            1 => 'H-1',
            2 => 'H-2',
            3 => 'H-3',
            4 => 'H-4',
            5 => 'H-5',
            6 => 'H-6',
            7 => 'H-7',
        ];
        $reminder = '';
        foreach ($hari as $rem => $value) {
            if ($notification->reminder != null) {
                if ($notification->reminder == $rem) {
                    $reminder = $value;
                }
            } else {
                $reminder = '-';
            }
        }
        $customer = Customer::find($notification->customer_id);
        return view('notification.show', compact('notification', 'customer', 'day', 'reminder'));
    }

    public function edit($id)
    {
        $notification = Notification::find($id);
        if (!empty($notification->schedule_day)) {
            $schedule = Carbon::parse($notification->schedule_day)->format('d-m-Y');
        } else {
            $schedule = '';
        }

        $tipe = TipeNotification::all();
        $hari = [
            0 => 'Hari-H',
            1 => 'H-1',
            2 => 'H-2',
            3 => 'H-3',
            4 => 'H-4',
            5 => 'H-5',
            6 => 'H-6',
            7 => 'H-7',
        ];

        $customerIds = $notification->customer_ids ?? [];
        $customers = Customer::whereIn('customer_id', $customerIds)->get();
        return view('notification.edit', compact('notification', 'tipe', 'schedule', 'hari', 'customers'));
    }


    public function update(Request $request, $id)
    {
        $schedule_day = $request->input('schedule_day');

        $schedule_day_converted = DateTime::createFromFormat('d/m/Y', $schedule_day);

        if ($schedule_day_converted) {
            $request->merge(['schedule_day' => $schedule_day_converted->format('Y-m-d')]);
        }

        $days = Carbon::parse($request->schedule_day)->format('Y-m-d');
        $validateData = $request->validate([
            'type_id' => [
                'required',
                function ($attribute, $value, $fail) use ($id) {
                    $existingRecord = Notification::withoutTrashed()
                        ->where('type_id', $value)
                        ->where('type_id', [1, 2, 3])
                        ->where('id', '!=', $id)
                        ->first();

                    if ($existingRecord) {
                        $fail("Tipe Notifikasi sudah digunakan");
                    }
                },
            ],
            'description' => 'required',
            'subject' => 'required',
            'schedule' => 'required_if:type_id,1,4,5',
            'schedule_day' => 'required_if:type_id,5',
            'reminder' => 'required_if:type_id,4,7',
        ], [
            'type_id.required' => 'Tipe Notifikasi belum diisi',
            'description.required' => 'Deskripsi belum diisi',
            'subject.required' => 'Subjek belum diisi',
            'schedule.required_if' => 'Jam Tayang belum diisi',
            'schedule_day.required_if' => 'Tanggal belum diisi',
            'reminder.required_if' => 'Reminder belum diisi'
        ]);

        $notification = Notification::find($id);
        $customerIds = $request->has('customer_ids') && is_array($request->customer_ids) ? array_values($request->customer_ids) : null;

        if ($request->type_id == 1) {
            $notification->update([
                'subject' => $request->subject,
                'customer_ids' => $customerIds,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'updated_who' => Auth::user()->name,
                'schedule' => $request->schedule,
            ]);
        } elseif ($request->type_id == 4 || $request->type_id == 7) {
            $notification->update([
                'subject' => $request->subject,
                'customer_ids' => $customerIds,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'updated_who' => Auth::user()->name,
                'schedule' => $request->schedule,
                'reminder' => $request->reminder
            ]);
        } elseif ($request->type_id == 5) {

            $notification->update([
                'subject' => $request->subject,
                'customer_ids' => $customerIds,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'updated_who' => Auth::user()->name,
                'schedule' => $request->schedule,
                'schedule_day' => $days
            ]);
        } elseif ($request->type_id == 2 || $request->type_id == 3 || $request->type_id == 6 || $request->type_id == 8) {
            $notification->update([
                'subject' => $request->subject,
                'customer_ids' => $customerIds,
                'description' =>  $request->description,
                'type_id' =>  $request->type_id,
                'updated_who' => Auth::user()->name,
            ]);
        }

        return redirect()->route('notification.index')
            ->with('success', 'Data Berhasil Diubah');
    }
    public function export_all()
    {

        return Excel::download(new NotifikasiExport(), 'data_notifikasi.xlsx');
    }

    public function destroy($id)
    {
        $notification = Notification::find($id);
        $response = [];
        try {
            $notification->delete();
            $response['message'] = 'Data berhasil dihapus.';
            return response()->json($response, 200);
        } catch (\Exception $e) {
            $response['message'] = 'Gagal menghapus data: ' . $e->getMessage();
            return response()->json($response, 500);
        }
    }

    public function cariPenerima(Request $request)
    {
        $query = $request->get('q');

        // Ambil data penerima yang cocok dengan query, misalnya:
        $items = Customer::where(function ($queryBuilder) use ($query) {
            $queryBuilder->where('nama_customer', 'ILIKE', '%' . $query . '%')
                ->orWhere('no_hp', 'ILIKE', '%' . $query . '%');
        })
            ->where('is_active', true)
            ->orderBy('nama_customer')
            ->limit(15)
            ->get();


        return response()->json([
            'items' => $items->map(function ($item) {
                return [
                    'id' => $item->customer_id,
                    'text' => $item->nama_customer . ' / ' . $item->no_hp
                ];
            }),
            'total_count' => $items->count()
        ]);
    }

    public function xuploadPenerima(Request $request)
    {
        $request->validate([
            'excel_file' => 'required|mimes:xlsx,csv'
        ]);

        try {
            // Proses upload dan import
            $import = new PenerimaImport();
            Excel::import($import, $request->file('excel_file'));

            // Ambil nama-nama yang diimport dari class import-nya
            $importedNames = $import->getImportedNames();

            // print_r('masuksini');
            // print_r('<pre>');
            // print_r($importedNames);
            // exit;

            // Ambil customer_id + nama_customer dari database 
            $customers = Customer::where(function ($query) use ($importedNames) {
                $query->whereIn(\DB::raw('LOWER(nama_customer)'), array_map('strtolower', $importedNames))
                    ->orWhereIn(\DB::raw('LOWER(no_hp)'), array_map('strtolower', $importedNames));
            })
                ->where('is_active', true)
                ->select(
                    'customer_id as id',
                    \DB::raw('concat(nama_customer, \' / \', no_hp) as nama')
                )
                ->get();

            return response()->json([
                'success' => true,
                'customers' => $customers
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    public function uploadPenerima(Request $request)
    {
        $request->validate([
            'excel_file' => 'required|mimes:xlsx,csv'
        ]);

        try {
            // Import file
            $import = new PenerimaImport();
            Excel::import($import, $request->file('excel_file'));

            $importedNames = $import->getImportedNames();

            // Cari yang ditemukan
            $customers = Customer::where(function ($query) use ($importedNames) {
                $query->whereIn(\DB::raw('LOWER(nama_customer)'), array_map('strtolower', $importedNames))
                    ->orWhereIn(\DB::raw('LOWER(no_hp)'), array_map('strtolower', $importedNames));
            })
                ->where('is_active', true)
                ->select(
                    'customer_id as id',
                    \DB::raw("LOWER(nama_customer) as nama"),
                    \DB::raw("LOWER(no_hp) as no_hp"),
                    \DB::raw("concat(nama_customer, ' / ', no_hp) as label")
                )
                ->get();

            // Ambil semua nama dan no_hp dari hasil query untuk dibandingkan
            $foundNames = $customers->map(function ($item) {
                return [
                    trim(strtolower($item->nama)),
                    trim(strtolower($item->no_hp))
                ];
            })->flatten()->unique()->toArray();

            // Cari yang tidak ditemukan
            $notFound = array_filter($importedNames, function ($name) use ($foundNames) {
                return !in_array(trim(strtolower($name)), $foundNames);
            });

            if (count($notFound)) {
                // Jika ada yang tidak ditemukan, kembalikan file Excel
                $export = new PenerimaExport($notFound);
                $filename = 'data_tidak_ditemukan.xlsx';

                return Excel::download($export, $filename);
            }

            // Jika semua ditemukan, kirim balik data customer untuk ditambahkan ke selector
            $formatted = $customers->map(function ($cust) {
                return [
                    'id' => $cust->id,
                    'nama' => $cust->label
                ];
            });

            return response()->json([
                'success' => true,
                'customers' => $formatted
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    public function downloadTemplate()
    {
        // Path ke file template Excel yang sudah Anda buat
        $templatePath = storage_path('app/templates/template_excel_penerima_notif.xlsx');

        // Cek apakah file template ada
        if (file_exists($templatePath)) {
            return response()->download($templatePath);
        }

        return response()->json(['message' => 'Template tidak ditemukan.'], 404);
    }
}
