<?php

namespace App\Http\Controllers;

use App\Helpers\TenantHelper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class RestaurantRegisterController extends Controller
{
    // ── GET /register/countries ───────────────────────────────────────────────

    public function countries()
    {
        $countries = DB::table('countries')
            ->where('is_active', true)
            ->select('id', 'name', 'code', 'schema_name', 'currency', 'auto_approve_vendors')
            ->get();

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

    // ── GET /register/cuisines ────────────────────────────────────────────────

    public function cuisines(Request $request)
    {
        $country = DB::table('countries')
            ->where('id', $request->query('country_id'))
            ->where('is_active', true)
            ->select('schema_name')
            ->first();

        if (!$country) {
            return response()->json([], 404);
        }

        TenantHelper::setSchema($country->schema_name);

        $cuisines = DB::connection('pgsql_country')
            ->table('vendor_categories')
            ->where('publish', true)
            ->select('id', 'title')
            ->get();

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

    // ── POST /register/upload-image ───────────────────────────────────────────

    public function uploadImage(Request $request)
    {
        $request->validate(['image' => 'required|image|max:5120']);

        $path = $request->file('image')->store('restaurant-images', 'public');

        return response()->json(['url' => Storage::disk('public')->url($path)]);
    }

    // ── POST /register/delete-image ───────────────────────────────────────────

    public function deleteImage(Request $request)
    {
        $url  = $request->input('url');
        $path = str_replace('/storage/', '', parse_url($url, PHP_URL_PATH));
        Storage::disk('public')->delete($path);

        return response()->json(['success' => true]);
    }

    // ── POST /register/restaurant ─────────────────────────────────────────────

    public function register(Request $request)
    {
        $data = $request->json()->all();

        // ── Inline validation ─────────────────────────────────────────────────
        try {
            $this->validateRegistration($data);
        } catch (ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => collect($e->errors())->flatten()->first(),
                'errors'  => $e->errors(),
            ], 422);
        }

        // ── Resolve country ───────────────────────────────────────────────────
        $country = DB::table('countries')
            ->where('id', $data['country_id'])
            ->where('is_active', true)
            ->first();

        if (!$country) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid or inactive country selected.',
            ], 422);
        }

        // ── Check email uniqueness ────────────────────────────────────────────
        if (DB::table('admin_user')->where('email', $data['email'])->exists()) {
            return response()->json([
                'success' => false,
                'message' => 'This email is already registered.',
            ], 422);
        }

        $autoApprove = (bool) $country->auto_approve_vendors;
        $authorName  = trim($data['first_name'] . ' ' . ($data['last_name'] ?? ''));
        $now         = now();

        DB::beginTransaction();
        try {
            // ── 1. public.admin_user ──────────────────────────────────────────
            DB::table('admin_user')->insert([
                'name'       => $authorName,
                'email'      => $data['email'],
                'password'   => Hash::make($data['password']),
                'created_at' => $now,
                'updated_at' => $now,
            ]);

            $adminUserId = DB::table('admin_user')
                ->where('email', $data['email'])
                ->value('id');

            // ── 2. public.users ───────────────────────────────────────────────
            DB::table('users')->insert([
                'firstName'         => $data['first_name'],
                'lastName'          => $data['last_name'] ?? '',
                'email'             => $data['email'],
                'phoneNumber'       => $data['phone'],
                'phoneNumberPrefix' => $data['phone_prefix'] ?? null,
                'profilePictureURL' => $data['owner_photo'] ?? '',
                'role'              => 'vendor',
                'active'            => $autoApprove ? '1' : '0',
                'createdAt'         => (string) $now,
                'updatedAt'         => (string) $now,
            ]);

            // ── 3. public.vendor_users ────────────────────────────────────────
            DB::table('vendor_users')->insert([
                'user_id'         => $adminUserId,
                'uuid'            => (string) Str::uuid(),
                'email'           => $data['email'],
                'roleType'        => 'vendor',
                'restaurant_name' => $data['restaurant_name'],
                'schema_name'     => $country->schema_name,
            ]);

            // ── 4. Switch to country schema ───────────────────────────────────
            TenantHelper::setSchema($country->schema_name);

            $conn = DB::connection('pgsql_country');

            // ── 5. {schema}.vendors ───────────────────────────────────────────
            $conn->table('vendors')->insert([
                'owner_id'               => $adminUserId,
                'title'                  => $data['restaurant_name'],
                'description'            => $data['description']    ?? null,
                'category_id'            => $data['category_id']    ?? null,
                'category_title'         => $data['category_title'] ?? null,
                'email'                  => $data['restaurant_email'],
                'phone_number'           => $data['restaurant_phone'],
                'author_name'            => $authorName,
                'author_profile_pic'     => $data['owner_photo']    ?? null,
                'address'                => $data['address'],
                'latitude'               => $data['latitude'],
                'longitude'              => $data['longitude'],
                'currency'               => $country->currency,
                'rest_status'            => $data['rest_status']    ?? true,
                'active'                 => $autoApprove,
                'publish'                => $autoApprove,
                'photo'                  => $data['photo']          ?? null,
                'photos'                 => json_encode($data['photos']      ?? []),
                'restaurant_menu_photos' => json_encode($data['menu_photos'] ?? []),
                'filters_ids'            => json_encode($data['filters']     ?? []),
                'enabled_dine_in_future' => $data['enabled_dine_in']         ?? false,
                'open_dine_time'         => $data['open_dine_time']  ?? null,
                'close_dine_time'        => $data['close_dine_time'] ?? null,
                'restaurant_cost'        => $data['restaurant_cost'] ?? null,
                'created_at'             => $now,
                'updated_at'             => $now,
            ]);

            $vendorId = $conn->table('vendors')
                ->where('owner_id', $adminUserId)
                ->value('id');

            // ── 6. {schema}.vendor_working_hours ─────────────────────────────
            $this->saveWorkingHours($conn, $vendorId, $data['working_hours'] ?? []);

            DB::commit();

        } catch (\Throwable $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
            ], 500);
        }

        $message = $autoApprove
            ? trans('lang.thank_you_signup_msg')
            : trans('lang.signup_waiting_approval');

        return response()->json(['success' => true, 'message' => $message]);
    }

    // ── POST /api/register/phone ──────────────────────────────────────────────
    // Simple phone-based registration (no SMS OTP — account pending approval)
    public function phoneStore(Request $request): \Illuminate\Http\JsonResponse
    {
        $firstName = trim($request->input('firstName', ''));
        $lastName  = trim($request->input('lastName',  ''));
        $phone     = trim($request->input('phone',     ''));

        if (!$firstName || !$phone) {
            return response()->json(['success' => false, 'message' => 'First name and phone number are required.'], 422);
        }

        // Use placeholder email keyed on phone number
        $sanitisedPhone   = preg_replace('/[^0-9]/', '', $phone);
        $placeholderEmail = 'phone_' . $sanitisedPhone . '@vendor.placeholder';

        if (DB::table('admin_user')->where('email', $placeholderEmail)->exists()) {
            return response()->json(['success' => false, 'message' => 'A registration with this phone number already exists.'], 422);
        }

        // Resolve the default country / schema from the main countries table
        $country = DB::table('countries')->where('is_active', true)->orderBy('id')->first();
        if (!$country) {
            return response()->json(['success' => false, 'message' => 'No active country configured.'], 500);
        }

        $autoApprove = (bool) ($country->auto_approve_vendors ?? false);
        $authorName  = trim("$firstName $lastName");
        $now         = now();

        DB::beginTransaction();
        try {
            DB::table('admin_user')->insert([
                'name'       => $authorName,
                'email'      => $placeholderEmail,
                'password'   => Hash::make(Str::random(32)),
                'created_at' => $now,
                'updated_at' => $now,
            ]);

            $adminUserId = DB::table('admin_user')->where('email', $placeholderEmail)->value('id');

            DB::table('users')->insert([
                'firstName'   => $firstName,
                'lastName'    => $lastName,
                'email'       => '',
                'phoneNumber' => $phone,
                'role'        => 'vendor',
                'active'      => $autoApprove ? '1' : '0',
                'createdAt'   => (string) $now,
                'updatedAt'   => (string) $now,
            ]);

            $vendorUuid = (string) Str::uuid();

            DB::table('vendor_users')->insert([
                'user_id'     => $adminUserId,
                'uuid'        => $vendorUuid,
                'email'       => '',
                'roleType'    => 'vendor',
                'schema_name' => $country->schema_name,
            ]);

            TenantHelper::setSchema($country->schema_name);
            $conn = DB::connection('pgsql_country');

            $conn->table('vendors')->insert([
                'owner_id'    => $adminUserId,
                'title'       => $authorName,
                'phone_number'=> $phone,
                'author_name' => $authorName,
                'currency'    => $country->currency,
                'active'      => $autoApprove,
                'publish'     => $autoApprove,
                'rest_status' => false,
                'created_at'  => $now,
                'updated_at'  => $now,
            ]);

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }

        $message = $autoApprove
            ? trans('lang.thank_you_signup_msg')
            : trans('lang.signup_waiting_approval');

        return response()->json(['success' => true, 'message' => $message]);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Private helpers
    // ─────────────────────────────────────────────────────────────────────────

    private function validateRegistration(array $data): void
    {
        $rules = [
            'country_id'          => 'required|integer',
            'first_name'          => 'required|string|max:100',
            'email'               => 'required|email|max:150',
            'password'            => 'required|string|min:6',
            'phone'               => 'required|string|max:30',
            'restaurant_name'     => 'required|string|max:255',
            'category_id'         => 'required|integer',
            'restaurant_phone'    => 'required|string|max:30',
            'restaurant_email'    => 'required|email|max:150',
            'address'             => 'required|string|max:500',
            'latitude'            => 'required|numeric|between:-90,90',
            'longitude'           => 'required|numeric|between:-180,180',
            'description'         => 'required|string|max:1000',
            'photo'               => 'nullable|string|url',
            'photos'              => 'nullable|array',
            'photos.*'            => 'string|url',
            'menu_photos'         => 'nullable|array',
            'menu_photos.*'       => 'string|url',
            'rest_status'         => 'nullable|boolean',
            'enabled_dine_in'     => 'nullable|boolean',
            'open_dine_time'      => 'nullable|date_format:H:i',
            'close_dine_time'     => 'nullable|date_format:H:i',
            'restaurant_cost'     => 'nullable|string|max:50',
            'filters'             => 'nullable|array',
            'working_hours'                   => 'nullable|array',
            'working_hours.*.day'             => 'required_with:working_hours|string|in:Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday',
            'working_hours.*.timeslot'        => 'nullable|array',
            'working_hours.*.timeslot.*.from' => 'required_with:working_hours.*.timeslot.*|date_format:H:i',
            'working_hours.*.timeslot.*.to'   => 'required_with:working_hours.*.timeslot.*|date_format:H:i',
        ];

        $messages = [
            'country_id.required'       => 'Please select your country.',
            'first_name.required'       => trans('lang.enter_owners_name_error'),
            'email.required'            => trans('lang.enter_owners_email'),
            'email.email'               => trans('lang.restaurant_email_invalid_error'),
            'password.required'         => trans('lang.enter_owners_password_error'),
            'phone.required'            => trans('lang.enter_owners_phone'),
            'restaurant_name.required'  => trans('lang.restaurant_name_error'),
            'category_id.required'      => trans('lang.restaurant_cuisine_error'),
            'restaurant_phone.required' => trans('lang.restaurant_phone_error'),
            'restaurant_email.required' => trans('lang.restaurant_email_error'),
            'restaurant_email.email'    => trans('lang.restaurant_email_invalid_error'),
            'address.required'          => trans('lang.restaurant_address_error'),
            'latitude.required'         => trans('lang.restaurant_lattitude_error'),
            'latitude.between'          => trans('lang.restaurant_lattitude_limit_error'),
            'longitude.required'        => trans('lang.restaurant_longitude_error'),
            'longitude.between'         => trans('lang.restaurant_longitude_limit_error'),
            'description.required'      => trans('lang.restaurant_description_error'),
        ];

        $validator = validator($data, $rules, $messages);

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }
    }

    /**
     * Inserts rows into {schema}.vendor_working_hours.
     * Days with no slots get a single is_closed = true row.
     */
    private function saveWorkingHours($conn, int $vendorId, array $workingHours): void
    {
        $conn->table('vendor_working_hours')
             ->where('vendor_id', $vendorId)
             ->delete();

        $rows = [];
        $now  = now();

        foreach ($workingHours as $dayData) {
            $day   = $dayData['day']      ?? null;
            $slots = $dayData['timeslot'] ?? [];

            if (!$day) continue;

            if (empty($slots)) {
                $rows[] = [
                    'vendor_id'    => $vendorId,
                    'day_of_week'  => $day,
                    'is_closed'    => true,
                    'open_time'    => null,
                    'close_time'   => null,
                    'is_special'   => false,
                    'special_date' => null,
                    'created_at'   => $now,
                ];
                continue;
            }

            foreach ($slots as $slot) {
                $from = $slot['from'] ?? null;
                $to   = $slot['to']   ?? null;
                if (!$from || !$to) continue;

                $rows[] = [
                    'vendor_id'    => $vendorId,
                    'day_of_week'  => $day,
                    'is_closed'    => false,
                    'open_time'    => $from,
                    'close_time'   => $to,
                    'is_special'   => false,
                    'special_date' => null,
                    'created_at'   => $now,
                ];
            }
        }

        if (!empty($rows)) {
            foreach (array_chunk($rows, 500) as $chunk) {
                $conn->table('vendor_working_hours')->insert($chunk);
            }
        }
    }
}