<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\OperatorPartnership;
use App\Models\Tenant;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

/**
 * Handles: Affiliate Directory, Affiliate Requests, My Affiliates
 */
class OperatorPartnershipController extends Controller
{
    private function myTenantId(Request $request): int
    {
        $user = $request->user();
        return (int) ($user->tenant_id ?? $request->header('X-Tenant-ID', 1));
    }

    // ── DIRECTORY ── list all OTHER tenants (operators) ────────────────────
    public function directory(Request $request)
    {
        try {
            $myId    = $this->myTenantId($request);
            $search  = $request->get('search', '');
            $status  = $request->get('status', 'active');
            $perPage = (int) $request->get('per_page', 20);

            $query = Tenant::where('id', '!=', $myId)
                ->where('status', $status);

            if ($search) {
                $query->where(function ($q) use ($search) {
                    $q->where('name', 'like', "%{$search}%")
                      ->orWhere('support_email', 'like', "%{$search}%");
                });
            }

            $tenants = $query->with([
                'settings',
                'receivedPartnerships' => fn($q) => $q->where('requester_tenant_id', $myId),
                'sentPartnerships'     => fn($q) => $q->where('receiver_tenant_id', $myId),
            ])->paginate($perPage);

            $data = collect($tenants->items())->map(function ($t) use ($myId) {
                // Determine partnership status with ME
                $partnershipStatus = 'none';
                $partnershipId = null;

                $sent = $t->receivedPartnerships->first();
                $received = $t->sentPartnerships->first();

                if ($sent) {
                    $partnershipStatus = $sent->status === 'active' ? 'connected' : $sent->status;
                    $partnershipId = $sent->id;
                } elseif ($received) {
                    $partnershipStatus = $received->status === 'active' ? 'connected' : $received->status;
                    $partnershipId = $received->id;
                }

                $vehicles = $t->settings?->available_vehicle_types
                    ? json_decode($t->settings->available_vehicle_types, true)
                    : ['Sedan', 'SUV'];

                return [
                    'id'                 => $t->id,
                    'name'               => $t->name,
                    'slug'               => $t->slug,
                    'logo_url'           => $t->logo_url,
                    'website_url'        => $t->website_url,
                    'support_email'      => $t->support_email,
                    'support_phone'      => $t->support_phone,
                    'subscription_plan'  => $t->subscription_plan,
                    'region'             => $t->settings?->region ?? 'N/A',
                    'vehicle_types'      => $vehicles,
                    'partnership_status' => $partnershipStatus,
                    'partnership_id'     => $partnershipId,
                    'member_since'       => $t->created_at?->format('Y-m-d'),
                ];
            });

            return response()->json([
                'success' => true,
                'data'    => $data,
                'pagination' => [
                    'current_page' => $tenants->currentPage(),
                    'total'        => $tenants->total(),
                    'per_page'     => $tenants->perPage(),
                    'last_page'    => $tenants->lastPage(),
                ],
            ]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── REQUESTS ── incoming + outgoing partnership requests ────────────────
    public function requests(Request $request)
    {
        try {
            $myId = $this->myTenantId($request);

            $incoming = OperatorPartnership::with(['requesterTenant'])
                ->where('receiver_tenant_id', $myId)
                ->whereIn('status', ['pending', 'rejected'])
                ->orderBy('created_at', 'desc')
                ->get()
                ->map(fn($p) => $this->mapPartnership($p, $myId, 'incoming'));

            $outgoing = OperatorPartnership::with(['receiverTenant'])
                ->where('requester_tenant_id', $myId)
                ->whereIn('status', ['pending', 'rejected', 'cancelled'])
                ->orderBy('created_at', 'desc')
                ->get()
                ->map(fn($p) => $this->mapPartnership($p, $myId, 'outgoing'));

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

    // ── MY AFFILIATES ── confirmed partners ─────────────────────────────────
    public function myAffiliates(Request $request)
    {
        try {
            $myId = $this->myTenantId($request);

            $partnerships = OperatorPartnership::with(['requesterTenant.settings', 'receiverTenant.settings'])
                ->where(function ($q) use ($myId) {
                    $q->where('requester_tenant_id', $myId)
                      ->orWhere('receiver_tenant_id', $myId);
                })
                ->where('status', 'active')
                ->orderBy('accepted_at', 'desc')
                ->get()
                ->map(fn($p) => $this->mapActivePartnership($p, $myId));

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

    // ── SEND REQUEST ────────────────────────────────────────────────────────
    public function sendRequest(Request $request)
    {
        $v = Validator::make($request->all(), [
            'receiver_tenant_id' => 'required|integer|exists:tenants,id',
            'notes'              => 'nullable|string|max:500',
        ]);
        if ($v->fails()) {
            return response()->json(['success' => false, 'errors' => $v->errors()], 422);
        }

        try {
            $myId = $this->myTenantId($request);
            $receiverId = (int) $request->receiver_tenant_id;

            if ($myId === $receiverId) {
                return response()->json(['success' => false, 'message' => 'Cannot partner with yourself'], 422);
            }

            // Check for existing
            $existing = OperatorPartnership::where(function ($q) use ($myId, $receiverId) {
                $q->where('requester_tenant_id', $myId)->where('receiver_tenant_id', $receiverId);
            })->orWhere(function ($q) use ($myId, $receiverId) {
                $q->where('requester_tenant_id', $receiverId)->where('receiver_tenant_id', $myId);
            })->whereNotIn('status', ['rejected', 'cancelled'])->first();

            if ($existing) {
                return response()->json(['success' => false, 'message' => 'Partnership already exists'], 422);
            }

            $p = OperatorPartnership::create([
                'requester_tenant_id' => $myId,
                'receiver_tenant_id'  => $receiverId,
                'notes'               => $request->notes,
                'status'              => 'pending',
            ]);

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

    // ── ACCEPT / REJECT ─────────────────────────────────────────────────────
    public function accept(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)->where('receiver_tenant_id', $myId)
                ->where('status', 'pending')->firstOrFail();

            $p->update(['status' => 'active', 'accepted_at' => now()]);
            return response()->json(['success' => true, 'data' => $p, 'message' => 'Partnership accepted']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function reject(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)->where('receiver_tenant_id', $myId)
                ->where('status', 'pending')->firstOrFail();

            $p->update([
                'status'           => 'rejected',
                'rejected_at'      => now(),
                'rejection_reason' => $request->get('reason'),
            ]);
            return response()->json(['success' => true, 'message' => 'Partnership rejected']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── CANCEL / WITHDRAW ────────────────────────────────────────────────────
    public function cancel(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)
                ->where('requester_tenant_id', $myId)
                ->where('status', 'pending')
                ->firstOrFail();

            $p->update(['status' => 'cancelled']);
            return response()->json(['success' => true, 'message' => 'Request withdrawn']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── SUSPEND / REACTIVATE ─────────────────────────────────────────────────
    public function suspend(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)
                ->where(fn($q) => $q->where('requester_tenant_id', $myId)->orWhere('receiver_tenant_id', $myId))
                ->where('status', 'active')->firstOrFail();

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

    public function reactivate(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)
                ->where(fn($q) => $q->where('requester_tenant_id', $myId)->orWhere('receiver_tenant_id', $myId))
                ->where('status', 'suspended')->firstOrFail();

            $p->update(['status' => 'active']);
            return response()->json(['success' => true, 'message' => 'Partnership reactivated']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function remove(Request $request, int $id)
    {
        try {
            $myId = $this->myTenantId($request);
            $p = OperatorPartnership::where('id', $id)
                ->where(fn($q) => $q->where('requester_tenant_id', $myId)->orWhere('receiver_tenant_id', $myId))
                ->firstOrFail();
            $p->delete();
            return response()->json(['success' => true, 'message' => 'Partnership removed']);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── Helpers ──────────────────────────────────────────────────────────────
    private function mapPartnership(OperatorPartnership $p, int $myId, string $direction): array
    {
        $other = $direction === 'incoming' ? $p->requesterTenant : $p->receiverTenant;
        return [
            'id'             => $p->id,
            'direction'      => $direction,
            'status'         => $p->status,
            'partner_id'     => $other?->id,
            'partner_name'   => $other?->name ?? 'Unknown',
            'partner_email'  => $other?->support_email,
            'partner_phone'  => $other?->support_phone,
            'partner_logo'   => $other?->logo_url,
            'notes'          => $p->notes,
            'rejection_reason' => $p->rejection_reason,
            'created_at'     => $p->created_at?->format('Y-m-d H:i'),
            'accepted_at'    => $p->accepted_at?->format('Y-m-d H:i'),
        ];
    }

    private function mapActivePartnership(OperatorPartnership $p, int $myId): array
    {
        $other = $p->requester_tenant_id === $myId ? $p->receiverTenant : $p->requesterTenant;

        $jobsSent     = \App\Models\OperatorFarmedJob::where('from_tenant_id', $myId)->where('to_tenant_id', $other?->id)->count();
        $jobsReceived = \App\Models\OperatorFarmedJob::where('to_tenant_id', $myId)->where('from_tenant_id', $other?->id)->count();
        $revenue      = \App\Models\OperatorFarmedJob::where('from_tenant_id', $myId)->where('to_tenant_id', $other?->id)->where('status', 'completed')->sum('agreed_rate');

        $vehicles = $other?->settings?->available_vehicle_types
            ? json_decode($other->settings->available_vehicle_types, true)
            : [];

        return [
            'partnership_id'       => $p->id,
            'partner_tenant_id'    => $other?->id,
            'partner_name'         => $other?->name ?? 'Unknown',
            'partner_email'        => $other?->support_email,
            'partner_phone'        => $other?->support_phone,
            'partner_logo'         => $other?->logo_url,
            'commission_rate'      => $p->default_commission_rate,
            'status'               => $p->status,
            'accepted_at'          => $p->accepted_at?->format('Y-m-d'),
            'jobs_sent'            => $jobsSent,
            'jobs_received'        => $jobsReceived,
            'total_revenue'        => number_format((float)$revenue, 2),
            'notes'                => $p->notes,
            'vehicle_types'        => is_array($vehicles) ? $vehicles : [],
        ];
    }
}
