import Database from 'better-sqlite3';
import { mkdirSync } from 'node:fs';
import { dirname } from 'node:path';
import { SEED_PRODUCTS, SEED_CUSTOMERS, seedOrders } from './seed.js';

const DB_PATH = process.env.DB_PATH || './data/shop.db';
try { mkdirSync(dirname(DB_PATH), { recursive: true }); } catch {}
const db = new Database(DB_PATH);
db.pragma('journal_mode = WAL');

db.exec(`
CREATE TABLE IF NOT EXISTS products (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  slug TEXT UNIQUE NOT NULL, name TEXT NOT NULL, shortName TEXT,
  priceCents INTEGER NOT NULL DEFAULT 0, category TEXT, productType TEXT DEFAULT 'physical',
  sizes TEXT DEFAULT '["One Size"]', images TEXT DEFAULT '[]', cardImage TEXT, freigestellt TEXT DEFAULT '',
  badge TEXT DEFAULT '', stock INTEGER, material TEXT DEFAULT '', features TEXT DEFAULT '[]',
  featured INTEGER DEFAULT 0, sort INTEGER DEFAULT 99, desc TEXT DEFAULT ''
);
CREATE TABLE IF NOT EXISTS customers (
  id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT UNIQUE, city TEXT, created_at TEXT
);
CREATE TABLE IF NOT EXISTS orders (
  id INTEGER PRIMARY KEY AUTOINCREMENT, number TEXT UNIQUE, email TEXT, customer_name TEXT,
  status TEXT DEFAULT 'pending', total_cents INTEGER DEFAULT 0, items TEXT DEFAULT '[]',
  address TEXT DEFAULT '', created_at TEXT
);
`);

const P = (r) => r && ({ ...r, sizes: JSON.parse(r.sizes||'[]'), images: JSON.parse(r.images||'[]'), features: JSON.parse(r.features||'[]'), featured: !!r.featured });
const O = (r) => r && ({ ...r, items: JSON.parse(r.items||'[]') });

function seedIfEmpty() {
  if (db.prepare('SELECT COUNT(*) c FROM products').get().c === 0) {
    const ins = db.prepare(`INSERT INTO products (slug,name,shortName,priceCents,category,productType,sizes,images,cardImage,freigestellt,badge,stock,material,features,featured,sort,desc)
      VALUES (@slug,@name,@shortName,@priceCents,@category,@productType,@sizes,@images,@cardImage,@freigestellt,@badge,@stock,@material,@features,@featured,@sort,@desc)`);
    const tx = db.transaction(rows => rows.forEach(p => ins.run({ ...p, sizes:JSON.stringify(p.sizes), images:JSON.stringify(p.images), features:JSON.stringify(p.features), featured:p.featured?1:0 })));
    tx(SEED_PRODUCTS);
  }
  if (db.prepare('SELECT COUNT(*) c FROM customers').get().c === 0) {
    const ic = db.prepare('INSERT OR IGNORE INTO customers (name,email,city,created_at) VALUES (@name,@email,@city,@created_at)');
    const now = new Date().toISOString();
    SEED_CUSTOMERS.forEach(c => ic.run({ ...c, created_at: now }));
  }
  if (db.prepare('SELECT COUNT(*) c FROM orders').get().c === 0) {
    const io = db.prepare('INSERT INTO orders (number,email,customer_name,status,total_cents,items,address,created_at) VALUES (@number,@email,@customer_name,@status,@total_cents,@items,@address,@created_at)');
    seedOrders().forEach(o => io.run({ ...o, items: JSON.stringify(o.items), address: '' }));
  }
}
seedIfEmpty();

export const listProducts = () => db.prepare('SELECT * FROM products ORDER BY sort, id').all().map(P);
export const getProductBySlug = (slug) => P(db.prepare('SELECT * FROM products WHERE slug=?').get(slug));
export const getProductById = (id) => P(db.prepare('SELECT * FROM products WHERE id=?').get(id));
export function createProduct(d) {
  const r = db.prepare(`INSERT INTO products (slug,name,shortName,priceCents,category,productType,sizes,images,cardImage,freigestellt,badge,stock,material,features,featured,sort,desc)
    VALUES (@slug,@name,@shortName,@priceCents,@category,@productType,@sizes,@images,@cardImage,@freigestellt,@badge,@stock,@material,@features,@featured,@sort,@desc)`)
    .run(norm(d));
  return r.lastInsertRowid;
}
export function updateProduct(id, d) {
  db.prepare(`UPDATE products SET slug=@slug,name=@name,shortName=@shortName,priceCents=@priceCents,category=@category,productType=@productType,sizes=@sizes,images=@images,cardImage=@cardImage,freigestellt=@freigestellt,badge=@badge,stock=@stock,material=@material,features=@features,featured=@featured,sort=@sort,desc=@desc WHERE id=@id`)
    .run({ ...norm(d), id: Number(id) });
  return id;
}
export const deleteProduct = (id) => db.prepare('DELETE FROM products WHERE id=?').run(Number(id));
function norm(d){
  const cardImage = d.cardImage || (Array.isArray(d.images)&&d.images[0]) || d.freigestellt || '';
  return { slug:d.slug, name:d.name, shortName:d.shortName||d.name, priceCents:Math.round(Number(d.priceCents)||0), category:d.category||'', productType:d.productType||'physical',
    sizes:JSON.stringify(d.sizes||['One Size']), images:JSON.stringify(d.images||[]), cardImage, freigestellt:d.freigestellt||'',
    badge:d.badge||'', stock:(d.stock===''||d.stock==null)?null:Math.round(Number(d.stock)), material:d.material||'', features:JSON.stringify(d.features||[]),
    featured:d.featured?1:0, sort:Number(d.sort)||99, desc:d.desc||'' };
}

export const listOrders = () => db.prepare('SELECT * FROM orders ORDER BY datetime(created_at) DESC, id DESC').all().map(O);
export const getOrderById = (id) => O(db.prepare('SELECT * FROM orders WHERE id=?').get(Number(id)));
export function createOrder({ email, customer_name, items, total_cents, status='pending', address='' }) {
  const n = (db.prepare("SELECT MAX(CAST(substr(number,9) AS INTEGER)) m FROM orders").get().m) || 1042;
  const number = 'PMPNZNG-' + (n + 1);
  const r = db.prepare('INSERT INTO orders (number,email,customer_name,status,total_cents,items,address,created_at) VALUES (?,?,?,?,?,?,?,?)')
    .run(number, email||'', customer_name||'', status, total_cents||0, JSON.stringify(items||[]), address||'', new Date().toISOString());
  if (email) db.prepare('INSERT OR IGNORE INTO customers (name,email,city,created_at) VALUES (?,?,?,?)').run(customer_name||'', email, '', new Date().toISOString());
  return { id: r.lastInsertRowid, number };
}
export const updateOrderStatus = (id, status) => db.prepare('UPDATE orders SET status=? WHERE id=?').run(status, Number(id));

export function listCustomers() {
  const rows = db.prepare('SELECT * FROM customers ORDER BY id').all();
  return rows.map(c => {
    const agg = db.prepare("SELECT COUNT(*) cnt, COALESCE(SUM(total_cents),0) spent FROM orders WHERE email=? AND status NOT IN ('cancelled','refunded')").get(c.email);
    return { ...c, orders_count: agg.cnt, total_spent_cents: agg.spent };
  });
}
export const getCustomerById = (id) => db.prepare('SELECT * FROM customers WHERE id=?').get(Number(id));

export function dashboard() {
  const revenue = db.prepare("SELECT COALESCE(SUM(total_cents),0) s FROM orders WHERE status NOT IN ('cancelled','refunded')").get().s;
  const orderCount = db.prepare('SELECT COUNT(*) c FROM orders').get().c;
  const productCount = db.prepare('SELECT COUNT(*) c FROM products').get().c;
  const customerCount = db.prepare('SELECT COUNT(*) c FROM customers').get().c;
  const pending = db.prepare("SELECT COUNT(*) c FROM orders WHERE status='pending'").get().c;
  const recentOrders = db.prepare('SELECT * FROM orders ORDER BY datetime(created_at) DESC, id DESC LIMIT 6').all().map(O);
  const lowStock = db.prepare('SELECT * FROM products WHERE stock IS NOT NULL AND stock <= 25 ORDER BY stock ASC').all().map(P);
  return { revenueCents: revenue, orderCount, productCount, customerCount, pending, recentOrders, lowStock };
}
