<?php

namespace App\Http\Controllers;

use App\Models\Material;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;

class SettingController extends Controller
{
    public function quickUpdate(Request $request)
    {
        $validated = $request->validate([
            'shop_name' => ['nullable', 'string', 'max:150'],
            'shop_address' => ['nullable', 'string', 'max:255'],
            'shop_phone' => ['nullable', 'string', 'max:50'],
            'shop_footer' => ['nullable', 'string', 'max:500'],
            'shop_logo' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
        ]);

        foreach (['shop_name', 'shop_address', 'shop_phone', 'shop_footer'] as $key) {
            if (array_key_exists($key, $validated)) {
                Setting::set($key, (string) ($validated[$key] ?? ''), 'shop');
            }
        }

        if ($request->hasFile('shop_logo')) {
            $relativePath = $this->storePublicImage(
                $request->file('shop_logo'),
                'logo-full',
                Setting::raw('shop_logo')
            );

            Setting::set('shop_logo', $relativePath, 'shop');
        }

        return response()->json([
            'success' => true,
            'message' => 'Settings tersimpan.',
            'logo_url' => Setting::getShopLogo(),
        ]);
    }

    public function index()
    {
        $settings = [
            'shop_name' => Setting::get('shop_name', 'POSGRAF Percetakan'),
            'shop_address' => Setting::get('shop_address', ''),
            'shop_phone' => Setting::get('shop_phone', ''),
            'shop_footer' => Setting::get('shop_footer', 'Terima kasih atas kepercayaan Anda'),
            'shop_logo' => Setting::getShopLogo(),
            'shop_logo_icon' => Setting::getShopLogoIcon(),
            'wa_template' => Setting::getWaTemplate(),
            'wa_template_piutang' => Setting::getWaTemplatePiutang(),
        ];

        return view('pages.settings.index', [
            'title' => 'Pengaturan',
            'settings' => $settings,
        ]);
    }

    public function update(Request $request)
    {
        $validated = $request->validate([
            'shop_name' => ['required', 'string', 'max:255'],
            'shop_address' => ['nullable', 'string', 'max:500'],
            'shop_phone' => ['nullable', 'string', 'max:20'],
            'shop_footer' => ['nullable', 'string', 'max:255'],
            'shop_logo' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
            'shop_logo_icon' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:1024'],
            'wa_template' => ['nullable', 'string', 'max:2000'],
            'wa_template_piutang' => ['nullable', 'string', 'max:1000'],
        ]);

        if ($request->hasFile('shop_logo')) {
            $relativePath = $this->storePublicImage(
                $request->file('shop_logo'),
                'logo-full',
                Setting::raw('shop_logo')
            );

            Setting::set('shop_logo', $relativePath, 'shop');
        }

        if ($request->hasFile('shop_logo_icon')) {
            $relativePath = $this->storePublicImage(
                $request->file('shop_logo_icon'),
                'logo-icon',
                Setting::raw('shop_logo_icon')
            );

            Setting::set('shop_logo_icon', $relativePath, 'shop');
        }

        foreach (['shop_name', 'shop_address', 'shop_phone', 'shop_footer'] as $key) {
            if (array_key_exists($key, $validated)) {
                Setting::set($key, $validated[$key] ?? '', 'shop');
            }
        }

        foreach (['wa_template', 'wa_template_piutang'] as $key) {
            if (array_key_exists($key, $validated)) {
                Setting::set($key, $validated[$key] ?? '', 'wa');
            }
        }

        return redirect()->route('settings.index')
            ->with('success', 'Pengaturan berhasil disimpan.');
    }

    public function materials()
    {
        $materials = Material::orderBy('category')->orderBy('name')->paginate(20);

        return view('pages.settings.materials.index', [
            'title' => 'Pengaturan Bahan',
            'materials' => $materials,
        ]);
    }

    public function createMaterial()
    {
        return view('pages.settings.materials.create', [
            'title' => 'Tambah Bahan',
        ]);
    }

    public function editMaterial(Material $material)
    {
        return view('pages.settings.materials.edit', [
            'title' => 'Edit Bahan',
            'material' => $material,
        ]);
    }

    public function storeMaterial(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'category' => ['nullable', 'string', 'max:100'],
            'base_price' => ['required', 'numeric', 'min:0'],
            'unit' => ['required', 'string', 'max:20'],
            'track_clicks' => ['boolean'],
        ]);

        Material::create([
            'name' => $validated['name'],
            'category' => $validated['category'] ?? null,
            'base_price' => $validated['base_price'],
            'unit' => $validated['unit'],
            'track_clicks' => $request->boolean('track_clicks'),
        ]);

        return redirect()->route('settings.materials')
            ->with('success', 'Bahan berhasil ditambahkan.');
    }

    public function updateMaterial(Request $request, Material $material)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'category' => ['nullable', 'string', 'max:100'],
            'base_price' => ['required', 'numeric', 'min:0'],
            'unit' => ['required', 'string', 'max:20'],
            'is_active' => ['boolean'],
            'track_clicks' => ['boolean'],
        ]);

        $material->update([
            'name' => $validated['name'],
            'category' => $validated['category'],
            'base_price' => $validated['base_price'],
            'unit' => $validated['unit'],
            'is_active' => $request->boolean('is_active'),
            'track_clicks' => $request->boolean('track_clicks'),
        ]);

        return redirect()->route('settings.materials')
            ->with('success', 'Bahan berhasil diperbarui.');
    }

    public function destroyMaterial(Material $material)
    {
        $material->delete();

        return redirect()->route('settings.materials')
            ->with('success', 'Bahan berhasil dihapus.');
    }

    private function storePublicImage(UploadedFile $file, string $prefix, ?string $oldPath = null): string
    {
        $directory = public_path('uploads/settings');

        if (!File::exists($directory)) {
            File::makeDirectory($directory, 0755, true, true);
        }

        $extension = strtolower($file->getClientOriginalExtension() ?: $file->extension() ?: 'png');
        $filename = $prefix . '-' . date('YmdHis') . '-' . substr(md5(uniqid((string) mt_rand(), true)), 0, 8) . '.' . $extension;

        $file->move($directory, $filename);

        $newRelativePath = 'uploads/settings/' . $filename;

        $this->deleteOldImageIfExists($oldPath, $newRelativePath);

        return $newRelativePath;
    }

    private function deleteOldImageIfExists(?string $oldPath, ?string $exceptPath = null): void
    {
        $oldPath = trim((string) $oldPath);

        if ($oldPath === '' || $oldPath === trim((string) $exceptPath)) {
            return;
        }

        if (
            str_starts_with($oldPath, 'http://') ||
            str_starts_with($oldPath, 'https://') ||
            str_starts_with($oldPath, 'data:')
        ) {
            return;
        }

        $candidates = [
            public_path(ltrim($oldPath, '/')),
            storage_path('app/public/' . ltrim($oldPath, '/')),
        ];

        foreach ($candidates as $candidate) {
            if (is_file($candidate)) {
                @unlink($candidate);
            }
        }
    }
}