<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Carbon\Carbon;

class AccountingPeriodController extends Controller
{
    /**
     * Menampilkan daftar periode akuntansi.
     * LOGIKA ENTERPRISE: Generate periode HANYA dimulai dari bulan transaksi pertama kali terjadi di sistem.
     */
    public function index(Request $request)
    {
        try {
            $user = $request->user();
            $currentYear = Carbon::now()->year;
            $currentMonth = Carbon::now()->month;

            // PENAMBAHAN: Efisiensi Database. 
            // Proses generate/insert periode baru hanya dipicu jika yang membuka adalah Owner/Pusat.
            // Admin cabang cukup melakukan SELECT (Read-Only) untuk melihat status buka/tutup bulan.
            if ($user && $user->role === 'owner') {
                // 1. Cari tanggal transaksi paling awal di sistem P-LINK (Titik Nol Operasional)
                $firstTransaction = DB::table('journal_entries')->orderBy('entry_date', 'asc')->first();

                if ($firstTransaction) {
                    // Jika ada transaksi, ambil Tahun dan Bulan dari transaksi paling tua
                    $startYear = Carbon::parse($firstTransaction->entry_date)->year;
                    $startMonth = Carbon::parse($firstTransaction->entry_date)->month;
                } else {
                    // Jika aplikasi benar-benar baru dan belum ada transaksi sama sekali
                    $startYear = $currentYear;
                    $startMonth = $currentMonth;
                }

                // 2. Generate periode HANYA dari bulan mulai operasi sampai bulan berjalan saat ini
                for ($y = $startYear; $y <= $currentYear; $y++) {
                    // Jika sedang di tahun mulai operasi, mulailah dari $startMonth. Jika tidak, mulai dari Januari (1)
                    $mStart = ($y === $startYear) ? $startMonth : 1;
                    
                    // Jika sedang di tahun saat ini, berhentilah di $currentMonth. Jika tidak, sampai Desember (12)
                    $mEnd = ($y === $currentYear) ? $currentMonth : 12;

                    for ($m = $mStart; $m <= $mEnd; $m++) {
                        $exists = DB::table('accounting_periods')
                            ->where('period_year', $y)
                            ->where('period_month', $m)
                            ->exists();

                        if (!$exists) {
                            DB::table('accounting_periods')->insert([
                                'period_month' => $m,
                                'period_year' => $y,
                                'status' => 'open',
                                'created_at' => Carbon::now(),
                                'updated_at' => Carbon::now()
                            ]);
                        }
                    }
                }
            }

            // 3. Ambil data periode, urutkan dari yang terbaru ke terlama
            $periods = DB::table('accounting_periods')
                ->leftJoin('users', 'accounting_periods.closed_by', '=', 'users.id')
                ->select('accounting_periods.*', 'users.name as closed_by_name')
                ->orderBy('period_year', 'desc')
                ->orderBy('period_month', 'desc')
                ->get();

            return response()->json([
                'success' => true,
                'data' => $periods
            ]);

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * Mengeksekusi penutupan atau pembukaan kembali (Unlock) suatu periode.
     * Wajib menyertakan Password Otorisasi Owner.
     */
    public function toggleStatus(Request $request)
    {
        $request->validate([
            'period_id' => 'required|exists:accounting_periods,id',
            'action' => 'required|in:close,open',
            'password' => 'required'
        ]);

        $user = $request->user();
        if (!$user) return response()->json(['success' => false, 'message' => 'Sesi tidak valid.'], 401);

        // HANYA OWNER YANG BOLEH MELAKUKAN TUTUP BUKU
        if ($user->role !== 'owner') {
            return response()->json(['success' => false, 'message' => 'Akses Ditolak! Hanya Owner yang berhak melakukan Tutup Buku.'], 403);
        }

        // VERIFIKASI PASSWORD OWNER
        if (!Hash::check($request->password, $user->password)) {
            return response()->json(['success' => false, 'message' => 'Otorisasi Gagal! Password Anda salah.']);
        }

        DB::beginTransaction();
        try {
            $period = DB::table('accounting_periods')->where('id', $request->period_id)->first();
            
            if ($request->action === 'close') {
                if ($period->status === 'closed') throw new \Exception("Periode ini sudah berstatus tertutup.");
                
                DB::table('accounting_periods')->where('id', $period->id)->update([
                    'status' => 'closed',
                    'closed_by' => $user->id,
                    'closed_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ]);
                $msg = "Periode berhasil DITUTUP. Semua akses input/edit transaksi di bulan ini telah TERKUNCI.";
            } else {
                if ($period->status === 'open') throw new \Exception("Periode ini sudah berstatus terbuka.");
                
                DB::table('accounting_periods')->where('id', $period->id)->update([
                    'status' => 'open',
                    'closed_by' => null,
                    'closed_at' => null,
                    'updated_at' => Carbon::now()
                ]);
                $msg = "Periode berhasil DIBUKA KEMBALI. Transaksi di bulan ini dapat diedit sementara waktu.";
            }

            DB::commit();
            return response()->json([
                'success' => true,
                'message' => $msg
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 400);
        }
    }
}