<?php

namespace App\Http\Controllers;

use App\Models\Contact;
use App\Models\ContactPoint;
use App\Models\Contacttype;
use App\Models\Stocktransaction;

use Illuminate\Http\Request;
use Carbon\Carbon;
use App\Imports\ContactImport;
use Maatwebsite\Excel\Facades\Excel;

class ContactController extends Controller
{
    public function getContact()
    {
        $data = Contact::with('type')->orderBy('id', 'desc')->get();

        $path = storage_path('app/countries.json');
        if (file_exists($path)) {
            $json = file_get_contents($path);
            $countries = json_decode($json, true);
            $countryMap = array_column($countries, null, 'code');

            $data->each(function ($item) use ($countryMap) {
                $item->country_detail = isset($countryMap[$item->country]) ? $countryMap[$item->country] : null;
            });
        }

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactCustomer()
    {
        $data = Contact::with('type')->whereHas('type', function ($type) {
            $type->where('category', '=', 'customer');
        })->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactSupplier()
    {
        $data = Contact::with('type')->whereHas('type', function ($type) {
            $type->where('category', '=', 'supplier');
        })->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactVendor()
    {
        $data = Contact::with('type')->whereHas('type', function ($type) {
            $type->where('category', '=', 'vendor');
        })->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactKaryawan()
    {
        $data = Contact::with('type')->whereHas('type', function ($type) {
            $type->where('category', '=', 'karyawan');
        })->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactMitra()
    {
        $data = Contact::with('type')->whereHas('type', function ($type) {
            $type->where('category', '=', 'mitra');
        })->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactVendorandKaryawanMitra()
    {
        $data = Contact::with('type')->with('type')
            ->whereHas('type', function ($type) {
                $type->whereIn('category', ['vendor', 'karyawan', 'mitra']);
            })
            ->orderBy('id', 'desc')
            ->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactCategorys(Request $request)
    {
        $defaultCategories = ['vendor', 'karyawan', 'mitra', 'supplier'];

        $categoriesInput = $request->input('categories', $request->input('category', null));
        if ($categoriesInput === null || $categoriesInput === '') {
            $categories = $defaultCategories;
        } elseif (is_array($categoriesInput)) {
            $categories = $categoriesInput;
        } else {
            $categories = array_filter(array_map('trim', explode(',', (string)$categoriesInput)));
        }

        $categories = array_values(array_unique(array_filter($categories, function ($v) {
            return is_string($v) && trim($v) !== '';
        })));

        if (count($categories) === 0) {
            $categories = $defaultCategories;
        }

        $allowedCategories = Contacttype::query()
            ->distinct()
            ->pluck('category')
            ->filter()
            ->map(function ($c) {
                return (string)$c;
            })
            ->toArray();

        // Menghapus validasi strict agar tidak return 422 jika category belum ada di DB
        // Cukup filter berdasarkan apa yang diminta, jika category tidak ada maka hasil query akan kosong untuk category tersebut

        $data = Contact::with('type')
            ->whereHas('type', function ($type) use ($categories) {
                $type->whereIn('category', $categories);
            })
            ->orderBy('id', 'desc')
            ->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactSales()
    {
        $data = Contact::with('type')->with('type')
            ->whereHas('type', function ($type) {
                $type->whereIn('category', ['mitra', 'karyawan']);
            })
            ->orderBy('id', 'desc')
            ->get();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function getContactDetail(Request $request)
    {
        $data = Contact::with('type')->find($request->id);

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function createContact(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'desc' => 'nullable',
            'address'  => 'nullable',
            'contact'  => 'nullable',
            'npwp'  => 'nullable',
            'bank_account_name'  => 'nullable',
            'bank_account_number'  => 'nullable',
            'type'  => 'required',
            'business_type' => 'nullable',
            'institutional_name' => 'nullable',
            'dependents_count' => 'nullable|integer',
            'country' => 'nullable',
            'npwp_verified' => 'nullable|boolean',
        ]);

        $data = new Contact;
        $data->name = $request->name;
        $data->desc = $request->desc;
        $data->address = $request->address;
        $data->contact = $request->contact;
        $data->contact_title = $request->contact_title;
        $data->contact_email = $request->contact_email;
        $data->type = $request->type;
        $data->npwp = $request->npwp;
        $data->bank_account_name = $request->bank_account_name;
        $data->bank_account_number = $request->bank_account_number;
        $data->business_type = $request->business_type ?? 'perorangan';
        $data->institutional_name = $request->institutional_name;
        $data->dependents_count = $request->dependents_count;
        $data->country = $request->country;
        $data->npwp_verified = $request->npwp_verified;
        $data->save();

        // add contact point
        $contactPoint = new ContactPoint;
        $contactPoint->contact_id = $data->id;
        $contactPoint->total_point = 0;
        $contactPoint->last_updated = Carbon::now()->format('Y-m-d');
        $contactPoint->save();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function editContact(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'desc' => 'nullable',
            'address'  => 'nullable',
            'contact'  => 'nullable',
            'npwp'  => 'nullable',
            'bank_account_name'  => 'nullable',
            'bank_account_number'  => 'nullable',
            'type'  => 'required',
            'business_type' => 'nullable',
            'institutional_name' => 'nullable',
            'dependents_count' => 'nullable|integer',
            'country' => 'nullable',
            'npwp_verified' => 'nullable|boolean',
        ]);

        $data = Contact::find($request->id);
        $data->name = $request->name;
        $data->desc = $request->desc;
        $data->address = $request->address;
        $data->contact = $request->contact;
        $data->contact_title = $request->contact_title;
        $data->contact_email = $request->contact_email;
        $data->type = $request->type;
        $data->npwp = $request->npwp;
        $data->bank_account_name = $request->bank_account_name;
        $data->bank_account_number = $request->bank_account_number;
        if ($request->filled('business_type')) $data->business_type = $request->business_type;
        $data->institutional_name = $request->institutional_name;
        $data->dependents_count = $request->dependents_count;
        $data->country = $request->country;
        $data->npwp_verified = $request->npwp_verified;
        $data->save();

        $response = [
            'success' => true,
            'contact' => $data,
        ];

        return response($response, 200);
    }

    public function deleteContact(Request $request)
    {

        $transaction = Stocktransaction::where('contact_id', $request->id)->get();
        if (!$transaction->isEmpty()) {
            return response(['message' => 'Contact sudah pernah digunakan untuk transaksi'], 400);
        }

        $data = Contact::find($request->id);
        $data->delete();

        $response = [
            'success' => true,
            'contact' => $data,
            'transaction' => $transaction,
        ];

        return response($response, 200);
    }

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

        $importer = new ContactImport;
        Excel::import($importer, $request->file('file'));

        return response()->json([
            'success' => true,
            'message' => 'Import process completed',
            'data' => $importer->getResults()
        ]);
    }
}
