<?php

namespace App\Http\Controllers;

use App\Models\Resep;
use App\Models\ResepItem;
use App\Models\ObatMasuk;
use App\Models\ObatKeluar;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ResepController extends Controller
{
    /**
     * Display a listing of the prescriptions.
     */
    public function index(Request $request)
    {
        $query = Resep::with(['user', 'items']);

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('no_resep', 'like', "%{$search}%")
                  ->orWhere('nama_pasien', 'like', "%{$search}%")
                  ->orWhere('no_rm', 'like', "%{$search}%");
            });
        }

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        $reseps = $query->orderBy('tanggal_resep', 'desc')->paginate(10);

        return view('resep.index', compact('reseps'));
    }

    /**
     * Show the form for creating a new prescription.
     */
    public function create()
    {
        // Get medicines with available stock
        $obats = ObatMasuk::where('stok', '>', 0)
            ->where('tanggal_kadaluarsa', '>=', now())
            ->with('kategori', 'satuan')
            ->orderBy('nama_obat')
            ->get();

        return view('resep.create', compact('obats'));
    }

    /**
     * Store a newly created prescription in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            // Data Resep
            'nama_dokter' => 'required|string|max:100',
            'no_sip' => 'nullable|string|max:50',
            'tanggal_resep' => 'required|date',
            'jenis_penjamin' => 'required|in:umum,BPJS Kes,BPJS Naker,Jamkesmas/KIS,R. Inap',
            'jenis_layanan' => 'required|in:BP,KIA,Gigi,UGD,Lainnya',
            // Data Pasien
            'no_rm' => 'nullable|string|max:50',
            'nama_pasien' => 'required|string|max:100',
            'alamat_pasien' => 'nullable|string|max:255',
            'jenis_kelamin' => 'required|in:L,P',
            'umur_pasien' => 'required|integer|min:0|max:150',
            'berat_badan' => 'required|numeric|min:0|max:500',
            'diagnosa' => 'required|string',
            'catatan' => 'nullable|string',
            // Daftar Obat
            'items' => 'required|array|min:1',
            'items.*.obat_masuk_id' => 'required|exists:obat_masuks,id',
            'items.*.jumlah' => 'required|integer|min:1',
            'items.*.aturan_pakai' => 'nullable|string|max:255',
        ]);

        // Validate stock availability
        foreach ($validated['items'] as $item) {
            $obatMasuk = ObatMasuk::find($item['obat_masuk_id']);
            if ($obatMasuk->stok < $item['jumlah']) {
                return back()->withErrors([
                    'items' => "Stok obat {$obatMasuk->nama_obat} tidak mencukupi. Tersedia: {$obatMasuk->stok}"
                ])->withInput();
            }
        }

        DB::transaction(function () use ($validated, $request) {
            // Create resep with status 'proses' (not 'selesai')
            $resep = Resep::create([
                'no_resep' => Resep::generateNoResep(),
                'user_id' => auth()->id(),
                'nama_dokter' => $validated['nama_dokter'],
                'no_sip' => $validated['no_sip'] ?? null,
                'jenis_penjamin' => $validated['jenis_penjamin'],
                'jenis_layanan' => $validated['jenis_layanan'],
                'no_rm' => $validated['no_rm'] ?? null,
                'nama_pasien' => $validated['nama_pasien'],
                'alamat_pasien' => $validated['alamat_pasien'] ?? null,
                'jenis_kelamin' => $validated['jenis_kelamin'],
                'umur_pasien' => $validated['umur_pasien'],
                'berat_badan' => $validated['berat_badan'],
                'tanggal_resep' => $validated['tanggal_resep'],
                'diagnosa' => $validated['diagnosa'],
                'catatan' => $validated['catatan'] ?? null,
                'status' => 'proses', // Changed from 'selesai' to 'proses'
                'is_read' => false,
            ]);

            // Create resep items and reduce stock
            foreach ($validated['items'] as $item) {
                $obatMasuk = ObatMasuk::find($item['obat_masuk_id']);

                // Create resep item
                ResepItem::create([
                    'resep_id' => $resep->id,
                    'obat_masuk_id' => $item['obat_masuk_id'],
                    'nama_obat' => $obatMasuk->nama_obat,
                    'jumlah' => $item['jumlah'],
                    'aturan_pakai' => $item['aturan_pakai'] ?? null,
                ]);

                // Create obat keluar record with status 'proses'
                ObatKeluar::create([
                    'obat_masuk_id' => $item['obat_masuk_id'],
                    'nama_obat' => $obatMasuk->nama_obat,
                    'sumber_dana' => $obatMasuk->sumber_dana,
                    'user_id' => auth()->id(),
                    'kode_batch' => $obatMasuk->kode_batch,
                    'barcode' => $obatMasuk->barcode,
                    'jumlah' => $item['jumlah'],
                    'tujuan_pemakaian' => 'Resep: ' . $resep->no_resep . ' - ' . $validated['nama_pasien'],
                    'tanggal_pengeluaran' => $validated['tanggal_resep'],
                    'tanggal_kadaluarsa' => $obatMasuk->tanggal_kadaluarsa,
                    'no_pengeluaran' => $resep->no_resep,
                    'nama_petugas' => auth()->user()->name,
                    'nama_penerima' => $validated['nama_pasien'],
                    'catatan' => 'Otomatis dari resep ' . $resep->no_resep,
                    'status' => 'proses', // Changed from 'terkirim' to 'proses'
                ]);
                
                // Do NOT reduce stock here because status is 'proses'
            }
        });

        return redirect()->route('resep.index')->with('success', 'Resep berhasil dibuat.');
    }

    /**
     * Display the specified prescription.
     */
    public function show(Resep $resep)
    {
        $resep->load(['user', 'items.obatMasuk.satuan']);
        
        // Mark as read if apoteker is viewing
        if (auth()->user()->isApoteker()) {
            $resep->markAsRead();
        }
        
        return view('resep.show', compact('resep'));
    }

    /**
     * Show the form for editing the specified prescription.
     */
    public function edit(Resep $resep)
    {
        // Resep yang sudah selesai tidak bisa diedit
        if ($resep->status === 'selesai') {
            return redirect()->route('resep.show', $resep)
                ->with('error', 'Resep dengan status selesai tidak dapat diedit.');
        }

        $resep->load(['items']);
        
        $obats = ObatMasuk::where(function ($q) {
                $q->where('stok', '>', 0)
                  ->where('tanggal_kadaluarsa', '>=', now());
            })
            ->orWhereIn('id', $resep->items->pluck('obat_masuk_id'))
            ->with('kategori', 'satuan')
            ->orderBy('nama_obat')
            ->get();

        return view('resep.edit', compact('resep', 'obats'));
    }

    /**
     * Update the specified prescription in storage.
     */
    public function update(Request $request, Resep $resep)
    {
        // Resep yang sudah selesai tidak bisa diubah
        if ($resep->status === 'selesai') {
            return redirect()->route('resep.show', $resep)
                ->with('error', 'Resep dengan status selesai tidak dapat diedit.');
        }

        $validated = $request->validate([
            // Data Resep
            'nama_dokter' => 'required|string|max:100',
            'no_sip' => 'nullable|string|max:50',
            'tanggal_resep' => 'required|date',
            'jenis_penjamin' => 'required|in:umum,BPJS Kes,BPJS Naker,Jamkesmas/KIS,R. Inap',
            'jenis_layanan' => 'required|in:BP,KIA,Gigi,UGD,Lainnya',
            // Data Pasien
            'no_rm' => 'nullable|string|max:50',
            'nama_pasien' => 'required|string|max:100',
            'alamat_pasien' => 'nullable|string|max:255',
            'jenis_kelamin' => 'required|in:L,P',
            'umur_pasien' => 'required|integer|min:0|max:150',
            'berat_badan' => 'required|numeric|min:0|max:500',
            'diagnosa' => 'required|string',
            'catatan' => 'nullable|string',
            'status' => 'required|in:proses,selesai,dibatalkan',
            // Daftar Obat
            'items' => 'required|array|min:1',
            'items.*.obat_masuk_id' => 'required|exists:obat_masuks,id',
            'items.*.jumlah' => 'required|integer|min:1',
            'items.*.aturan_pakai' => 'nullable|string|max:255',
        ]);

        DB::transaction(function () use ($validated, $resep) {
            // Restore old stock first (only if status was selesai, but update is not allowed for selesai)
            foreach ($resep->items as $oldItem) {
                // Delete related obat keluar
                ObatKeluar::where('no_pengeluaran', $resep->no_resep)
                    ->where('obat_masuk_id', $oldItem->obat_masuk_id)
                    ->delete();
            }

            // Delete old items
            $resep->items()->delete();

            // Validate new stock
            foreach ($validated['items'] as $item) {
                $obatMasuk = ObatMasuk::find($item['obat_masuk_id']);
                if ($obatMasuk->stok < $item['jumlah']) {
                    throw new \Exception("Stok obat {$obatMasuk->nama_obat} tidak mencukupi. Tersedia: {$obatMasuk->stok}");
                }
            }

            // Update resep
            $resep->update([
                'nama_dokter' => $validated['nama_dokter'],
                'no_sip' => $validated['no_sip'] ?? null,
                'jenis_penjamin' => $validated['jenis_penjamin'],
                'jenis_layanan' => $validated['jenis_layanan'],
                'no_rm' => $validated['no_rm'] ?? null,
                'nama_pasien' => $validated['nama_pasien'],
                'alamat_pasien' => $validated['alamat_pasien'] ?? null,
                'jenis_kelamin' => $validated['jenis_kelamin'],
                'umur_pasien' => $validated['umur_pasien'],
                'berat_badan' => $validated['berat_badan'],
                'tanggal_resep' => $validated['tanggal_resep'],
                'diagnosa' => $validated['diagnosa'],
                'catatan' => $validated['catatan'] ?? null,
                'status' => $validated['status'],
            ]);

            // Create new items and reduce stock
            foreach ($validated['items'] as $item) {
                $obatMasuk = ObatMasuk::find($item['obat_masuk_id']);

                // Create resep item
                ResepItem::create([
                    'resep_id' => $resep->id,
                    'obat_masuk_id' => $item['obat_masuk_id'],
                    'nama_obat' => $obatMasuk->nama_obat,
                    'jumlah' => $item['jumlah'],
                    'aturan_pakai' => $item['aturan_pakai'] ?? null,
                ]);

                // Create obat keluar record
                ObatKeluar::create([
                    'obat_masuk_id' => $item['obat_masuk_id'],
                    'nama_obat' => $obatMasuk->nama_obat,
                    'sumber_dana' => $obatMasuk->sumber_dana,
                    'user_id' => auth()->id(),
                    'kode_batch' => $obatMasuk->kode_batch,
                    'barcode' => $obatMasuk->barcode,
                    'jumlah' => $item['jumlah'],
                    'tujuan_pemakaian' => 'Resep: ' . $resep->no_resep . ' - ' . $validated['nama_pasien'],
                    'tanggal_pengeluaran' => $validated['tanggal_resep'],
                    'tanggal_kadaluarsa' => $obatMasuk->tanggal_kadaluarsa,
                    'no_pengeluaran' => $resep->no_resep,
                    'nama_petugas' => auth()->user()->name,
                    'nama_penerima' => $validated['nama_pasien'],
                    'catatan' => 'Otomatis dari resep ' . $resep->no_resep,
                    'status' => $validated['status'] === 'selesai' ? 'selesai' : ($validated['status'] === 'dibatalkan' ? 'dibatalkan' : 'proses'),
                ]);

                // Reduce stock only if status is selesai
                if ($validated['status'] === 'selesai') {
                    $obatMasuk->decrement('stok', $item['jumlah']);
                }
            }
        });

        return redirect()->route('resep.index')->with('success', 'Resep berhasil diperbarui.');
    }

    /**
     * Update the status of the specified prescription (by apoteker).
     */
    public function updateStatus(Request $request, Resep $resep)
    {
        // Resep yang sudah selesai tidak bisa diubah statusnya
        if ($resep->status === 'selesai') {
            return redirect()->route('resep.index')
                ->with('error', 'Status resep yang sudah selesai tidak dapat diubah.');
        }

        $validated = $request->validate([
            'status' => 'required|in:proses,selesai,dibatalkan',
        ]);


        DB::transaction(function () use ($validated, $resep) {
            $oldStatus = $resep->status;
            
            $resep->update(['status' => $validated['status']]);
            
            // Also update related obat keluar records
            ObatKeluar::where('no_pengeluaran', $resep->no_resep)
                ->update(['status' => $validated['status']]);
                
            // If changing to 'selesai', reduce stock
            if ($oldStatus !== 'selesai' && $validated['status'] === 'selesai') {
                foreach ($resep->items as $item) {
                    if ($item->obatMasuk) {
                        $item->obatMasuk->decrement('stok', $item->jumlah);
                    }
                }
            }
        });

        return redirect()->route('resep.index')->with('success', 'Status resep berhasil diperbarui.');
    }

    /**
     * Remove the specified prescription from storage.
     */
    public function destroy(Resep $resep)
    {
        DB::transaction(function () use ($resep) {
            // Restore stock for each item ONLY IF status was selesai
            if ($resep->status === 'selesai') {
                foreach ($resep->items as $item) {
                    if ($item->obatMasuk) {
                        $item->obatMasuk->increment('stok', $item->jumlah);
                    }
                }
            }

            // Delete related obat keluar
            ObatKeluar::where('no_pengeluaran', $resep->no_resep)->delete();

            // Delete resep (items will cascade)
            $resep->delete();
        });

        return redirect()->route('resep.index')->with('success', 'Resep berhasil dihapus dan stok dikembalikan.');
    }

    /**
     * Print the prescription.
     */
    public function print(Resep $resep)
    {
        $resep->load(['user', 'items.obatMasuk.satuan']);
        return view('resep.print', compact('resep'));
    }
}

