<?php

namespace App\Http\Controllers;

use App\Models\Customer;
use Illuminate\Http\Request;

class CustomerController extends Controller
{
    /**
     * Jenis pelanggan.
     *
     * Catatan:
     * - Value "studio" tetap dipakai agar data lama aman.
     * - Label tampilannya saja diganti dari "Percetakan" menjadi "Instansi".
     */
    private array $memberTypes = [
        'umum' => 'Umum',
        'studio' => 'Instansi',
    ];

    public function __construct()
    {
        $this->middleware(\App\Http\Middleware\PermissionMiddleware::class . ':create customers')->only(['create', 'store']);
        $this->middleware(\App\Http\Middleware\PermissionMiddleware::class . ':edit customers')->only(['edit', 'update']);
        $this->middleware(\App\Http\Middleware\PermissionMiddleware::class . ':delete customers')->only(['destroy']);
    }

    public function index(Request $request)
    {
        $this->authorize('view customers');

        $query = Customer::query();

        if ($request->filled('search')) {
            $search = trim($request->search);

            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', '%' . $search . '%')
                    ->orWhere('phone', 'like', '%' . $search . '%')
                    ->orWhere('email', 'like', '%' . $search . '%');

                if ($this->customerColumnExists('contact_person')) {
                    $q->orWhere('contact_person', 'like', '%' . $search . '%');
                }

                if ($this->customerColumnExists('npwp')) {
                    $q->orWhere('npwp', 'like', '%' . $search . '%');
                }
            });
        }

        if ($request->filled('member_type')) {
            $query->where('member_type', $request->member_type);
        }

        $customers = $query->latest()->paginate(10)->withQueryString();

        return view('pages.customers.index', [
            'title' => 'Data Instansi / Pelanggan',
            'customers' => $customers,
            'memberTypes' => $this->memberTypes,
        ]);
    }

    public function print(Request $request)
    {
        $this->authorize('view customers');

        $query = Customer::query();

        if ($request->filled('search')) {
            $search = trim($request->search);

            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', '%' . $search . '%')
                    ->orWhere('phone', 'like', '%' . $search . '%')
                    ->orWhere('email', 'like', '%' . $search . '%');

                if ($this->customerColumnExists('contact_person')) {
                    $q->orWhere('contact_person', 'like', '%' . $search . '%');
                }

                if ($this->customerColumnExists('npwp')) {
                    $q->orWhere('npwp', 'like', '%' . $search . '%');
                }
            });
        }

        if ($request->filled('member_type')) {
            $query->where('member_type', $request->member_type);
        }

        $customers = $query->orderBy('name')->get();

        return view('pages.customers.customers-print', [
            'title' => 'Cetak Daftar Instansi / Pelanggan',
            'customers' => $customers,
            'memberTypes' => $this->memberTypes,
        ]);
    }

    public function create()
    {
        $this->authorize('create customers');

        return view('pages.customers.form', [
            'title' => 'Tambah Instansi / Pelanggan',
            'customer' => new Customer(),
            'memberTypes' => $this->memberTypes,
        ]);
    }

    public function store(Request $request)
    {
        $this->authorize('create customers');

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'member_type' => 'required|in:umum,studio',
            'contact_person' => 'nullable|string|max:100',
            'phone' => 'required|string|max:20',
            'email' => 'nullable|email|max:255',
            'npwp' => 'nullable|string|max:50',
            'address' => 'nullable|string|max:500',
        ]);

        $validated = $this->filterAvailableCustomerColumns($validated);

        $customer = Customer::create($validated);

        if ($request->wantsJson()) {
            return response()->json([
                'success' => true,
                'customer' => $customer,
            ]);
        }

        return redirect()
            ->route('customers.index')
            ->with('success', 'Data instansi / pelanggan berhasil ditambahkan.');
    }

    public function edit(Customer $customer)
    {
        $this->authorize('edit customers');

        return view('pages.customers.form', [
            'title' => 'Edit Instansi / Pelanggan',
            'customer' => $customer,
            'memberTypes' => $this->memberTypes,
        ]);
    }

    public function update(Request $request, Customer $customer)
    {
        $this->authorize('edit customers');

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'member_type' => 'required|in:umum,studio',
            'contact_person' => 'nullable|string|max:100',
            'phone' => 'required|string|max:20',
            'email' => 'nullable|email|max:255',
            'npwp' => 'nullable|string|max:50',
            'address' => 'nullable|string|max:500',
        ]);

        $validated = $this->filterAvailableCustomerColumns($validated);

        $customer->update($validated);

        return redirect()
            ->route('customers.index')
            ->with('success', 'Data instansi / pelanggan berhasil diperbarui.');
    }

    public function destroy(Customer $customer)
    {
        $this->authorize('delete customers');

        if ($customer->orders()->exists()) {
            return redirect()
                ->back()
                ->with('error', 'Data instansi / pelanggan tidak dapat dihapus karena memiliki riwayat order.');
        }

        $customer->delete();

        return redirect()
            ->route('customers.index')
            ->with('success', 'Data instansi / pelanggan berhasil dihapus.');
    }

    /**
     * Cek kolom agar controller tetap aman walaupun migration contact_person/npwp
     * belum dijalankan.
     */
    private function customerColumnExists(string $column): bool
    {
        try {
            return \Illuminate\Support\Facades\Schema::hasColumn('customers', $column);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * Hapus field baru kalau kolomnya belum ada, supaya tidak error SQL.
     * Setelah migration dijalankan, data contact_person dan npwp otomatis tersimpan.
     */
    private function filterAvailableCustomerColumns(array $data): array
    {
        if (!$this->customerColumnExists('contact_person')) {
            unset($data['contact_person']);
        }

        if (!$this->customerColumnExists('npwp')) {
            unset($data['npwp']);
        }

        return $data;
    }
}
