<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ProjectMonthPlan;
use App\Services\ReconciliationCalculator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class ProjectMonthPlanController extends Controller
{
    public function __construct(
        private ReconciliationCalculator $reconciliationCalculator
    ) {}

    /**
     * GET /api/project-month-plans?year=2026
     * Returns month-plan grid payload by project/month for the year.
     */
    public function index(Request $request): JsonResponse
    {
        $year = $request->query('year', date('Y'));

        $startDate = "{$year}-01-01";
        $endDate = "{$year}-12-01";

        $plans = ProjectMonthPlan::whereBetween('month', [$startDate, $endDate])
            ->with('project')
            ->get()
            ->groupBy('project_id');

        // Get all projects for the year with status relationship
        $projects = \App\Models\Project::with('status')->get();

        // Build grid payload
        $data = $projects->map(function ($project) use ($plans, $year) {
            $projectPlans = $plans->get($project->id, collect());
            $planByMonth = $projectPlans->mapWithKeys(function ($plan) {
                $monthKey = $plan->month?->format('Y-m-01');

                if ($monthKey === null) {
                    return [];
                }

                return [$monthKey => $plan];
            });

            $months = [];
            for ($month = 1; $month <= 12; $month++) {
                $monthDate = sprintf('%04d-%02d-01', $year, $month);
                $plan = $planByMonth->get($monthDate);

                $months[$monthDate] = $plan
                    ? [
                        'id' => $plan->id,
                        'planned_hours' => $plan->planned_hours,
                        'is_blank' => $plan->planned_hours === null,
                    ]
                    : null;
            }

            return [
                'project_id' => $project->id,
                'project_code' => $project->code,
                'project_name' => $project->title,
                'project_status' => $project->status?->name,
                'approved_estimate' => $project->approved_estimate,
                'months' => $months,
            ];
        });

        // Calculate reconciliation status for each project using the service
        $reconciliationResults = $this->reconciliationCalculator->calculateForProjects($projects, (int) $year);

        $data = $data->map(function ($project) use ($reconciliationResults) {
            $project['plan_sum'] = $reconciliationResults[$project['project_id']]['plan_sum'] ?? 0;
            $project['reconciliation_status'] = $reconciliationResults[$project['project_id']]['status'] ?? 'UNDER';

            return $project;
        });

        return response()->json([
            'data' => $data,
            'meta' => [
                'year' => (int) $year,
            ],
        ]);
    }

    /**
     * PUT /api/project-month-plans/bulk
     * Bulk upsert month plan cells.
     */
    public function bulkUpdate(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'year' => 'required|integer|min:2020|max:2100',
            'items' => 'required|array',
            'items.*.project_id' => 'required|uuid|exists:projects,id',
            'items.*.month' => 'required|date_format:Y-m',
            'items.*.planned_hours' => 'nullable|numeric|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        $year = $request->input('year');
        $items = $request->input('items');
        $created = 0;
        $updated = 0;
        $cleared = 0;

        foreach ($items as $item) {
            $projectId = $item['project_id'];
            $month = $item['month'].'-01'; // Convert YYYY-MM to YYYY-MM-01
            $plannedHours = $item['planned_hours']; // Can be null to clear

            $plan = ProjectMonthPlan::firstOrNew([
                'project_id' => $projectId,
                'month' => $month,
            ]);

            if ($plannedHours === null && $plan->exists) {
                // Clear semantics: delete the row to represent blank
                $plan->delete();
                $cleared++;
            } elseif ($plannedHours !== null) {
                $plan->planned_hours = $plannedHours;
                $plan->save();

                if (! $plan->wasRecentlyCreated) {
                    $updated++;
                } else {
                    $created++;
                }
            }
        }

        return response()->json([
            'message' => 'Bulk update complete',
            'summary' => [
                'created' => $created,
                'updated' => $updated,
                'cleared' => $cleared,
            ],
        ]);
    }
}
