<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('expense_categories', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('business_id')->constrained()->cascadeOnDelete();
            $table->string('name', 120);
            $table->string('code', 40)->nullable();
            $table->text('description')->nullable();
            $table->enum('status', ['active', 'inactive'])->default('active');
            $table->timestamps();
            $table->unique(['business_id', 'name']);
            $table->unique(['business_id', 'code']);
        });

        Schema::create('recurring_expenses', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('business_id')->constrained()->cascadeOnDelete();
            $table->foreignId('branch_id')->constrained()->restrictOnDelete();
            $table->foreignId('expense_category_id')->constrained('expense_categories')->restrictOnDelete();
            $table->foreignId('financial_account_id')->constrained('financial_accounts')->restrictOnDelete();
            $table->string('description', 255);
            $table->decimal('amount', 18, 2);
            $table->string('supplier', 180)->nullable();
            $table->date('start_date');
            $table->date('next_due_date');
            $table->date('end_date')->nullable();
            $table->enum('recurrence', ['weekly', 'monthly', 'quarterly', 'yearly', 'custom_days']);
            $table->unsignedInteger('interval_days')->nullable();
            $table->unsignedInteger('reminder_days_before')->default(3);
            $table->enum('status', ['active', 'inactive'])->default('active');
            $table->text('notes')->nullable();
            $table->foreignId('created_by')->constrained('users')->restrictOnDelete();
            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamps();
            $table->index(['branch_id', 'status', 'next_due_date']);
        });

        Schema::create('expenses', function (Blueprint $table): void {
            $table->id();
            $table->string('expense_number', 60)->unique();
            $table->foreignId('branch_id')->constrained()->restrictOnDelete();
            $table->foreignId('expense_category_id')->constrained('expense_categories')->restrictOnDelete();
            $table->foreignId('financial_account_id')->constrained('financial_accounts')->restrictOnDelete();
            $table->foreignId('recurring_expense_id')->nullable()->constrained('recurring_expenses')->nullOnDelete();
            $table->date('occurrence_date')->nullable();
            $table->string('description', 255);
            $table->decimal('amount', 18, 2);
            $table->date('expense_date');
            $table->string('supplier', 180)->nullable();
            $table->string('receipt_original_name')->nullable();
            $table->string('receipt_path')->nullable();
            $table->string('receipt_mime_type', 120)->nullable();
            $table->unsignedBigInteger('receipt_size')->nullable();
            $table->text('notes')->nullable();
            $table->enum('status', ['pending', 'approved', 'rejected'])->default('pending');
            $table->foreignId('entered_by')->constrained('users')->restrictOnDelete();
            $table->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('approved_at')->nullable();
            $table->foreignId('rejected_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('rejected_at')->nullable();
            $table->text('decision_comments')->nullable();
            $table->foreignId('financial_account_transaction_id')->nullable()->unique()->constrained('financial_account_transactions')->nullOnDelete();
            $table->string('accounting_journal_number', 80)->nullable();
            $table->timestamps();
            $table->unique(['recurring_expense_id', 'occurrence_date']);
            $table->index(['branch_id', 'status', 'expense_date']);
            $table->index(['expense_category_id', 'expense_date']);
        });

        Schema::create('expense_reminders', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('recurring_expense_id')->constrained('recurring_expenses')->cascadeOnDelete();
            $table->foreignId('branch_id')->constrained()->restrictOnDelete();
            $table->date('due_date');
            $table->date('reminder_date');
            $table->foreignId('expense_id')->nullable()->constrained('expenses')->nullOnDelete();
            $table->string('message', 500);
            $table->enum('status', ['open', 'generated', 'acknowledged'])->default('open');
            $table->foreignId('acknowledged_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('acknowledged_at')->nullable();
            $table->timestamps();
            $table->unique(['recurring_expense_id', 'due_date']);
            $table->index(['branch_id', 'status', 'due_date']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('expense_reminders');
        Schema::dropIfExists('expenses');
        Schema::dropIfExists('recurring_expenses');
        Schema::dropIfExists('expense_categories');
    }
};