<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\EmployeeWalletTransaction;
use App\Models\Employee;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Carbon\Carbon;

class EmployeeWalletController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:sanctum');
    }

    /**
     * Get wallet transactions with filters
     */
    public function index(Request $request)
    {
        $user = $request->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $query = EmployeeWalletTransaction::with(['employee', 'createdBy', 'branch', 'restaurant']);

        // Filter by employee_id if provided
        if ($request->has('employee_id') && $request->employee_id) {
            $query->where('employee_id', $request->employee_id);
        }

        // Apply role-based filtering
        if ($user->role === 'admin') {
            if ($request->has('restaurant_id') && $request->restaurant_id) {
                $query->where('restaurant_id', $request->restaurant_id);
            }
            if ($request->has('branch_id') && $request->branch_id) {
                $query->where('branch_id', $request->branch_id);
            }
        } elseif ($user->role === 'restaurant_owner') {
            $query->where('restaurant_id', $user->restaurant_id);
            if ($request->has('branch_id') && $request->branch_id) {
                $query->where('branch_id', $request->branch_id);
            }
        } elseif ($user->role === 'branch_manager') {
            $query->where('restaurant_id', $user->restaurant_id)
                  ->where('branch_id', $user->branch_id);
        }

        // Date range filter
        if ($request->has('date_from') && $request->date_from) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->has('date_to') && $request->date_to) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        // Payment type filter
        if ($request->has('payment_type') && $request->payment_type) {
            $query->where('payment_type', $request->payment_type);
        }

        // Transaction type filter
        if ($request->has('transaction_type') && $request->transaction_type) {
            $query->where('transaction_type', $request->transaction_type);
        }

        // Month filter
        if ($request->has('month') && $request->month) {
            $query->where('month', $request->month);
        }

        $transactions = $query->orderBy('created_at', 'desc')->get();

        return response()->json($transactions);
    }

    /**
     * Get wallet balance for an employee
     */
    public function getBalance($employeeId)
    {
        $user = request()->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $employee = Employee::findOrFail($employeeId);

        // Check access
        if ($user->role === 'restaurant_owner' && $employee->restaurant_id !== $user->restaurant_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        if ($user->role === 'branch_manager' && $employee->branch_id !== $user->branch_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $balance = $employee->getWalletBalance();
        $credits = $employee->walletTransactions()->credits()->sum('amount') ?? 0;
        $debits = $employee->walletTransactions()->debits()->sum('amount') ?? 0;

        return response()->json([
            'balance' => $balance ?? 0,
            'credits' => $credits,
            'debits' => $debits,
            'employee' => $employee->load(['restaurant', 'branch']),
        ]);
    }

    /**
     * Get all transactions for a specific employee
     */
    public function getTransactions($employeeId)
    {
        $user = request()->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $employee = Employee::findOrFail($employeeId);

        // Check access
        if ($user->role === 'restaurant_owner' && $employee->restaurant_id !== $user->restaurant_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        if ($user->role === 'branch_manager' && $employee->branch_id !== $user->branch_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $transactions = $employee->walletTransactions()
            ->with(['createdBy', 'restaurant', 'branch'])
            ->orderBy('created_at', 'desc')
            ->get();

        $balance = $employee->getWalletBalance() ?? 0;

        return response()->json([
            'transactions' => $transactions,
            'balance' => $balance,
        ]);
    }

    /**
     * Create a payout (advance/salary/daily_wage)
     */
    public function payout(Request $request)
    {
        $user = $request->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'employee_id' => 'required|exists:employees,id',
            'payment_type' => ['required', Rule::in(['advance', 'salary', 'daily_wage'])],
            'amount' => 'required|numeric|min:0',
            'notes' => 'nullable|string',
        ]);

        $employee = Employee::findOrFail($validated['employee_id']);

        // Check access
        if ($user->role === 'restaurant_owner' && $employee->restaurant_id !== $user->restaurant_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        if ($user->role === 'branch_manager' && $employee->branch_id !== $user->branch_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        DB::beginTransaction();
        try {
            $currentMonth = Carbon::now()->format('Y-m');
            $transactions = [];

            if ($validated['payment_type'] === 'advance') {
                // Advance: Credit only
                $transactions[] = EmployeeWalletTransaction::create([
                    'employee_id' => $employee->id,
                    'transaction_type' => 'credit',
                    'amount' => $validated['amount'],
                    'payment_type' => 'advance',
                    'notes' => $validated['notes'] ?? null,
                    'created_by' => $user->id,
                    'restaurant_id' => $employee->restaurant_id,
                    'branch_id' => $employee->branch_id,
                ]);
            } elseif ($validated['payment_type'] === 'salary') {
                // Salary: Credit + Debit (if monthly, calculate for current month)
                if ($employee->salary_type === 'monthly') {
                    $salaryAmount = $employee->getCurrentSalaryAmount();
                    // Create debit entry for current month
                    $transactions[] = EmployeeWalletTransaction::create([
                        'employee_id' => $employee->id,
                        'transaction_type' => 'debit',
                        'amount' => $salaryAmount,
                        'payment_type' => 'salary',
                        'month' => $currentMonth,
                        'notes' => $validated['notes'] ?? null,
                        'created_by' => $user->id,
                        'restaurant_id' => $employee->restaurant_id,
                        'branch_id' => $employee->branch_id,
                    ]);
                }
                // Create credit entry for paid amount
                $transactions[] = EmployeeWalletTransaction::create([
                    'employee_id' => $employee->id,
                    'transaction_type' => 'credit',
                    'amount' => $validated['amount'],
                    'payment_type' => 'salary',
                    'month' => $employee->salary_type === 'monthly' ? $currentMonth : null,
                    'notes' => $validated['notes'] ?? null,
                    'created_by' => $user->id,
                    'restaurant_id' => $employee->restaurant_id,
                    'branch_id' => $employee->branch_id,
                ]);
            } elseif ($validated['payment_type'] === 'daily_wage') {
                // Daily wage: Credit + Debit (equal amounts to balance to 0)
                $transactions[] = EmployeeWalletTransaction::create([
                    'employee_id' => $employee->id,
                    'transaction_type' => 'debit',
                    'amount' => $validated['amount'],
                    'payment_type' => 'daily_wage',
                    'notes' => $validated['notes'] ?? null,
                    'created_by' => $user->id,
                    'restaurant_id' => $employee->restaurant_id,
                    'branch_id' => $employee->branch_id,
                ]);
                $transactions[] = EmployeeWalletTransaction::create([
                    'employee_id' => $employee->id,
                    'transaction_type' => 'credit',
                    'amount' => $validated['amount'],
                    'payment_type' => 'daily_wage',
                    'notes' => $validated['notes'] ?? null,
                    'created_by' => $user->id,
                    'restaurant_id' => $employee->restaurant_id,
                    'branch_id' => $employee->branch_id,
                ]);
            }

            DB::commit();

            // Load relationships
            foreach ($transactions as $transaction) {
                $transaction->load(['employee', 'createdBy', 'restaurant', 'branch']);
            }

            return response()->json([
                'message' => 'Payout created successfully',
                'transactions' => $transactions,
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['error' => 'Failed to create payout: ' . $e->getMessage()], 500);
        }
    }

    /**
     * Update wallet transaction
     */
    public function update(Request $request, $id)
    {
        $user = $request->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $transaction = EmployeeWalletTransaction::findOrFail($id);

        // Check access
        if ($user->role === 'restaurant_owner' && $transaction->restaurant_id !== $user->restaurant_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        if ($user->role === 'branch_manager' && $transaction->branch_id !== $user->branch_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $validated = $request->validate([
            'amount' => 'sometimes|required|numeric|min:0',
            'notes' => 'nullable|string',
            'payment_type' => ['sometimes', Rule::in(['advance', 'salary', 'daily_wage', 'adjustment'])],
        ]);

        $transaction->update($validated);
        $transaction->load(['employee', 'createdBy', 'restaurant', 'branch']);

        return response()->json($transaction);
    }

    /**
     * Delete wallet transaction
     */
    public function destroy($id)
    {
        $user = request()->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $transaction = EmployeeWalletTransaction::findOrFail($id);

        // Check access
        if ($user->role === 'restaurant_owner' && $transaction->restaurant_id !== $user->restaurant_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        if ($user->role === 'branch_manager' && $transaction->branch_id !== $user->branch_id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $transaction->delete();

        return response()->json(['message' => 'Transaction deleted successfully']);
    }

    /**
     * Export wallet transactions
     */
    public function export(Request $request)
    {
        $user = $request->user();
        
        if (!$user || !in_array($user->role, ['admin', 'restaurant_owner', 'branch_manager'])) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $format = $request->get('format', 'csv'); // csv, excel, pdf

        $query = EmployeeWalletTransaction::with(['employee', 'createdBy', 'branch', 'restaurant']);

        // Apply same filters as index
        if ($request->has('employee_id') && $request->employee_id) {
            $query->where('employee_id', $request->employee_id);
        }

        if ($user->role === 'admin') {
            if ($request->has('restaurant_id') && $request->restaurant_id) {
                $query->where('restaurant_id', $request->restaurant_id);
            }
            if ($request->has('branch_id') && $request->branch_id) {
                $query->where('branch_id', $request->branch_id);
            }
        } elseif ($user->role === 'restaurant_owner') {
            $query->where('restaurant_id', $user->restaurant_id);
            if ($request->has('branch_id') && $request->branch_id) {
                $query->where('branch_id', $request->branch_id);
            }
        } elseif ($user->role === 'branch_manager') {
            $query->where('restaurant_id', $user->restaurant_id)
                  ->where('branch_id', $user->branch_id);
        }

        if ($request->has('date_from') && $request->date_from) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->has('date_to') && $request->date_to) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        $transactions = $query->orderBy('created_at', 'desc')->get();

        if ($format === 'csv') {
            return $this->exportCsv($transactions, $request);
        } elseif ($format === 'excel') {
            return $this->exportExcel($transactions, $request);
        } elseif ($format === 'pdf') {
            return $this->exportPdf($transactions, $request);
        }

        return response()->json(['error' => 'Invalid format'], 400);
    }

    /**
     * Export to CSV
     */
    private function exportCsv($transactions, $request)
    {
        $headers = ['Employee Name', 'Date', 'Transaction Type', 'Amount', 'Payment Type', 'Month', 'Notes', 'Created By', 'Restaurant', 'Branch'];
        $rows = [];

        $runningBalance = 0;
        foreach ($transactions as $transaction) {
            if ($transaction->transaction_type === 'credit') {
                $runningBalance += $transaction->amount;
            } else {
                $runningBalance -= $transaction->amount;
            }

            $rows[] = [
                $transaction->employee->name ?? '-',
                $transaction->created_at->format('Y-m-d H:i:s'),
                ucfirst($transaction->transaction_type),
                number_format($transaction->amount, 2),
                ucfirst(str_replace('_', ' ', $transaction->payment_type)),
                $transaction->month ?? '-',
                $transaction->notes ?? '-',
                $transaction->createdBy->name ?? '-',
                $transaction->restaurant->name ?? '-',
                $transaction->branch->name ?? '-',
            ];
        }

        $csvContent = [implode(',', $headers)];
        foreach ($rows as $row) {
            $csvContent[] = implode(',', array_map(function($cell) {
                return '"' . str_replace('"', '""', $cell) . '"';
            }, $row));
        }

        $dateStr = '';
        if ($request->has('date_from') && $request->has('date_to')) {
            $dateStr = '_' . $request->date_from . '_to_' . $request->date_to;
        } else {
            $dateStr = '_' . date('Y-m-d');
        }
        $filename = 'employee_wallet_transactions' . $dateStr . '.csv';

        return response(implode("\n", $csvContent))
            ->header('Content-Type', 'text/csv')
            ->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
    }

    /**
     * Export to Excel
     */
    private function exportExcel($transactions, $request)
    {
        // Check if Laravel Excel is available
        if (!class_exists(\Maatwebsite\Excel\Facades\Excel::class)) {
            return response()->json(['error' => 'Excel export not available. Please install maatwebsite/excel package.'], 500);
        }

        // For now, return CSV as Excel is not critical
        // In production, you would create an Export class similar to DailyClosingReportExport
        return $this->exportCsv($transactions, $request);
    }

    /**
     * Export to PDF
     */
    private function exportPdf($transactions, $request)
    {
        // For now, return a simple HTML response that can be printed as PDF
        // In production, you would use DomPDF or similar
        $html = '<html><head><title>Employee Wallet Transactions</title></head><body>';
        $html .= '<h1>Employee Wallet Transactions</h1>';
        $html .= '<table border="1" cellpadding="5" style="border-collapse: collapse; width: 100%;">';
        $html .= '<tr><th>Employee</th><th>Date</th><th>Type</th><th>Amount</th><th>Payment Type</th><th>Notes</th></tr>';
        
        foreach ($transactions as $transaction) {
            $html .= '<tr>';
            $html .= '<td>' . ($transaction->employee->name ?? '-') . '</td>';
            $html .= '<td>' . $transaction->created_at->format('Y-m-d') . '</td>';
            $html .= '<td>' . ucfirst($transaction->transaction_type) . '</td>';
            $html .= '<td>' . number_format($transaction->amount, 2) . '</td>';
            $html .= '<td>' . ucfirst(str_replace('_', ' ', $transaction->payment_type)) . '</td>';
            $html .= '<td>' . ($transaction->notes ?? '-') . '</td>';
            $html .= '</tr>';
        }
        
        $html .= '</table></body></html>';

        return response($html)
            ->header('Content-Type', 'text/html')
            ->header('Content-Disposition', 'attachment; filename="employee_wallet_transactions_' . date('Y-m-d') . '.html"');
    }
}

