<?php

namespace App\Http\Controllers\Accounting;

use App\Http\Controllers\Controller;
use App\Models\Project;
use App\Models\Customer;
use App\Models\User;
use App\Models\ProgrammerPayment;
use App\Services\WaSenderService;
use App\Services\EmailService;
use Illuminate\Http\Request;
use Carbon\Carbon;

class ProjectController extends Controller
{
    protected $transactionService;

    public function __construct(\App\Services\FinancialTransactionService $transactionService)
    {
        $this->transactionService = $transactionService;
    }

    public function index()
    {
        // Stats
        $stats = [
            'total_count' => Project::count(),
            'total_value' => (float) Project::sum('total_price'),
            'active_count' => Project::whereIn('status', ['pending', 'in_progress', 'on_hold'])->count(),
            'completed_count' => Project::where('status', 'completed')->count(),
            'avg_progress' => (float) Project::whereIn('status', ['pending', 'in_progress', 'on_hold'])->avg('progress_percent') ?? 0,
        ];

        $projects = Project::with(['customer', 'programmer'])->latest()->paginate(15);
        return view('accounting.projects.index', compact('projects', 'stats'));
    }

    public function create()
    {
        $customers = Customer::orderBy('name')->get();
        $programmers = User::orderBy('name')->get(); // Ideally filter by role 'programmer'
        return view('accounting.projects.create', compact('customers', 'programmers'));
    }


    public function store(Request $request, WaSenderService $wa, EmailService $email)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'customer_id' => 'required|exists:customers,id',
            'programmer_id' => 'required|exists:users,id',
            'total_price' => 'required|numeric|min:0',
            'commission_amount' => 'required|numeric|min:0',
            'start_date' => 'nullable|date',
            'end_date' => 'nullable|date',
            'notes' => 'nullable|string',
            'create_invoice' => 'nullable|boolean', // Optional: allow user to skip invoice creation
        ]);

        $project = Project::create($validated);

        // Auto-create invoice if total_price > 0
        if ($project->total_price > 0) {
            $this->createProjectInvoice($project);
        }

        // Notify Programmer
        $this->notifyProgrammerAssignment($project, $wa, $email);

        return redirect()->route('accounting.projects.index')
            ->with('success', __('Project created successfully with invoice.'));
    }

    /**
     * Auto-create invoice for a project
     */
    protected function createProjectInvoice(Project $project): \App\Models\Invoice
    {
        // Get Default Currency
        $currency = \App\Models\Currency::where('is_base', true)->orWhere('code', 'EGP')->first();
        $currencyId = $currency ? $currency->id : null;

        // Generate invoice code (Consistent with InvoiceController)
        $lastInvoice = \App\Models\Invoice::latest()->first();
        $nextId = $lastInvoice ? ($lastInvoice->id + 1) : 1;
        $invoiceCode = 'INV-' . now()->format('Y') . '-' . str_pad($nextId, 4, '0', STR_PAD_LEFT);

        // Create the invoice
        $invoice = \App\Models\Invoice::create([
            'code' => $invoiceCode,
            'customer_id' => $project->customer_id,
            'currency_id' => $currencyId,
            'exchange_rate' => $currency ? $currency->exchange_rate : 1,
            'date' => now()->toDateString(),
            'due_date' => $project->end_date ?? now()->addDays(30)->toDateString(),
            'status' => 'unpaid',
            'subtotal' => $project->total_price,
            'tax_percent' => 0,
            'tax_amount' => 0,
            'total' => $project->total_price,
            'paid_amount' => 0,
            'notes' => __('Invoice for project') . ': ' . $project->name,
            'project_id' => $project->id,
        ]);

        // Create invoice item
        $invoice->items()->create([
            'description' => $project->name,
            'quantity' => 1,
            'unit_price' => $project->total_price,
            'total' => $project->total_price,
        ]);

        // Link project to invoice
        $project->update(['invoice_id' => $invoice->id]);

        return $invoice;
    }


    public function show(Project $project)
    {
        $project->load(['customer', 'programmer', 'payments.recorder', 'transactions.treasury', 'transactions.category']);
        $treasuries = \App\Models\FinancialTreasury::all(); // For payment Modal
        return view('accounting.projects.show', compact('project', 'treasuries'));
    }

    public function edit(Project $project)
    {
        $customers = Customer::orderBy('name')->get();
        $programmers = User::orderBy('name')->get();
        return view('accounting.projects.edit', compact('project', 'customers', 'programmers'));
    }

    public function update(Request $request, Project $project)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'customer_id' => 'required|exists:customers,id',
            'programmer_id' => 'required|exists:users,id',
            'total_price' => 'required|numeric|min:0',
            'commission_amount' => 'required|numeric|min:0',
            'progress_percent' => 'required|integer|min:0|max:100',
            'status' => 'required|in:pending,in_progress,completed,cancelled,on_hold',
            'start_date' => 'nullable|date',
            'end_date' => 'nullable|date',
            'notes' => 'nullable|string',
        ]);

        $project->update($validated);

        return redirect()->route('accounting.projects.show', $project)
            ->with('success', 'Project updated successfully.');
    }

    /**
     * Update progress and notes (specialized for programmers)
     */
    public function updateProgress(Request $request, Project $project, WaSenderService $wa)
    {
        $validated = $request->validate([
            'progress_percent' => 'required|integer|min:0|max:100',
            'status' => 'required|in:pending,in_progress,completed,cancelled,on_hold',
            'notes' => 'nullable|string',
        ]);

        $project->update($validated);

        // Notify Customer about progress
        $this->notifyCustomerProgress($project, $wa);

        return back()->with('success', 'Project progress updated.');
    }

    /**
     * Record a payment to the programmer
     */
    public function storePayment(Request $request, Project $project, WaSenderService $wa, EmailService $email)
    {
        $validated = $request->validate([
            'amount' => 'required|numeric|min:0.01',
            'treasury_id' => 'required|exists:financial_treasuries,id',
            'date' => 'required|date',
            'notes' => 'nullable|string',
        ]);

        // Legacy: Track in ProgrammerPayments
        $payment = $project->payments()->create([
            'programmer_id' => $project->programmer_id,
            'amount' => $validated['amount'],
            'date' => $validated['date'],
            'notes' => $validated['notes'],
            'user_id' => auth()->id() ?? 1,
        ]);

        // Automated Accounting: Record Expense
        // Identify Category (Cost of Goods Sold / Labor)
        $category = \App\Models\FinancialCategory::firstOrCreate(
            ['name' => 'Project Labor Costs', 'type' => 'expense'],
            ['description' => 'Payments to programmers and contractors']
        );

        $this->transactionService->recordExpense(
            $validated['amount'],
            $validated['treasury_id'],
            $category->id,
            "Payment to {$project->programmer->name} for Project: {$project->name}",
            $payment, // Link to payment model
            $project->id,
            $validated['date']
        );

        // Notify Programmer about payment
        $this->notifyProgrammerPayment($payment, $wa, $email);

        return back()->with('success', 'Payment recorded for programmer.');
    }

    public function programmerStatement(User $user)
    {
        $user->load(['projects.customer', 'programmerPayments.project']);
        return view('accounting.projects.programmer_statement', compact('user'));
    }

    protected function notifyProgrammerAssignment(Project $project, WaSenderService $wa, EmailService $email)
    {
        $prog = $project->programmer;
        $msg = "Hello {$prog->name},\n\nYou have been assigned to a new project: *{$project->name}*.\nCustomer: {$project->customer->name}\nCommission: {$project->commission_amount} EGP.\n\nPlease check your dashboard for details.";

        if ($wa->isConfigured()) {
            $wa->sendMessage($prog->phone ?? '', $msg);
        }

        if ($email->isConfigured()) {
            $email->sendRaw($prog->email, "New Project Assigned: {$project->name}", $msg);
        }
    }

    protected function notifyCustomerProgress(Project $project, WaSenderService $wa)
    {
        $cust = $project->customer;
        $msg = "Dear {$cust->name},\n\nGood news! Your project *{$project->name}* is now {$project->progress_percent}% complete.\nStatus: {$project->status}.\n\nThank you for choosing us!";

        $phone = $cust->whatsapp ?: $cust->phone;
        if ($wa->isConfigured() && $phone) {
            $wa->sendMessage($phone, $msg);
        }
    }

    protected function notifyProgrammerPayment(ProgrammerPayment $payment, WaSenderService $wa, EmailService $email)
    {
        $prog = $payment->programmer;
        $project = $payment->project;
        $date = $payment->date instanceof Carbon ? $payment->date : Carbon::parse($payment->date);
        $msg = "Hello {$prog->name},\n\nA new payment of *{$payment->amount} EGP* has been recorded for project: *{$project->name}*.\nDate: " . $date->format('Y-m-d') . "\nYour remaining balance for this project: {$project->remaining_programmer_balance} EGP.";

        if ($wa->isConfigured()) {
            $wa->sendMessage($prog->phone ?? '', $msg);
        }

        if ($email->isConfigured()) {
            $email->sendRaw($prog->email, "Payment Received: {$project->name}", $msg);
        }
    }

    /**
     * Delete a project
     */
    public function destroy(Project $project)
    {
        // Delete related records first
        $project->payments()->delete();
        $project->transactions()->delete();

        // Delete the project
        $project->delete();

        return redirect()->route('accounting.projects.index')
            ->with('success', __('Project deleted successfully.'));
    }
}

