#!/usr/bin/env python3
import os
import sys
import argparse
import shutil
from pathlib import Path


SCRIPT_DIR = Path(__file__).parent


def pkg_json(name):
    return (
        '''{
  "name": "'''
        + name
        + """",
  "type": "module",
  "version": "1.0.0",
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro"
  },
  "dependencies": {
    "astro": "^5.17.1",
    "@astrojs/react": "^4.2.0",
    "@astrojs/node": "^9.1.0",
    "@astrojs/sitemap": "^3.2.0",
    "@supabase/supabase-js": "^2.47.0",
    "@supabase/ssr": "^0.6.1",
    "@tailwindcss/vite": "^4.2.1",
    "tailwindcss": "^4.2.1",
    "zustand": "^5.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "jose": "^6.0.0"
  },
  "devDependencies": {
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0",
    "typescript": "^5.7.0"
  }
}"""
    )


ASTRO_CONFIG = """import {{ defineConfig }} from 'astro/config';
import react from '@astrojs/react';
import node from '@astrojs/node';
import sitemap from '@astrojs/sitemap';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({{
  site: '{site_url}',
  output: 'hybrid',
  adapter: node({{ mode: 'standalone' }}),
  i18n: {{
    locales: [{locales}],
    defaultLocale: '{default_locale}',
    routing: {{
      prefixDefaultLocale: false,
      fallbackType: 'rewrite',
    }},
  }},
  integrations: [
    react(),
    sitemap({{
      i18n: {{ defaultLocale: '{default_locale}' }},
    }}),
  ],
  vite: {{
    plugins: [tailwindcss()],
  }},
}});
"""

TSCONFIG = """{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}"""

SUPABASE_TS = """import {{ createClient }} from '@supabase/supabase-js';
import type {{ Database }} from './types';

const supabaseUrl = import.meta.env.SUPABASE_URL;
const supabaseAnonKey = import.meta.env.SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

export type {{ Database }};
"""

AUTH_TS = r"""import { supabase } from './supabase';
import { SignJWT, jwtVerify } from 'jose';
import type { User, VendorProfile } from './types';

const JWT_SECRET = new TextEncoder().encode(
  import.meta.env.JWT_SECRET || 'default-secret-change-me'
);

export interface AuthUser {
  id: string;
  email: string;
  name: string | null;
  role: 'customer' | 'vendor' | 'admin';
  vendor_id?: string;
}

export async function createSessionToken(user: AuthUser): Promise<string> {
  return new SignJWT({
    sub: user.id,
    email: user.email,
    name: user.name,
    role: user.role,
    vendor_id: user.vendor_id,
  })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('7d')
    .sign(JWT_SECRET);
}

export async function verifySessionToken(token: string): Promise<AuthUser | null> {
  try {
    const { payload } = await jwtVerify(token, JWT_SECRET);
    return {
      id: payload.sub as string,
      email: payload.email as string,
      name: payload.name as string | null,
      role: payload.role as 'customer' | 'vendor' | 'admin',
      vendor_id: payload.vendor_id as string | undefined,
    };
  } catch {
    return null;
  }
}

export async function registerUser(
  email: string,
  password: string,
  name: string
): Promise<{ user: User | null; error: string | null }> {
  const { data, error } = await supabase.auth.signUp({
    email,
    password,
    options: {
      data: { name },
    },
  });

  if (error) return { user: null, error: error.message };

  const user = data.user;
  if (!user) return { user: null, error: 'Registration failed' };

  return {
    user: {
      id: user.id,
      email: user.email || email,
      name,
      role: 'customer',
    },
    error: null,
  };
}

export async function loginUser(
  email: string,
  password: string
): Promise<{ user: AuthUser | null; token: string | null; error: string | null }> {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  });

  if (error) return { user: null, token: null, error: error.message };

  const user = data.user;
  if (!user) return { user: null, token: null, error: 'Login failed' };

  const { data: profileData } = await supabase
    .from('vendor_profiles')
    .select('id')
    .eq('user_id', user.id)
    .single();

  const authUser: AuthUser = {
    id: user.id,
    email: user.email || email,
    name: user.user_metadata?.name || null,
    role: profileData ? 'vendor' : 'customer',
    vendor_id: profileData?.id,
  };

  const token = await createSessionToken(authUser);

  return { user: authUser, token, error: null };
}

export async function logoutUser(): Promise<void> {
  await supabase.auth.signOut();
}
"""

PAYSOS_TS = r"""export interface PaySoPayment {
  merchant_id: string;
  order_id: string;
  amount: number;
  currency: string;
  description: string;
  callback_url: string;
  return_url: string;
  customer_name?: string;
  customer_email?: string;
  customer_phone?: string;
}

export interface PaySoResponse {
  code: string;
  message: string;
  data: {
    payment_url: string;
    qr_code?: string;
    qr_image?: string;
    transaction_id: string;
  };
}

export interface PaySoWebhookPayload {
  transaction_id: string;
  order_id: string;
  amount: number;
  status: 'pending' | 'success' | 'failed';
  timestamp: string;
  signature: string;
}

export async function createPaySoPayment(payment: PaySoPayment): Promise<PaySoResponse> {
  const response = await fetch('https://api.paysogateway.com/v1/payment', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${import.meta.env.PAYSOLO_API_KEY}`,
    },
    body: JSON.stringify({
      merchant_id: import.meta.env.PAYSOLO_MERCHANT_ID,
      order_id: payment.order_id,
      amount: payment.amount,
      currency: payment.currency || 'THB',
      description: payment.description,
      callback_url: payment.callback_url,
      return_url: payment.return_url,
      customer: {
        name: payment.customer_name,
        email: payment.customer_email,
        phone: payment.customer_phone,
      },
    }),
  });

  if (!response.ok) {
    throw new Error(`PaySo API error: ${response.status}`);
  }

  return response.json();
}

export async function verifyPaySoSignature(
  payload: PaySoWebhookPayload,
  signature: string
): Promise<boolean> {
  const crypto = await import('crypto');
  const secret = import.meta.env.PAYSOLO_SECRET_KEY;
  const data = JSON.stringify({
    transaction_id: payload.transaction_id,
    order_id: payload.order_id,
    amount: payload.amount,
    status: payload.status,
  });
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(data)
    .digest('hex');
  return signature === expectedSignature;
}
"""

TYPES_TS = r"""export interface User {
  id: string;
  email: string;
  name: string | null;
  phone: string | null;
  role: 'customer' | 'vendor' | 'admin';
  avatar_url: string | null;
  created_at: string;
  updated_at: string;
}

export interface VendorProfile {
  id: string;
  user_id: string;
  store_name: string;
  store_slug: string;
  store_description: string | null;
  store_logo: string | null;
  bank_account: string | null;
  bank_name: string | null;
  payout_status: 'pending' | 'approved' | 'rejected';
  total_earnings: number;
  approved_at: string | null;
  created_at: string;
}

export interface Category {
  id: string;
  name: string;
  slug: string;
  description: string | null;
  image_url: string | null;
  parent_id: string | null;
  sort_order: number;
}

export interface Product {
  id: string;
  vendor_id: string;
  category_id: string | null;
  name: string;
  slug: string;
  description: string | null;
  price: number;
  compare_at_price: number | null;
  cost_price: number | null;
  sku: string | null;
  barcode: string | null;
  inventory: number;
  low_stock_threshold: number;
  track_inventory: boolean;
  allow_backorder: boolean;
  weight: number | null;
  images: string[];
  metadata: Record<string, unknown>;
  status: 'draft' | 'active' | 'archived';
  featured: boolean;
  created_at: string;
  updated_at: string;
}

export interface ProductVariant {
  id: string;
  product_id: string;
  name: string;
  sku: string | null;
  price: number | null;
  inventory: number;
  attributes: Record<string, string>;
  image_url: string | null;
}

export interface Review {
  id: string;
  product_id: string;
  user_id: string;
  order_id: string | null;
  rating: number;
  title: string | null;
  comment: string | null;
  images: string[];
  verified_purchase: boolean;
  status: 'pending' | 'approved' | 'rejected';
  created_at: string;
}

export interface Order {
  id: string;
  order_number: string;
  user_id: string;
  vendor_id: string | null;
  status: 'pending' | 'confirmed' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
  payment_status: 'unpaid' | 'paid' | 'failed' | 'refunded';
  subtotal: number;
  tax: number;
  shipping_cost: number;
  total: number;
  currency: string;
  payment_method: string | null;
  payment_provider: string | null;
  payment_ref: string | null;
  shipping_name: string | null;
  shipping_phone: string | null;
  shipping_address: string | null;
  shipping_city: string | null;
  shipping_postal: string | null;
  shipping_country: string;
  notes: string | null;
  created_at: string;
  updated_at: string;
}

export interface OrderItem {
  id: string;
  order_id: string;
  product_id: string;
  variant_id: string | null;
  vendor_id: string | null;
  quantity: number;
  unit_price: number;
  total_price: number;
}

export interface CartItem {
  id: string;
  product: Product;
  variant: ProductVariant | null;
  quantity: number;
}
"""

UTILS_TS = r"""export function formatPrice(amount: number, currency = 'THB'): string {
  return new Intl.NumberFormat('th-TH', {
    style: 'currency',
    currency,
  }).format(amount);
}

export function generateSlug(text: string): string {
  return text
    .toLowerCase()
    .replace(/[^\w\s-]/g, '')
    .replace(/[\s_-]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

export function generateOrderNumber(): string {
  const date = new Date();
  const dateStr = date.toISOString().slice(0, 10).replace(/-/g, '');
  const random = Math.random().toString(36).substring(2, 10).toUpperCase();
  return `ORD-${dateStr}-${random}`;
}

export function cn(...classes: (string | undefined | null | false)[]): string {
  return classes.filter(Boolean).join(' ');
}

export function debounce<T extends (...args: any[]) => any>(
  fn: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timeoutId: ReturnType<typeof setTimeout>;
  return (...args: Parameters<T>) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  };
}
"""

CART_STORE = r"""import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { CartItem, Product, ProductVariant } from '../lib/types';

interface CartStore {
  items: CartItem[];
  addItem: (product: Product, variant?: ProductVariant, quantity?: number) => void;
  removeItem: (productId: string, variantId?: string) => void;
  updateQuantity: (productId: string, variantId: string | undefined, quantity: number) => void;
  clearCart: () => void;
  getTotal: () => number;
  getItemCount: () => number;
}

export const useCartStore = create<CartStore>()(
  persist(
    (set, get) => ({
      items: [],
      addItem: (product, variant, quantity = 1) => {
        set((state) => {
          const existingIndex = state.items.findIndex(
            (item) =>
              item.product.id === product.id &&
              item.variant?.id === variant?.id
          );

          if (existingIndex >= 0) {
            const newItems = [...state.items];
            newItems[existingIndex].quantity += quantity;
            return { items: newItems };
          }

          return {
            items: [
              ...state.items,
              { id: crypto.randomUUID(), product, variant: variant || null, quantity },
            ],
          };
        });
      },
      removeItem: (productId, variantId) => {
        set((state) => ({
          items: state.items.filter(
            (item) =>
              !(item.product.id === productId && item.variant?.id === variantId)
          ),
        }));
      },
      updateQuantity: (productId, variantId, quantity) => {
        if (quantity <= 0) {
          get().removeItem(productId, variantId);
          return;
        }
        set((state) => ({
          items: state.items.map((item) =>
            item.product.id === productId && item.variant?.id === variantId
              ? { ...item, quantity }
              : item
          ),
        }));
      },
      clearCart: () => set({ items: [] }),
      getTotal: () => {
        return get().items.reduce(
          (total, item) => total + (item.variant?.price || item.product.price) * item.quantity,
          0
        );
      },
      getItemCount: () => {
        return get().items.reduce((count, item) => count + item.quantity, 0);
      },
    }),
    {
      name: 'ecommerce-cart',
    }
  )
);
"""

AUTH_STORE = r"""import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { AuthUser } from '../lib/auth';

interface AuthStore {
  user: AuthUser | null;
  token: string | null;
  isLoading: boolean;
  setAuth: (user: AuthUser, token: string) => void;
  logout: () => void;
  setLoading: (loading: boolean) => void;
}

export const useAuthStore = create<AuthStore>()(
  persist(
    (set) => ({
      user: null,
      token: null,
      isLoading: false,
      setAuth: (user, token) => set({ user, token }),
      logout: () => set({ user: null, token: null }),
      setLoading: (isLoading) => set({ isLoading }),
    }),
    {
      name: 'ecommerce-auth',
    }
  )
);
"""

VENDOR_STORE = r"""import { create } from 'zustand';
import { supabase } from '../lib/supabase';
import type { Product, Order, VendorProfile } from '../lib/types';

interface VendorStore {
  profile: VendorProfile | null;
  products: Product[];
  orders: Order[];
  isLoading: boolean;
  fetchProfile: (userId: string) => Promise<void>;
  fetchProducts: (vendorId: string) => Promise<void>;
  fetchOrders: (vendorId: string) => Promise<void>;
  createProduct: (product: Partial<Product>) => Promise<Product | null>;
  updateProduct: (id: string, updates: Partial<Product>) => Promise<void>;
  updateOrderStatus: (orderId: string, status: string) => Promise<void>;
}

export const useVendorStore = create<VendorStore>((set, get) => ({
  profile: null,
  products: [],
  orders: [],
  isLoading: false,
  fetchProfile: async (userId) => {
    set({ isLoading: true });
    const { data } = await supabase
      .from('vendor_profiles')
      .select('*')
      .eq('user_id', userId)
      .single();
    set({ profile: data, isLoading: false });
  },
  fetchProducts: async (vendorId) => {
    set({ isLoading: true });
    const { data } = await supabase
      .from('products')
      .select('*')
      .eq('vendor_id', vendorId)
      .order('created_at', { ascending: false });
    set({ products: data || [], isLoading: false });
  },
  fetchOrders: async (vendorId) => {
    set({ isLoading: true });
    const { data } = await supabase
      .from('orders')
      .select('*')
      .eq('vendor_id', vendorId)
      .order('created_at', { ascending: false });
    set({ orders: data || [], isLoading: false });
  },
  createProduct: async (product) => {
    const { data, error } = await supabase
      .from('products')
      .insert(product)
      .select()
      .single();
    if (error) return null;
    set((state) => ({ products: [data, ...state.products] }));
    return data;
  },
  updateProduct: async (id, updates) => {
    await supabase.from('products').update(updates).eq('id', id);
    set((state) => ({
      products: state.products.map((p) =>
        p.id === id ? { ...p, ...updates } : p
      ),
    }));
  },
  updateOrderStatus: async (orderId, status) => {
    await supabase.from('orders').update({ status }).eq('id', orderId);
    set((state) => ({
      orders: state.orders.map((o) =>
        o.id === orderId ? { ...o, status: status as Order['status'] } : o
      ),
    }));
  },
}));
"""

BASE_LAYOUT = """---
interface Props {{
  title: string;
  description?: string;
}}

const {{ title, description = '{site_name}' }} = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content={{description}} />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <title>{{title}} | {site_name}</title>
  </head>
  <body class="bg-gray-50 text-gray-900">
    <slot />
  </body>
</html>

<style is:global>
  @import "tailwindcss";
</style>
"""

TH_JSON = """{{
  "common": {{
    "home": "หน้าแรก",
    "products": "สินค้า",
    "cart": "ตะกร้า",
    "checkout": "ชำระเงิน",
    "login": "เข้าสู่ระบบ",
    "register": "ลงทะเบียน",
    "logout": "ออกจากระบบ"
  }},
  "product": {{
    "addToCart": "เพิ่มลงตะกร้า",
    "outOfStock": "สินค้าหมด",
    "inStock": "มีสินค้า"
  }},
  "cart": {{
    "empty": "ตะกร้าว่าง",
    "total": "รวม"
  }}
}}"""

EN_JSON = """{{
  "common": {{
    "home": "Home",
    "products": "Products",
    "cart": "Cart",
    "checkout": "Checkout",
    "login": "Login",
    "register": "Register",
    "logout": "Logout"
  }},
  "product": {{
    "addToCart": "Add to Cart",
    "outOfStock": "Out of Stock",
    "inStock": "In Stock"
  }},
  "cart": {{
    "empty": "Your cart is empty",
    "total": "Total"
  }}
}}"""

GLOBAL_CSS = """@import "tailwindcss";

@theme {
  --font-sans: "Inter", system-ui, sans-serif;
  --color-primary: #2563eb;
  --color-secondary: #64748b;
}"""

CART_BUTTON = r"""import { useCartStore } from '../../stores/cart';

export function CartButton() {
  const getItemCount = useCartStore((state) => state.getItemCount);
  const count = getItemCount();

  return (
    <a
      href="/cart"
      className="relative p-2 text-gray-600 hover:text-primary transition-colors"
    >
      <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
          d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
      </svg>
      {count > 0 && (
        <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center">
          {count > 9 ? '9+' : count}
        </span>
      )}
    </a>
  );
}"""

CART_DRAWER = r"""import { useState } from 'react';
import { useCartStore } from '../../stores/cart';
import { formatPrice } from '../../lib/utils';
import { CartItem } from './CartItem';

export function CartDrawer() {
  const [isOpen, setIsOpen] = useState(false);
  const items = useCartStore((state) => state.items);
  const getTotal = useCartStore((state) => state.getTotal);

  return (
    <>
      <button
        onClick={() => setIsOpen(true)}
        className="p-2 text-gray-600 hover:text-primary transition-colors"
      >
        <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
            d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
        </svg>
      </button>

      {isOpen && (
        <div className="fixed inset-0 z-50 overflow-hidden">
          <div className="absolute inset-0 bg-black/50" onClick={() => setIsOpen(false)} />
          <div className="absolute right-0 top-0 h-full w-full max-w-md bg-white shadow-xl">
            <div className="flex h-full flex-col">
              <div className="flex items-center justify-between p-4 border-b">
                <h2 className="text-lg font-semibold">ตะกร้าสินค้า</h2>
                <button onClick={() => setIsOpen(false)} className="p-2">
                  <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </div>

              <div className="flex-1 overflow-y-auto p-4">
                {items.length === 0 ? (
                  <p className="text-center text-gray-500 py-8">ตะกร้าว่างเปล่า</p>
                ) : (
                  <div className="space-y-4">
                    {items.map((item) => (
                      <CartItem key={item.id} item={item} />
                    ))}
                  </div>
                )}
              </div>

              {items.length > 0 && (
                <div className="border-t p-4 space-y-4">
                  <div className="flex justify-between text-lg font-semibold">
                    <span>รวม</span>
                    <span>{formatPrice(getTotal())}</span>
                  </div>
                  <a
                    href="/checkout"
                    className="block w-full bg-primary text-white text-center py-3 rounded-lg font-medium hover:bg-primary/90 transition-colors"
                  >
                    ชำระเงิน
                  </a>
                </div>
              )}
            </div>
          </div>
        </div>
      )}
    </>
  );
}"""

CART_ITEM_COMPONENT = r"""import { useCartStore } from '../../stores/cart';
import { formatPrice } from '../../lib/utils';
import type { CartItem as CartItemType } from '../../lib/types';

interface Props {
  item: CartItemType;
}

export function CartItem({ item }: Props) {
  const updateQuantity = useCartStore((state) => state.updateQuantity);
  const removeItem = useCartStore((state) => state.removeItem);
  const price = item.variant?.price || item.product.price;

  return (
    <div className="flex gap-4 p-4 bg-gray-50 rounded-lg">
      <img
        src={item.product.images[0] || '/placeholder.jpg'}
        alt={item.product.name}
        className="w-20 h-20 object-cover rounded"
      />
      <div className="flex-1">
        <h3 className="font-medium">{item.product.name}</h3>
        {item.variant && (
          <p className="text-sm text-gray-500">{item.variant.name}</p>
        )}
        <p className="font-semibold text-primary mt-1">
          {formatPrice(price)}
        </p>
      </div>
      <div className="flex flex-col items-end justify-between">
        <button
          onClick={() => removeItem(item.product.id, item.variant?.id)}
          className="text-gray-400 hover:text-red-500"
        >
          <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
              d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
          </svg>
        </button>
        <div className="flex items-center gap-2">
          <button
            onClick={() => updateQuantity(item.product.id, item.variant?.id, item.quantity - 1)}
            className="w-8 h-8 rounded bg-gray-200 hover:bg-gray-300"
          >
            -
          </button>
          <span className="w-8 text-center">{item.quantity}</span>
          <button
            onClick={() => updateQuantity(item.product.id, item.variant?.id, item.quantity + 1)}
            className="w-8 h-8 rounded bg-gray-200 hover:bg-gray-300"
          >
            +
          </button>
        </div>
      </div>
    </div>
  );
}"""

PRODUCT_CARD = r"""import { Link } from '@astrojs/react/components';
import { formatPrice } from '../../lib/utils';
import type { Product } from '../../lib/types';

interface Props {
  product: Product;
}

export function ProductCard({ product }: Props) {
  const isOutOfStock = product.inventory <= 0 && !product.allow_backorder;
  const isLowStock = product.inventory > 0 && product.inventory <= product.low_stock_threshold;

  return (
    <Link href={`/products/${product.slug}`} className="group block">
      <div className="bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-shadow">
        <div className="aspect-square bg-gray-100 relative">
          <img
            src={product.images[0] || '/placeholder.jpg'}
            alt={product.name}
            className="w-full h-full object-cover"
          />
          {isOutOfStock && (
            <div className="absolute inset-0 bg-black/50 flex items-center justify-center">
              <span className="bg-white px-3 py-1 rounded-full text-sm font-medium">
                สินค้าหมด
              </span>
            </div>
          )}
          {product.featured && !isOutOfStock && (
            <span className="absolute top-2 left-2 bg-primary text-white px-2 py-1 rounded text-xs font-medium">
              แนะนำ
            </span>
          )}
        </div>
        <div className="p-4">
          <h3 className="font-medium text-gray-900 group-hover:text-primary transition-colors line-clamp-2">
            {product.name}
          </h3>
          <div className="mt-2 flex items-center gap-2">
            <span className="text-lg font-bold text-primary">
              {formatPrice(product.price)}
            </span>
            {product.compare_at_price && (
              <span className="text-sm text-gray-400 line-through">
                {formatPrice(product.compare_at_price)}
              </span>
            )}
          </div>
          {isLowStock && (
            <p className="text-xs text-orange-500 mt-1">สินค้าใกล้หมด ({product.inventory} ชิ้น)</p>
          )}
        </div>
      </div>
    </Link>
  );
}"""

CHECKOUT_FORM = r"""import { useState } from 'react';
import { useCartStore } from '../../stores/cart';
import { useAuthStore } from '../../stores/auth';
import { formatPrice, generateOrderNumber } from '../../lib/utils';

export function CheckoutForm() {
  const items = useCartStore((state) => state.items);
  const getTotal = useCartStore((state) => state.getTotal);
  const clearCart = useCartStore((state) => state.clearCart);
  const user = useAuthStore((state) => state.user);

  const [formData, setFormData] = useState({
    name: user?.name || '',
    phone: '',
    address: '',
    city: '',
    postal: '',
    paymentMethod: 'qr',
  });
  const [isSubmitting, setIsSubmitting] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);

    try {
      const response = await fetch('/api/checkout/create-order', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          ...formData,
          items: items.map((item) => ({
            product_id: item.product.id,
            variant_id: item.variant?.id,
            quantity: item.quantity,
            unit_price: item.variant?.price || item.product.price,
          })),
          order_number: generateOrderNumber(),
        }),
      });

      const data = await response.json();

      if (data.payment_url) {
        window.location.href = data.payment_url;
      } else {
        clearCart();
        window.location.href = `/orders/${data.order_id}`;
      }
    } catch (error) {
      console.error('Checkout error:', error);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      <div className="bg-white rounded-lg shadow-sm p-6">
        <h2 className="text-lg font-semibold mb-4">ข้อมูลจัดส่ง</h2>
        <div className="grid gap-4">
          <div>
            <label className="block text-sm font-medium mb-1">ชื่อ-นามสกุล</label>
            <input
              type="text"
              required
              value={formData.name}
              onChange={(e) => setFormData({ ...formData, name: e.target.value })}
              className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
            />
          </div>
          <div>
            <label className="block text-sm font-medium mb-1">เบอร์โทรศัพท์</label>
            <input
              type="tel"
              required
              value={formData.phone}
              onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
              className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
            />
          </div>
          <div>
            <label className="block text-sm font-medium mb-1">ที่อยู่</label>
            <textarea
              required
              rows={3}
              value={formData.address}
              onChange={(e) => setFormData({ ...formData, address: e.target.value })}
              className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
            />
          </div>
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium mb-1">จังหวัด</label>
              <input
                type="text"
                required
                value={formData.city}
                onChange={(e) => setFormData({ ...formData, city: e.target.value })}
                className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
              />
            </div>
            <div>
              <label className="block text-sm font-medium mb-1">รหัสไปรษณีย์</label>
              <input
                type="text"
                required
                value={formData.postal}
                onChange={(e) => setFormData({ ...formData, postal: e.target.value })}
                className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
              />
            </div>
          </div>
        </div>
      </div>

      <div className="bg-white rounded-lg shadow-sm p-6">
        <h2 className="text-lg font-semibold mb-4">วิธีการชำระเงิน</h2>
        <div className="space-y-3">
          <label className="flex items-center gap-3 p-4 border rounded-lg cursor-pointer hover:border-primary">
            <input
              type="radio"
              name="payment"
              value="qr"
              checked={formData.paymentMethod === 'qr'}
              onChange={(e) => setFormData({ ...formData, paymentMethod: e.target.value })}
              className="text-primary"
            />
            <span className="font-medium">QR Code</span>
            <span className="text-sm text-gray-500">ชำระผ่าน QR ที่ธนาคาร</span>
          </label>
        </div>
      </div>

      <div className="bg-white rounded-lg shadow-sm p-6">
        <h2 className="text-lg font-semibold mb-4">สรุปคำสั่งซื้อ</h2>
        <div className="space-y-2 text-sm">
          <div className="flex justify-between">
            <span>ราคารวม ({items.length} รายการ)</span>
            <span>{formatPrice(getTotal())}</span>
          </div>
          <div className="flex justify-between">
            <span>ค่าจัดส่ง</span>
            <span>฿0</span>
          </div>
          <div className="border-t pt-2 mt-2 flex justify-between font-semibold text-lg">
            <span>รวมทั้งสิ้น</span>
            <span className="text-primary">{formatPrice(getTotal())}</span>
          </div>
        </div>
      </div>

      <button
        type="submit"
        disabled={isSubmitting || items.length === 0}
        className="w-full bg-primary text-white py-4 rounded-lg font-semibold hover:bg-primary/90 transition-colors disabled:opacity-50"
      >
        {isSubmitting ? 'กำลังประมวลผล...' : 'ยืนยันคำสั่งซื้อ'}
      </button>
    </form>
  );
}"""

VENDOR_DASHBOARD = r"""import { useVendorStore } from '../../stores/vendor';
import { formatPrice } from '../../lib/utils';
import { Link } from '@astrojs/react/components';

export function VendorDashboard() {
  const { profile, products, orders, isLoading } = useVendorStore();

  if (isLoading) {
    return <div className="text-center py-8">กำลังโหลด...</div>;
  }

  const pendingOrders = orders.filter((o) => o.status === 'pending' || o.status === 'confirmed');
  const totalRevenue = orders
    .filter((o) => o.payment_status === 'paid')
    .reduce((sum, o) => sum + o.total, 0);

  return (
    <div className="space-y-6">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div className="bg-white p-6 rounded-lg shadow-sm">
          <h3 className="text-gray-500 text-sm">คำสั่งซื้อรอดำเนินการ</h3>
          <p className="text-2xl font-bold text-primary">{pendingOrders.length}</p>
        </div>
        <div className="bg-white p-6 rounded-lg shadow-sm">
          <h3 className="text-gray-500 text-sm">สินค้าทั้งหมด</h3>
          <p className="text-2xl font-bold text-primary">{products.length}</p>
        </div>
        <div className="bg-white p-6 rounded-lg shadow-sm">
          <h3 className="text-gray-500 text-sm">รายได้ทั้งหมด</h3>
          <p className="text-2xl font-bold text-primary">{formatPrice(totalRevenue)}</p>
        </div>
      </div>

      <div className="bg-white rounded-lg shadow-sm p-6">
        <div className="flex justify-between items-center mb-4">
          <h2 className="text-lg font-semibold">คำสั่งซื้อล่าสุด</h2>
          <Link href="/vendor/orders" className="text-primary text-sm hover:underline">
            ดูทั้งหมด
          </Link>
        </div>
        {orders.length === 0 ? (
          <p className="text-gray-500 text-center py-4">ยังไม่มีคำสั่งซื้อ</p>
        ) : (
          <div className="space-y-3">
            {orders.slice(0, 5).map((order) => (
              <div key={order.id} className="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
                <div>
                  <p className="font-medium">{order.order_number}</p>
                  <p className="text-sm text-gray-500">{order.created_at}</p>
                </div>
                <div className="text-right">
                  <p className="font-semibold">{formatPrice(order.total)}</p>
                  <span className={`inline-block px-2 py-0.5 rounded text-xs ${
                    order.status === 'pending' ? 'bg-yellow-100 text-yellow-700' :
                    order.status === 'confirmed' ? 'bg-blue-100 text-blue-700' :
                    order.status === 'shipped' ? 'bg-purple-100 text-purple-700' :
                    'bg-green-100 text-green-700'
                  }`}>
                    {order.status}
                  </span>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}"""

PRODUCT_FORM = r"""import { useState } from 'react';
import { useVendorStore } from '../../stores/vendor';
import { generateSlug } from '../../lib/utils';

interface Props {
  product?: Partial<import('../../lib/types').Product>;
  onSuccess?: () => void;
}

export function ProductForm({ product, onSuccess }: Props) {
  const createProduct = useVendorStore((state) => state.createProduct);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [formData, setFormData] = useState({
    name: product?.name || '',
    slug: product?.slug || '',
    description: product?.description || '',
    price: product?.price || 0,
    compare_at_price: product?.compare_at_price || 0,
    sku: product?.sku || '',
    inventory: product?.inventory || 0,
    low_stock_threshold: product?.low_stock_threshold || 5,
    images: product?.images || [],
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);

    try {
      const slug = formData.slug || generateSlug(formData.name);
      await createProduct({
        ...formData,
        slug,
        status: 'draft',
      });
      onSuccess?.();
    } catch (error) {
      console.error('Error creating product:', error);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      <div>
        <label className="block text-sm font-medium mb-1">ชื่อสินค้า</label>
        <input
          type="text"
          required
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
          className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
        />
      </div>

      <div>
        <label className="block text-sm font-medium mb-1">รายละเอียด</label>
        <textarea
          rows={4}
          value={formData.description}
          onChange={(e) => setFormData({ ...formData, description: e.target.value })}
          className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
        />
      </div>

      <div className="grid grid-cols-2 gap-4">
        <div>
          <label className="block text-sm font-medium mb-1">ราคา (บาท)</label>
          <input
            type="number"
            required
            min="0"
            step="0.01"
            value={formData.price}
            onChange={(e) => setFormData({ ...formData, price: parseFloat(e.target.value) })}
            className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
          />
        </div>
        <div>
          <label className="block text-sm font-medium mb-1">SKU</label>
          <input
            type="text"
            value={formData.sku}
            onChange={(e) => setFormData({ ...formData, sku: e.target.value })}
            className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
          />
        </div>
      </div>

      <div className="grid grid-cols-2 gap-4">
        <div>
          <label className="block text-sm font-medium mb-1">จำนวนในสต็อก</label>
          <input
            type="number"
            min="0"
            value={formData.inventory}
            onChange={(e) => setFormData({ ...formData, inventory: parseInt(e.target.value) })}
            className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
          />
        </div>
        <div>
          <label className="block text-sm font-medium mb-1">แจ้งเตือนสต็อกต่ำ</label>
          <input
            type="number"
            min="0"
            value={formData.low_stock_threshold}
            onChange={(e) => setFormData({ ...formData, low_stock_threshold: parseInt(e.target.value) })}
            className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary"
          />
        </div>
      </div>

      <button
        type="submit"
        disabled={isSubmitting}
        className="w-full bg-primary text-white py-3 rounded-lg font-semibold hover:bg-primary/90 transition-colors disabled:opacity-50"
      >
        {isSubmitting ? 'กำลังบันทึก...' : 'บันทึกสินค้า'}
      </button>
    </form>
  );
}"""

INDEX_PAGE = """---
import BaseLayout from '../layouts/BaseLayout.astro';
import { ProductCard } from '../components/product/ProductCard';
import { supabase } from '../lib/supabase';

const {{ data: products }} = await supabase
  .from('products')
  .select('*')
  .eq('status', 'active')
  .order('created_at', {{ ascending: false }})
  .limit(12);
---

<BaseLayout title="หน้าแรก">
  <section class="bg-gradient-to-r from-primary to-primary/80 text-white py-20">
    <div class="container mx-auto px-4 text-center">
      <h1 class="text-4xl md:text-5xl font-bold mb-4">{site_name}</h1>
      <p class="text-xl text-white/80 mb-8">สินค้าคุณภาพ ราคาดีที่สุด</p>
      <a href="/products" class="inline-block bg-white text-primary px-8 py-3 rounded-lg font-semibold hover:bg-gray-100 transition-colors">
        ดูสินค้าทั้งหมด
      </a>
    </div>
  </section>

  <section class="py-12 container mx-auto px-4">
    <h2 class="text-2xl font-bold mb-8">สินค้าแนะนำ</h2>
    <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
      {products?.map((product) => (
        <ProductCard client:load product={product} />
      ))}
    </div>
  </section>
</BaseLayout>
"""

CHECKOUT_PAGE = """---
import BaseLayout from '../layouts/BaseLayout.astro';
import { CheckoutForm } from '../components/checkout/CheckoutForm';
---

<BaseLayout title="ชำระเงิน">
  <div class="container mx-auto px-4 py-8">
    <h1 class="text-2xl font-bold mb-8">ชำระเงิน</h1>
    <CheckoutForm client:load />
  </div>
</BaseLayout>
"""

API_AUTH_LOGIN = """import type {{ APIRoute }} from 'astro';
import {{ loginUser }} from '../../../lib/auth';

export const POST: APIRoute = async ({{ request }}) => {{
  try {{
    const {{ email, password }} = await request.json();

    if (!email || !password) {{
      return new Response(JSON.stringify({{ error: 'Email and password required' }}), {{
        status: 400,
        headers: {{ 'Content-Type': 'application/json' }},
      }});
    }}

    const {{ user, token, error }} = await loginUser(email, password);

    if (error) {{
      return new Response(JSON.stringify({{ error }}), {{
        status: 401,
        headers: {{ 'Content-Type': 'application/json' }},
      }});
    }}

    return new Response(JSON.stringify({{ user, token }}), {{
      status: 200,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }} catch (error) {{
    return new Response(JSON.stringify({{ error: 'Internal server error' }}), {{
      status: 500,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }}
}};
"""

API_CHECKOUT = """import type {{ APIRoute }} from 'astro';
import {{ supabase }} from '../../../lib/supabase';
import {{ createPaySoPayment }} from '../../../lib/payso';

export const POST: APIRoute = async ({{ request }}) => {{
  try {{
    const body = await request.json();
    const {{ items, order_number, name, phone, address, city, postal, paymentMethod }} = body;

    const subtotal = items.reduce(
      (sum: number, item: {{ unit_price: number; quantity: number }}) => sum + item.unit_price * item.quantity,
      0
    );

    const {{ data: userData }} = await supabase.auth.getUser();
    const userId = userData?.user?.id;

    const {{ data: order, error: orderError }} = await supabase
      .from('orders')
      .insert({{
        order_number,
        user_id: userId,
        subtotal,
        tax: 0,
        shipping_cost: 0,
        total: subtotal,
        shipping_name: name,
        shipping_phone: phone,
        shipping_address: address,
        shipping_city: city,
        shipping_postal: postal,
        status: 'pending',
        payment_status: 'unpaid',
        payment_method: paymentMethod,
      }})
      .select()
      .single();

    if (orderError) {{
      return new Response(JSON.stringify({{ error: orderError.message }}), {{
        status: 500,
        headers: {{ 'Content-Type': 'application/json' }},
      }});
    }}

    for (const item of items) {{
      await supabase.from('order_items').insert({{
        order_id: order.id,
        product_id: item.product_id,
        variant_id: item.variant_id || null,
        quantity: item.quantity,
        unit_price: item.unit_price,
        total_price: item.unit_price * item.quantity,
      }});
    }}

    if (paymentMethod === 'qr') {{
      const payment = await createPaySoPayment({{
        merchant_id: import.meta.env.PAYSOLO_MERCHANT_ID,
        order_id: order.id,
        amount: subtotal,
        currency: 'THB',
        description: `Order ${{order_number}}`,
        callback_url: `${{import.meta.env.SITE_URL}}/api/webhooks/payso`,
        return_url: `${{import.meta.env.SITE_URL}}/orders/${{order.id}}`,
        customer_name: name,
        customer_phone: phone,
      }});

      if (payment.data?.payment_url) {{
        return new Response(JSON.stringify({{
          order_id: order.id,
          payment_url: payment.data.payment_url,
        }}), {{
          status: 200,
          headers: {{ 'Content-Type': 'application/json' }},
        }});
      }}
    }}

    return new Response(JSON.stringify({{ order_id: order.id }}), {{
      status: 200,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }} catch (error) {{
    return new Response(JSON.stringify({{ error: 'Internal server error' }}), {{
      status: 500,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }}
}};
"""

API_PAYSO_WEBHOOK = """import type {{ APIRoute }} from 'astro';
import {{ supabase }} from '../../../../lib/supabase';
import {{ verifyPaySoSignature }} from '../../../../lib/payso';

export const POST: APIRoute = async ({{ request }}) => {{
  try {{
    const payload = await request.json();
    const signature = request.headers.get('x-payso-signature') || '';

    const isValid = await verifyPaySoSignature(payload, signature);
    if (!isValid) {{
      return new Response(JSON.stringify({{ error: 'Invalid signature' }}), {{
        status: 401,
        headers: {{ 'Content-Type': 'application/json' }},
      }});
    }}

    const {{ transaction_id, order_id, amount, status }} = payload;

    if (status === 'success') {{
      await supabase
        .from('orders')
        .update({{ payment_status: 'paid', payment_ref: transaction_id }})
        .eq('id', order_id);

      await supabase.from('payments').insert({{
        order_id,
        provider: 'payso',
        provider_ref: transaction_id,
        amount,
        status: 'completed',
        paid_at: new Date().toISOString(),
      }});
    }} else if (status === 'failed') {{
      await supabase
        .from('orders')
        .update({{ payment_status: 'failed' }})
        .eq('id', order_id);
    }}

    return new Response(JSON.stringify({{ success: true }}), {{
      status: 200,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }} catch (error) {{
    return new Response(JSON.stringify({{ error: 'Internal server error' }}), {{
      status: 500,
      headers: {{ 'Content-Type': 'application/json' }},
    }});
  }}
}};
"""

DOCKERFILE = """FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

RUN npm run build

EXPOSE 4321
CMD ["npm", "run", "preview"]
"""

DOCKER_COMPOSE = """services:
  web:
    build: .
    ports:
      - "4321:4321"
    environment:
      - SUPABASE_URL=${SUPABASE_URL}
      - SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
      - PAYSOLO_MERCHANT_ID=${PAYSOLO_MERCHANT_ID}
      - PAYSOLO_API_KEY=${PAYSOLO_API_KEY}
      - SITE_URL=${SITE_URL}
    env_file:
      - .env
"""

GITIGNORE = """node_modules/
dist/
.env
.env.*
!.env.example
.DS_Store
"""

HEADER_COMPONENT = """---
import {{ CartButton }} from '../components/cart/CartButton';
---

<header class="bg-white shadow-sm sticky top-0 z-40">
  <nav class="container mx-auto px-4">
    <div class="flex items-center justify-between h-16">
      <a href="/" class="text-xl font-bold text-primary">LOGO</a>

      <div class="hidden md:flex items-center gap-6">
        <a href="/" class="text-gray-600 hover:text-primary">หน้าแรก</a>
        <a href="/products" class="text-gray-600 hover:text-primary">สินค้า</a>
        <a href="/cart" class="text-gray-600 hover:text-primary">ตะกร้า</a>
      </div>

      <div class="flex items-center gap-4">
        <CartButton client:load />
        <a href="/auth/login" class="text-gray-600 hover:text-primary">เข้าสู่ระบบ</a>
      </div>
    </div>
  </nav>
</header>
"""

FOOTER_COMPONENT = """<footer class="bg-gray-900 text-white py-12 mt-auto">
  <div class="container mx-auto px-4">
    <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
      <div>
        <h3 class="font-bold text-lg mb-4">{site_name}</h3>
        <p class="text-gray-400">สินค้าคุณภาพ ราคาดีที่สุด</p>
      </div>
      <div>
        <h4 class="font-semibold mb-4">บริการ</h4>
        <ul class="space-y-2 text-gray-400">
          <li><a href="/products" class="hover:text-white">สินค้าทั้งหมด</a></li>
          <li><a href="/cart" class="hover:text-white">ตะกร้า</a></li>
          <li><a href="/checkout" class="hover:text-white">ชำระเงิน</a></li>
        </ul>
      </div>
      <div>
        <h4 class="font-semibold mb-4">บัญชี</h4>
        <ul class="space-y-2 text-gray-400">
          <li><a href="/auth/login" class="hover:text-white">เข้าสู่ระบบ</a></li>
          <li><a href="/auth/register" class="hover:text-white">ลงทะเบียน</a></li>
          <li><a href="/orders" class="hover:text-white">คำสั่งซื้อ</a></li>
        </ul>
      </div>
      <div>
        <h4 class="font-semibold mb-4">ติดต่อ</h4>
        <p class="text-gray-400">อีเมล: info@example.com</p>
        <p class="text-gray-400">โทร: 02-xxx-xxxx</p>
      </div>
    </div>
    <div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
      <p>&copy; 2024 {site_name}. All rights reserved.</p>
    </div>
  </div>
</footer>
"""

LOGIN_PAGE = """---
import BaseLayout from '../../layouts/BaseLayout.astro';
---

<BaseLayout title="เข้าสู่ระบบ">
  <div class="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4">
    <div class="max-w-md w-full bg-white rounded-lg shadow-md p-8">
      <h1 class="text-2xl font-bold text-center mb-8">เข้าสู่ระบบ</h1>
      <form id="login-form" class="space-y-6">
        <div>
          <label class="block text-sm font-medium mb-2">อีเมล</label>
          <input
            type="email"
            id="email"
            required
            class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
          />
        </div>
        <div>
          <label class="block text-sm font-medium mb-2">รหัสผ่าน</label>
          <input
            type="password"
            id="password"
            required
            class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary focus:border-primary"
          />
        </div>
        <button
          type="submit"
          id="submit-btn"
          class="w-full bg-primary text-white py-3 rounded-lg font-semibold hover:bg-primary/90 transition-colors"
        >
          เข้าสู่ระบบ
        </button>
      </form>
      <p class="mt-4 text-center text-sm text-gray-600">
        ยังไม่มีบัญชี? <a href="/auth/register" class="text-primary hover:underline">ลงทะเบียน</a>
      </p>
    </div>
  </div>
</BaseLayout>

<script>
  const form = document.getElementById('login-form') as HTMLFormElement;
  const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement;

  form.addEventListener('submit', async (e) => {{
    e.preventDefault();
    submitBtn.disabled = true;
    submitBtn.textContent = 'กำลังเข้าสู่ระบบ...';

    const email = (document.getElementById('email') as HTMLInputElement).value;
    const password = (document.getElementById('password') as HTMLInputElement).value;

    try {{
      const response = await fetch('/api/auth/login', {{
        method: 'POST',
        headers: {{ 'Content-Type': 'application/json' }},
        body: JSON.stringify({{ email, password }}),
      }});

      const data = await response.json();

      if (response.ok && data.token) {{
        localStorage.setItem('auth_token', data.token);
        localStorage.setItem('auth_user', JSON.stringify(data.user));
        window.location.href = '/';
      }} else {{
        alert(data.error || 'Login failed');
        submitBtn.disabled = false;
        submitBtn.textContent = 'เข้าสู่ระบบ';
      }}
    }} catch (error) {{
      alert('An error occurred');
      submitBtn.disabled = false;
      submitBtn.textContent = 'เข้าสู่ระบบ';
    }}
  }});
</script>
"""

CART_PAGE = """---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout title="ตะกร้าสินค้า">
  <div class="container mx-auto px-4 py-8">
    <h1 class="text-2xl font-bold mb-8">ตะกร้าสินค้า</h1>
    <div id="cart-container">
      <p class="text-center text-gray-500 py-8">กำลังโหลด...</p>
    </div>
  </div>
</BaseLayout>

<script>
  import {{ create }} from 'zustand';
  import {{ persist }} from 'zustand/middleware';
  import {{ formatPrice }} from '../lib/utils';

  interface CartItem {{
    id: string;
    product: any;
    variant: any;
    quantity: number;
  }}

  interface CartStore {{
    items: CartItem[];
    addItem: (product: any, variant: any, quantity?: number) => void;
    removeItem: (productId: string, variantId?: string) => void;
    updateQuantity: (productId: string, variantId: string | undefined, quantity: number) => void;
    getTotal: () => number;
  }}

  const useCartStore = create<CartStore>()(
    persist(
      (set, get) => ({{
        items: [],
        addItem: (product, variant, quantity = 1) => {{
          set((state) => {{
            const existingIndex = state.items.findIndex(
              (item) => item.product.id === product.id && item.variant?.id === variant?.id
            );
            if (existingIndex >= 0) {{
              const newItems = [...state.items];
              newItems[existingIndex].quantity += quantity;
              return {{ items: newItems }};
            }}
            return {{ items: [...state.items, {{ id: crypto.randomUUID(), product, variant: variant || null, quantity }}] }};
          }});
        }},
        removeItem: (productId, variantId) => {{
          set((state) => ({{
            items: state.items.filter((item) => !(item.product.id === productId && item.variant?.id === variantId)),
          }}));
        }},
        updateQuantity: (productId, variantId, quantity) => {{
          if (quantity <= 0) {{
            get().removeItem(productId, variantId);
            return;
          }}
          set((state) => ({{
            items: state.items.map((item) =>
              item.product.id === productId && item.variant?.id === variantId
                ? {{ ...item, quantity }}
                : item
            ),
          }}));
        }},
        getTotal: () => get().items.reduce((total: number, item: CartItem) => total + (item.variant?.price || item.product.price) * item.quantity, 0),
      }}),
      {{ name: 'ecommerce-cart' }}
    )
  );

  const cart = useCartStore.getState();
  const container = document.getElementById('cart-container');

  if (cart.items.length === 0) {{
    container.innerHTML = '<p class="text-center text-gray-500 py-8">ตะกร้าว่างเปล่า</p>';
  }} else {{
    container.innerHTML = `
      <div class="space-y-4">
        ${{cart.items.map((item: CartItem) => `
          <div class="flex gap-4 p-4 bg-white rounded-lg shadow-sm" data-item-id="${{item.id}}">
            <img src="${{item.product.images[0] || '/placeholder.jpg'}}" alt="${{item.product.name}}" class="w-24 h-24 object-cover rounded" />
            <div class="flex-1">
              <h3 class="font-medium">${{item.product.name}}</h3>
              ${{item.variant ? `<p class="text-sm text-gray-500">${{item.variant.name}}</p>` : ''}}
              <p class="font-semibold text-primary mt-1">${{formatPrice(item.variant?.price || item.product.price)}}</p>
            </div>
            <div class="flex flex-col items-end justify-between">
              <button onclick="removeItem('${{item.product.id}}', '${{item.variant?.id}}')" class="text-gray-400 hover:text-red-500">
                ลบ
              </button>
              <div class="flex items-center gap-2">
                <button onclick="updateQty('${{item.product.id}}', '${{item.variant?.id}}', -1)" class="w-8 h-8 rounded bg-gray-200">-</button>
                <span class="w-8 text-center">${{item.quantity}}</span>
                <button onclick="updateQty('${{item.product.id}}', '${{item.variant?.id}}', 1)" class="w-8 h-8 rounded bg-gray-200">+</button>
              </div>
            </div>
          </div>
        `).join('')}}
      </div>
      <div class="mt-8 flex justify-between items-center">
        <h3 class="text-xl font-semibold">รวม: ${{formatPrice(cart.getTotal())}}</h3>
        <a href="/checkout" class="bg-primary text-white px-8 py-3 rounded-lg font-semibold hover:bg-primary/90">
          ชำระเงิน
        </a>
      </div>
    `;
  }}

  (window as any).removeItem = (productId: string, variantId: string) => {{
    useCartStore.getState().removeItem(productId, variantId || undefined);
    location.reload();
  }};

  (window as any).updateQty = (productId: string, variantId: string, delta: number) => {{
    const item = cart.items.find((i: CartItem) => i.product.id === productId && i.variant?.id === variantId);
    if (item) {{
      useCartStore.getState().updateQuantity(productId, variantId || undefined, item.quantity + delta);
      location.reload();
    }}
  }};
</script>
"""


def create_project(args):
    output_path = Path(args.output)
    project_name = args.name.lower().replace(" ", "-")
    site_url = f"https://{project_name}.moreminimore.com"
    languages = [lang.strip() for lang in args.languages.split(",")]
    default_locale = "en" if "en" in languages else languages[0]

    print(f"Creating e-commerce project: {args.name}")
    print(f"Output: {args.output}")

    dirs = [
        output_path / "supabase" / "migrations",
        output_path / "src" / "components" / "cart",
        output_path / "src" / "components" / "checkout",
        output_path / "src" / "components" / "product",
        output_path / "src" / "components" / "vendor",
        output_path / "src" / "components" / "ui",
        output_path / "src" / "layouts",
        output_path / "src" / "lib",
        output_path / "src" / "stores",
        output_path / "src" / "pages" / "products",
        output_path / "src" / "pages" / "cart",
        output_path / "src" / "pages" / "checkout",
        output_path / "src" / "pages" / "orders",
        output_path / "src" / "pages" / "auth",
        output_path / "src" / "pages" / "vendor" / "products",
        output_path / "src" / "pages" / "vendor" / "orders",
        output_path / "src" / "pages" / "api" / "auth",
        output_path / "src" / "pages" / "api" / "checkout",
        output_path / "src" / "pages" / "api" / "webhooks",
        output_path / "src" / "i18n",
        output_path / "src" / "styles",
        output_path / "public" / "images",
    ]

    for d in dirs:
        d.mkdir(parents=True, exist_ok=True)

    print("  ✓ Directory structure created")

    for lang in languages:
        (output_path / "src" / "pages" / lang).mkdir(exist_ok=True)

    locales_str = ", ".join([f"'{lang}'" for lang in languages])

    config = ASTRO_CONFIG.format(
        site_url=site_url,
        locales=locales_str,
        default_locale=default_locale,
    )
    (output_path / "astro.config.mjs").write_text(config)

    package = pkg_json(project_name)
    (output_path / "package.json").write_text(package)

    (output_path / "tsconfig.json").write_text(TSCONFIG)

    migration_src = SCRIPT_DIR / "supabase_migration.sql"
    if migration_src.exists():
        shutil.copy(
            migration_src,
            output_path / "supabase" / "migrations" / "001_initial_schema.sql",
        )

    lib_files = {
        "supabase.ts": SUPABASE_TS,
        "auth.ts": AUTH_TS,
        "payso.ts": PAYSOS_TS,
        "types.ts": TYPES_TS,
        "utils.ts": UTILS_TS,
    }
    for filename, content in lib_files.items():
        (output_path / "src" / "lib" / filename).write_text(content)

    stores_files = {
        "cart.ts": CART_STORE,
        "auth.ts": AUTH_STORE,
        "vendor.ts": VENDOR_STORE,
    }
    for filename, content in stores_files.items():
        (output_path / "src" / "stores" / filename).write_text(content)

    components = {
        "cart/CartButton.tsx": CART_BUTTON,
        "cart/CartDrawer.tsx": CART_DRAWER,
        "cart/CartItem.tsx": CART_ITEM_COMPONENT,
        "product/ProductCard.tsx": PRODUCT_CARD,
        "checkout/CheckoutForm.tsx": CHECKOUT_FORM,
        "vendor/VendorDashboard.tsx": VENDOR_DASHBOARD,
        "vendor/ProductForm.tsx": PRODUCT_FORM,
    }
    for path, content in components.items():
        (output_path / "src" / "components" / path).write_text(content)

    (output_path / "src" / "styles" / "global.css").write_text(GLOBAL_CSS)

    base_layout = BASE_LAYOUT.format(site_name=args.name)
    (output_path / "src" / "layouts" / "BaseLayout.astro").write_text(base_layout)

    header = HEADER_COMPONENT.format(site_name=args.name)
    (output_path / "src" / "components" / "Header.astro").write_text(header)

    footer = FOOTER_COMPONENT.format(site_name=args.name)
    (output_path / "src" / "components" / "Footer.astro").write_text(footer)

    (output_path / "src" / "i18n" / "th.json").write_text(TH_JSON)
    if len(languages) > 1:
        (output_path / "src" / "i18n" / "en.json").write_text(EN_JSON)

    pages = {
        "index.astro": INDEX_PAGE,
        "cart.astro": CART_PAGE,
        "checkout.astro": CHECKOUT_PAGE,
        "auth/login.astro": LOGIN_PAGE,
        "api/auth/login.ts": API_AUTH_LOGIN,
        "api/checkout/create-order.ts": API_CHECKOUT,
        "api/webhooks/payso.ts": API_PAYSO_WEBHOOK,
    }
    for path, content in pages.items():
        (output_path / "src" / "pages" / path).write_text(content)

    (output_path / "Dockerfile").write_text(DOCKERFILE)
    (output_path / "docker-compose.yml").write_text(DOCKER_COMPOSE)
    (output_path / ".gitignore").write_text(GITIGNORE)

    env_content = f"""# Supabase
SUPABASE_URL={args.supabase_url or "https://xxx.supabase.co"}
SUPABASE_ANON_KEY={args.supabase_key or "your-anon-key"}
SUPABASE_SERVICE_ROLE_KEY={args.supabase_service_key or "your-service-key"}

# PaySo Payment
PAYSOLO_MERCHANT_ID={args.paysolo_merchant_id or "your-merchant-id"}
PAYSOLO_API_KEY={args.paysolo_api_key or "your-api-key"}
PAYSOLO_SECRET_KEY={args.paysolo_secret_key or "your-secret-key"}
PAYSOLO_CALLBACK_URL={args.callback_url or f"{site_url}/api/webhooks/payso"}

# JWT
JWT_SECRET={args.jwt_secret or "change-this-to-a-secure-secret-key"}

# Site
SITE_URL={site_url}
SITE_NAME={args.name}
"""
    (output_path / ".env.example").write_text(env_content)
    (output_path / ".env").write_text(env_content)

    (output_path / "public" / "favicon.svg").write_text(
        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">🛒</text></svg>'
    )

    print("  ✓ Configuration files created")
    print("  ✓ Supabase client and types created")
    print("  ✓ Auth and PaySo integration created")
    print("  ✓ Zustand stores created")
    print("  ✓ React components created")
    print("  ✓ Pages created")
    print("  ✓ i18n translations created")
    print("  ✓ Dockerfile created")

    return output_path


def main():
    parser = argparse.ArgumentParser(description="Create e-commerce Astro site")
    parser.add_argument("--name", required=True, help="Store name")
    parser.add_argument("--slug", default="", help="Store slug (URL friendly)")
    parser.add_argument(
        "--languages", default="th,en", help="Languages (comma-separated)"
    )
    parser.add_argument("--output", "-o", required=True, help="Output directory")
    parser.add_argument("--supabase-url", default="", help="Supabase project URL")
    parser.add_argument("--supabase-key", default="", help="Supabase anon key")
    parser.add_argument(
        "--supabase-service-key", default="", help="Supabase service role key"
    )
    parser.add_argument("--paysolo-merchant-id", default="", help="PaySo merchant ID")
    parser.add_argument("--paysolo-api-key", default="", help="PaySo API key")
    parser.add_argument("--paysolo-secret-key", default="", help="PaySo secret key")
    parser.add_argument("--callback-url", default="", help="PaySo callback URL")
    parser.add_argument("--jwt-secret", default="", help="JWT secret key")

    args = parser.parse_args()

    if not args.slug:
        args.slug = args.name.lower().replace(" ", "-")

    output_path = create_project(args)

    print(f"\n✅ E-commerce site created at: {output_path}")
    print("\nNext steps:")
    print(f"  1. cd {output_path}")
    print("  2. npm install")
    print("  3. Run the Supabase migration in your dashboard:")
    print(f"     supabase/migrations/001_initial_schema.sql")
    print("  4. Update .env with your credentials")
    print("  5. npm run dev")


if __name__ == "__main__":
    main()
