<?php

namespace App\Http\Controllers;

use App\Models\ContactPoint;
use App\Models\PointTransaction;
use App\Imports\PointImport;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ContactPointController extends Controller
{
    // GET /contact-points
    public function index(Request $request)
    {
        $query = ContactPoint::with('contact.type')
            ->whereHas('contact.type', function ($q) {
                $q->where('category', 'customer');
            });

        if (!empty($request->start_date) && !empty($request->end_date)) {
            $startDate = date('Y-m-d', strtotime($request->start_date));
            $endDate = date('Y-m-d', strtotime($request->end_date));

            $query->whereBetween('last_updated', [$startDate, $endDate]);
        }

        $query->orderBy('total_point', 'desc');
        $data = $query->get();

        return response([
            'success' => true,
            'data' => $data,
        ], 200);
    }

    public function pointPage(Request $request)
    {
        $query = ContactPoint::with('contact.type')
            ->whereHas('contact.type', function ($q) {
                $q->where('category', 'customer');
            })
            ->where('contact_id', '!=', 25);

        // Search filter
        if (!empty($request->search)) {
            $search = $request->search;

            $query->whereHas('contact', function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%");
            });
        }

        // Date filter
        if (!empty($request->start_date) && !empty($request->end_date)) {
            $startDate = date('Y-m-d', strtotime($request->start_date));
            $endDate = date('Y-m-d', strtotime($request->end_date));

            $query->whereBetween('last_updated', [$startDate, $endDate]);
        }

        $perPage = $request->input('limit', 20);

        $query->orderBy('total_point', 'desc');

        $data = $query->paginate($perPage);

        return response([
            'success' => true,
            'data' => $data->items(),
            'pagination' => [
                'current_page' => $data->currentPage(),
                'last_page'    => $data->lastPage(),
                'per_page'     => $data->perPage(),
                'total'        => $data->total(),
            ]
        ], 200);
    }

    // GET /contact-points/{id}
    public function show($id)
    {
        $data = ContactPoint::with('contact')
            ->where('contact_id', $id)
            ->first();

        if (!$data) {
            return response([
                'success' => false,
                'message' => 'Data not found',
            ], 404);
        }

        return response([
            'success' => true,
            'data' => $data,
        ], 200);
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'total_point' => 'required|numeric',
            'date'        => 'required',
            'staff'       => 'required',
            'reference'   => 'nullable',
        ]);

        $point = ContactPoint::find($id);

        if (!$point) {
            return response()->json([
                'message' => 'Data tidak ditemukan.'
            ], 404);
        }

        DB::beginTransaction();

        try {
            $oldPoint = $point->total_point;
            $newPoint = $request->total_point;

            $selisih = $newPoint - $oldPoint;

            $point->total_point  = $newPoint;
            $point->last_updated = date("Y-m-d", strtotime($request->date));
            $point->save();

            $pointtransaction = new PointTransaction();
            $pointtransaction->customer_id = $point->contact_id;
            $pointtransaction->type        = 'adjust';
            $pointtransaction->point       = $selisih;
            $pointtransaction->staff       = $request->staff;
            $pointtransaction->reference   = $request->reference;
            $pointtransaction->date        = date("Y-m-d", strtotime($request->date));
            $pointtransaction->save();

            DB::commit();

            return response([
                'success' => true,
                'data' => $point,
            ], 200);
        } catch (\Exception $e) {
            DB::rollback();

            return response([
                'success' => false,
                'message' => 'Terjadi kesalahan saat memperbarui point: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function resetPointPersonal(Request $request, $id)
    {
        $request->validate([
            'date'  => 'required|date',
            'staff' => 'required',
        ]);

        $point = ContactPoint::find($id);

        if (!$point) {
            return response()->json([
                'message' => 'Data tidak ditemukan.'
            ], 404);
        }

        if ($point->total_point <= 0) {
            return response()->json([
                'message' => 'Total poin sudah nol, tidak ada yang di-reset.'
            ], 200);
        }

        $currentPoint = $point->total_point;
        $resetDate = date("Y-m-d", strtotime($request->date));

        // Reset point
        $point->total_point = 0;
        $point->last_updated = $resetDate;
        $point->save();

        // Tambah transaksi expire
        $transactionPoint = new PointTransaction();
        $transactionPoint->customer_id = $point->contact_id;
        $transactionPoint->type        = 'expire';
        $transactionPoint->point       = -$currentPoint;
        $transactionPoint->date        = $resetDate;
        $transactionPoint->staff       = $request->staff;
        $transactionPoint->save();

        return response()->json([
            'success' => true,
            'message' => 'Poin berhasil di-reset untuk contact ini.',
            'data' => $point
        ], 200);
    }

    public function resetAllPoints(Request $request)
    {
        $request->validate([
            'date'  => 'required|date',
            'staff' => 'required',
        ]);

        $date = date("Y-m-d", strtotime($request->date));

        $points = ContactPoint::where('total_point', '>', 0)->get();

        if ($points->isEmpty()) {
            return response()->json([
                'message' => 'Tidak ada data point yang perlu di-reset.'
            ], 200);
        }

        foreach ($points as $point) {
            $currentPoint = $point->total_point;

            // Reset point
            $point->total_point = 0;
            $point->last_updated = $date;
            $point->save();

            // Tambah transaksi expire
            $transactionPoint = new PointTransaction();
            $transactionPoint->customer_id = $point->contact_id;
            $transactionPoint->type        = 'expire';
            $transactionPoint->point       = -$currentPoint;
            $transactionPoint->date        = $date;
            $transactionPoint->staff       = $request->staff;
            $transactionPoint->save();
        }

        return response([
            'success' => true,
            'message' => 'Berhasil reset semua point dan menambahkan transaksi expire.'
        ], 200);
    }

    public function importPoints(Request $request)
    {
        $request->validate([
            'file' => 'required|file|mimes:xlsx,xls',
            'date' => 'required',
            'staff' => 'required',
        ]);

        try {
            Excel::import(new PointImport($request->date, $request->staff), $request->file('file'));

            return response([
                'success' => true,
                'message' => 'Import berhasil.',
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Gagal memproses file.',
                'error' => $e->getMessage(),
            ], 500);
        }
    }
}
