
#!/bin/bash
set -e

echo "==> ডিজিটালওয়ার্কশপ সেটআপ শুরু..."

# 1. Laravel প্রোজেক্ট তৈরি
if [ ! -f backend/artisan ]; then
  echo "--> Laravel ইন্সটল হচ্ছে..."
  docker run --rm -v "$(pwd)/backend":/app composer create-project laravel/laravel . "^11.0"
else
  echo "--> Laravel আগেই আছে, স্কিপ করা হলো"
fi

# 2. .env তৈরি
if [ ! -f backend/.env ]; then
  cp backend/.env.example backend/.env
fi

# 3. কাস্টম ফাইল লিখা (মডেল, কন্ট্রোলার, রাউট, মিডলওয়্যার)
echo "--> কাস্টম কোড লেখা হচ্ছে..."

# User Model
cat > backend/app/Models/User.php << 'EOF'
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens;

    protected $fillable = [
        'name', 'phone', 'password', 'role', 'otp_code', 'otp_expires_at', 'phone_verified_at'
    ];

    protected $hidden = ['password', 'remember_token', 'otp_code'];

    protected $casts = [
        'phone_verified_at' => 'datetime',
        'otp_expires_at' => 'datetime',
        'password' => 'hashed',
    ];

    public function vendor()
    {
        return $this->hasOne(Vendor::class);
    }

    public function isAdmin()
    {
        return in_array($this->role, ['admin', 'customer_care']);
    }
}
EOF

# Vendor Model
cat > backend/app/Models/Vendor.php << 'EOF'
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Vendor extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id', 'store_name', 'nid_or_trade_license',
        'approval_status', 'payout_method', 'payout_details'
    ];

    protected $casts = [
        'payout_details' => 'array',
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function products()
    {
        return $this->hasMany(Product::class);
    }
}
EOF

# Category Model
cat > backend/app/Models/Category.php << 'EOF'
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = ['name', 'slug', 'parent_id'];

    public function products()
    {
        return $this->hasMany(Product::class);
    }
}
EOF

# Product Model
cat > backend/app/Models/Product.php << 'EOF'
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'vendor_id', 'category_id', 'name', 'description', 'price',
        'currency', 'stock', 'approval_status'
    ];

    public function vendor()
    {
        return $this->belongsTo(Vendor::class);
    }

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function scopeActive($query)
    {
        return $query->where('approval_status', 'active');
    }
}
EOF

# SMS Service
mkdir -p backend/app/Services
cat > backend/app/Services/SmsService.php << 'EOF'
<?php
namespace App\Services;

use Illuminate\Support\Facades\Http;

class SmsService
{
    public function send(string $phone, string $message): bool
    {
        $apiKey = env('HTTPSMS_API_KEY');
        $from = env('HTTPSMS_FROM_NUMBER');

        if (!$apiKey || !$from) {
            // ডেভেলপমেন্ট মোড: OTP লগে দেখান
            \Log::info("OTP for $phone: $message");
            return true;
        }

        $response = Http::withHeaders([
            'x-api-key' => $apiKey,
        ])->post('https://api.httpsms.com/v1/messages/send', [
            'content' => $message,
            'from' => $from,
            'to' => $phone,
        ]);

        return $response->successful();
    }
}
EOF

# Auth Controller
mkdir -p backend/app/Http/Controllers/Api
cat > backend/app/Http/Controllers/Api/AuthController.php << 'EOF'
<?php
namespace App\Http\Controllers\Api;

use App\Models\User;
use App\Services\SmsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string',
            'phone' => 'required|string|unique:users,phone',
            'password' => 'required|min:6|confirmed',
        ]);

        $otp = app()->isProduction() ? rand(100000, 999999) : 123456;
        $user = User::create([
            'name' => $data['name'],
            'phone' => $data['phone'],
            'password' => $data['password'],
            'otp_code' => $otp,
            'otp_expires_at' => now()->addMinutes(5),
            'role' => 'buyer',
        ]);

        // OTP পাঠান
        app(SmsService::class)->send($data['phone'], "Your DigitalWorkshop OTP is: $otp");

        return response()->json([
            'message' => 'OTP sent',
            'debug_otp' => app()->isProduction() ? null : $otp,
        ]);
    }

    public function verifyOtp(Request $request)
    {
        $data = $request->validate([
            'phone' => 'required|string',
            'code' => 'required|digits:6',
        ]);

        $user = User::where('phone', $data['phone'])->first();
        if (!$user || $user->otp_code !== $data['code'] || now()->gt($user->otp_expires_at)) {
            return response()->json(['message' => 'Invalid OTP'], 422);
        }

        $user->phone_verified_at = now();
        $user->otp_code = null;
        $user->otp_expires_at = null;
        $user->save();

        $token = $user->createToken('api')->plainTextToken;

        return response()->json(['token' => $token, 'user' => $user]);
    }

    public function login(Request $request)
    {
        $data = $request->validate([
            'phone' => 'required|string',
            'password' => 'required',
        ]);

        $user = User::where('phone', $data['phone'])->first();
        if (!$user || !Hash::check($data['password'], $user->password)) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        if (!$user->phone_verified_at) {
            return response()->json(['message' => 'Phone not verified'], 403);
        }

        $token = $user->createToken('api')->plainTextToken;
        return response()->json(['token' => $token, 'user' => $user]);
    }

    public function user(Request $request)
    {
        return $request->user()->load('vendor');
    }
}
EOF

# Vendor Controller
cat > backend/app/Http/Controllers/Api/VendorController.php << 'EOF'
<?php
namespace App\Http\Controllers\Api;

use App\Models\Vendor;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class VendorController extends Controller
{
    public function apply(Request $request)
    {
        $user = $request->user();
        if ($user->vendor) {
            return response()->json(['message' => 'Vendor application already submitted'], 422);
        }

        $data = $request->validate([
            'store_name' => 'required|string',
            'nid_or_trade_license' => 'required|string',
            'payout_method' => 'required|in:bkash,nagad,sslcommerz',
            'payout_details' => 'required|array',
        ]);

        $vendor = Vendor::create([
            'user_id' => $user->id,
            'store_name' => $data['store_name'],
            'nid_or_trade_license' => $data['nid_or_trade_license'],
            'payout_method' => $data['payout_method'],
            'payout_details' => $data['payout_details'],
            'approval_status' => 'pending',
        ]);

        return response()->json(['message' => 'Application submitted', 'vendor' => $vendor], 201);
    }

    public function status(Request $request)
    {
        $vendor = $request->user()->vendor;
        if (!$vendor) {
            return response()->json(['message' => 'Not a vendor'], 404);
        }
        return response()->json($vendor);
    }
}
EOF

# Product Controller
cat > backend/app/Http/Controllers/Api/ProductController.php << 'EOF'
<?php
namespace App\Http\Controllers\Api;

use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ProductController extends Controller
{
    public function index(Request $request)
    {
        $products = Product::active()->with('vendor', 'category')->latest()->paginate(20);
        return response()->json($products);
    }

    public function store(Request $request)
    {
        $user = $request->user();
        $vendor = $user->vendor;
        if (!$vendor || $vendor->approval_status !== 'approved') {
            return response()->json(['message' => 'Vendor not approved'], 403);
        }

        $data = $request->validate([
            'category_id' => 'required|exists:categories,id',
            'name' => 'required|string',
            'description' => 'nullable|string',
            'price' => 'required|numeric',
            'currency' => 'required|in:BDT,USD',
            'stock' => 'required|integer',
        ]);

        $product = Product::create([
            'vendor_id' => $vendor->id,
            ...$data,
            'approval_status' => 'pending_review',
        ]);

        return response()->json(['message' => 'Product submitted for review', 'product' => $product], 201);
    }

    public function show(Product $product)
    {
        if ($product->approval_status !== 'active') {
            abort(404);
        }
        return response()->json($product->load('vendor', 'category'));
    }
}
EOF

# Admin Approval Controller
cat > backend/app/Http/Controllers/Api/AdminController.php << 'EOF'
<?php
namespace App\Http\Controllers\Api;

use App\Models\Vendor;
use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class AdminController extends Controller
{
    public function approveVendor(Request $request, $vendorId)
    {
        $vendor = Vendor::findOrFail($vendorId);
        $vendor->update(['approval_status' => 'approved']);
        return response()->json(['message' => 'Vendor approved', 'vendor' => $vendor]);
    }

    public function rejectVendor(Request $request, $vendorId)
    {
        $vendor = Vendor::findOrFail($vendorId);
        $vendor->update(['approval_status' => 'rejected']);
        return response()->json(['message' => 'Vendor rejected', 'vendor' => $vendor]);
    }

    public function pendingVendors()
    {
        return Vendor::where('approval_status', 'pending')->with('user')->paginate(20);
    }

    public function approveProduct(Request $request, $productId)
    {
        $product = Product::findOrFail($productId);
        $product->update(['approval_status' => 'active']);
        return response()->json(['message' => 'Product approved', 'product' => $product]);
    }

    public function rejectProduct(Request $request, $productId)
    {
        $product = Product::findOrFail($productId);
        $product->update(['approval_status' => 'rejected']);
        return response()->json(['message' => 'Product rejected', 'product' => $product]);
    }

    public function pendingProducts()
    {
        return Product::where('approval_status', 'pending_review')->with('vendor')->paginate(20);
    }
}
EOF

# Middleware
cat > backend/app/Http/Middleware/EnsureUserHasRole.php << 'EOF'
<?php
namespace App\Http\Middleware;

use Closure;

class EnsureUserHasRole
{
    public function handle($request, Closure $next, ...$roles)
    {
        $user = $request->user();
        if (!$user || !in_array($user->role, $roles)) {
            return response()->json(['message' => 'Forbidden'], 403);
        }
        return $next($request);
    }
}
EOF

# Routes (api.php)
cat > backend/routes/api.php << 'EOF'
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\AuthController;
use App\Http\Controllers\Api\VendorController;
use App\Http\Controllers\Api\ProductController;
use App\Http\Controllers\Api\AdminController;

// Public Auth
Route::post('auth/register', [AuthController::class, 'register']);
Route::post('auth/verify-otp', [AuthController::class, 'verifyOtp']);
Route::post('auth/login', [AuthController::class, 'login']);

// Protected
Route::middleware('auth:sanctum')->group(function () {
    Route::get('auth/user', [AuthController::class, 'user']);

    // Vendor application
    Route::post('vendor/apply', [VendorController::class, 'apply']);
    Route::get('vendor/status', [VendorController::class, 'status']);

    // Product CRUD (only approved vendor)
    Route::apiResource('products', ProductController::class)->only(['index', 'store', 'show']);

    // Admin routes
    Route::middleware('role:admin,customer_care')->prefix('admin')->group(function () {
        Route::get('vendors/pending', [AdminController::class, 'pendingVendors']);
        Route::post('vendors/{id}/approve', [AdminController::class, 'approveVendor']);
        Route::post('vendors/{id}/reject', [AdminController::class, 'rejectVendor']);
        Route::get('products/pending', [AdminController::class, 'pendingProducts']);
        Route::post('products/{id}/approve', [AdminController::class, 'approveProduct']);
        Route::post('products/{id}/reject', [AdminController::class, 'rejectProduct']);
    });
});
EOF

# bootstrap/app.php modification (register middleware alias)
cat > backend/bootstrap/app.php << 'EOF'
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'role' => \App\Http\Middleware\EnsureUserHasRole::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();
EOF

# 4. ডকার কন্টেইনার চালু
echo "--> ডকার কন্টেইনার বিল্ড ও স্টার্ট..."
docker compose up -d --build

# 5. অপেক্ষা করুন যতক্ষণ না MySQL রেডি হয়
echo "--> ডাটাবেস রেডি হওয়ার জন্য অপেক্ষা..."
until docker compose exec -T mysql mysqladmin ping -h mysql -u root --password="${DB_PASSWORD:-root}" --silent; do
  sleep 2
done

# 6. Laravel কমান্ড
echo "--> Laravel কমান্ড চালানো হচ্ছে..."
docker compose exec -T app php artisan key:generate
docker compose exec -T app php artisan install:api --no-interaction
docker compose exec -T app php artisan migrate --force
docker compose exec -T app php artisan db:seed --class=DefaultCategoriesSeeder || echo "No seeder, skipping"

# 7. ক্যাটাগরি সিডার তৈরি (যাতে প্রোডাক্ট অ্যাড করা যায়)
mkdir -p backend/database/seeders
cat > backend/database/seeders/DefaultCategoriesSeeder.php << 'EOF'
<?php
namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Category;

class DefaultCategoriesSeeder extends Seeder
{
    public function run()
    {
        $categories = ['Electronics', 'Fashion', 'Home & Living', 'Books', 'Toys'];
        foreach ($categories as $cat) {
            Category::create(['name' => $cat, 'slug' => \Str::slug($cat)]);
        }
    }
}
EOF
docker compose exec -T app php artisan db:seed --class=DefaultCategoriesSeeder

# 8. প্রথম অ্যাডমিন ইউজার তৈরি (যদি না থাকে)
docker compose exec -T app php artisan tinker --execute="
    if (!\App\Models\User::where('phone','01700000000')->exists()) {
        \$u = \App\Models\User::create([
            'name' => 'Super Admin',
            'phone' => '01700000000',
            'password' => bcrypt('password'),
            'phone_verified_at' => now(),
            'role' => 'admin',
        ]);
        echo 'Admin created: 01700000000 / password';
    } else {
        echo 'Admin already exists';
    }
"

echo ""
echo "======= সেটআপ সম্পূর্ণ ======="
echo "আপনার API: http://localhost:8080/api"
echo "অ্যাডমিন লগইন: phone=01700000000, password=password"
echo "টেস্ট করতে curl ব্যবহার করুন উপরের উদাহরণ অনুযায়ী।"
