import { getDb } from "../../../db";
import { requireSession } from "../../auth-server";
type Item={description:string;qty:number;unit:string;price:number};const n=(v:unknown)=>Number(v)||0,first=<T,>(rows:unknown)=>((rows as T[])||[])[0];
function totals(items:Item[],taxMode:string,taxRate:number,discountType:string,discountValue:number){const subtotal=items.reduce((a,x)=>a+n(x.qty)*n(x.price),0),discountAmount=discountType==="percent"?subtotal*n(discountValue)/100:Math.min(subtotal,n(discountValue)),after=Math.max(0,subtotal-discountAmount),taxAmount=taxMode==="exclude"?after*n(taxRate)/100:taxMode==="include"?after*n(taxRate)/(100+n(taxRate)):0;return{subtotal,discountAmount,taxAmount,total:taxMode==="exclude"?after+taxAmount:after}}
const selectDoc="SELECT d.id,d.type,d.document_no documentNo,d.date,d.due_date dueDate,d.client_id clientId,d.project_id projectId,d.subject,d.items_json itemsJson,d.tax_mode taxMode,d.tax_rate taxRate,d.discount_type discountType,d.discount_value discountValue,d.subtotal,d.discount_amount discountAmount,d.tax_amount taxAmount,d.total,d.paid_amount paidAmount,d.status,d.source_document_id sourceDocumentId,d.sent_at sentAt,d.sent_to sentTo,d.payment_date paymentDate,d.payment_method paymentMethod,d.terms,d.notes,d.created_at createdAt,c.company clientName,c.address clientAddress,p.name projectName FROM commercial_documents d LEFT JOIN clients c ON c.id=d.client_id LEFT JOIN projects p ON p.id=d.project_id";
export async function GET(request:Request){const auth=await requireSession(request);if(auth.response)return auth.response;try{const [rows]=await getDb().query(`${selectDoc} ORDER BY d.id DESC`);return Response.json({documents:rows})}catch(e){return Response.json({error:e instanceof Error?e.message:"Gagal membaca dokumen",documents:[]},{status:500})}}
export async function POST(request:Request){const auth=await requireSession(request,"manager");if(auth.response)return auth.response;try{const p=await request.json() as Record<string,unknown>,db=getDb();
 if(p.kind==="update_status"){const id=n(p.id),[rows]=await db.query("SELECT document_no documentNo,sent_at sentAt,sent_to sentTo FROM commercial_documents WHERE id=? LIMIT 1",[id]),current=first<{documentNo:string;sentAt:string;sentTo:string}>(rows);if(!current)return Response.json({error:"Dokumen tidak ditemukan"},{status:404});const status=String(p.status||"");await db.execute("UPDATE commercial_documents SET status=?,sent_at=?,sent_to=? WHERE id=?",[status,String(p.sentAt||current.sentAt||""),String(p.sentTo||current.sentTo||""),id]);await db.execute("UPDATE finance_entries SET status=? WHERE document_no=?",[status,current.documentNo]);const [updated]=await db.query(`${selectDoc} WHERE d.id=?`,[id]);return Response.json(first(updated));}
 if(p.kind==="receipt"){const id=n(p.sourceDocumentId),[sourceRows]=await db.query("SELECT * FROM commercial_documents WHERE id=? LIMIT 1",[id]),s=first<Record<string,unknown>>(sourceRows);if(!s)return Response.json({error:"Tagihan sumber tidak ditemukan"},{status:404});const [mx]=await db.query("SELECT COALESCE(MAX(id),0)+1 nextId FROM commercial_documents"),next=first<{nextId:number}>(mx)?.nextId||1,documentNo=`KWT/JLBB/${new Date().getFullYear()}/${String(next).padStart(4,"0")}`,paymentDate=String(p.paymentDate||new Date().toISOString().slice(0,10)),amount=Math.min(n(p.paidAmount)||n(s.total),n(s.total)),method=String(p.paymentMethod||"Transfer Bank");const [r]=await db.execute("INSERT INTO commercial_documents(type,document_no,date,due_date,client_id,project_id,subject,items_json,tax_mode,tax_rate,discount_type,discount_value,subtotal,discount_amount,tax_amount,total,paid_amount,status,source_document_id,sent_at,sent_to,payment_date,payment_method,terms,notes) VALUES('Kwitansi',?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? ,?,'','',?,?,?,?)",[documentNo,paymentDate,"",s.client_id,s.project_id,s.subject,s.items_json,s.tax_mode,s.tax_rate,s.discount_type,s.discount_value,s.subtotal,s.discount_amount,s.tax_amount,amount,amount,"Lunas",id,paymentDate,method,s.terms,s.notes]);const newId=(r as {insertId:number}).insertId;await db.execute("UPDATE commercial_documents SET paid_amount=?,status=? WHERE id=?",[amount,amount>=n(s.total)?"Lunas":"Sebagian",id]);await db.execute("INSERT INTO finance_entries(date,due_date,document_no,category,direction,description,amount,paid_amount,status,client_id,project_id,notes) VALUES(?,'',?,'Penerimaan','Masuk',?,?,?,?,?,?,?)",[paymentDate,documentNo,`Pembayaran ${String(s.subject)}`,amount,amount,"Lunas",s.client_id,s.project_id,`Kwitansi dari ${String(s.document_no)}`]);const [created]=await db.query(`${selectDoc} WHERE d.id=?`,[newId]);return Response.json(first(created),{status:201});}
 const items=(Array.isArray(p.items)?p.items:[]) as Item[];if(!items.length||!p.clientId)return Response.json({error:"Klien dan minimal satu rincian wajib diisi"},{status:400});const taxMode=String(p.taxMode||"exclude"),taxRate=n(p.taxRate),discountType=String(p.discountType||"percent"),discountValue=n(p.discountValue),calc=totals(items,taxMode,taxRate,discountType,discountValue),type=String(p.type||"Penawaran"),[mx]=await db.query("SELECT COALESCE(MAX(id),0)+1 nextId FROM commercial_documents"),next=first<{nextId:number}>(mx)?.nextId||1,prefix=type==="Penawaran"?"PEN":"INV",documentNo=`${prefix}/JLBB/${new Date().getFullYear()}/${String(next).padStart(4,"0")}`,status=String(p.status||(type==="Penawaran"?"Draft":"Belum Terkirim"));const [r]=await db.execute("INSERT INTO commercial_documents(type,document_no,date,due_date,client_id,project_id,subject,items_json,tax_mode,tax_rate,discount_type,discount_value,subtotal,discount_amount,tax_amount,total,paid_amount,status,sent_at,sent_to,payment_date,payment_method,terms,notes) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,0,?,?,?,'','',?,?)",[type,documentNo,String(p.date||""),String(p.dueDate||""),n(p.clientId),p.projectId?n(p.projectId):null,String(p.subject||type),JSON.stringify(items),taxMode,taxRate,discountType,discountValue,calc.subtotal,calc.discountAmount,calc.taxAmount,calc.total,status,String(p.sentAt||""),String(p.sentTo||""),String(p.terms||""),String(p.notes||"")]);const newId=(r as {insertId:number}).insertId;await db.execute("INSERT INTO finance_entries(date,due_date,document_no,category,direction,description,amount,paid_amount,status,client_id,project_id,notes) VALUES(?,?,?,?,?,?,?,0,?,?,?,?)",[String(p.date||""),String(p.dueDate||""),documentNo,type==="Penawaran"?"Penawaran":"Invoice","Masuk",String(p.subject||type),calc.total,status,n(p.clientId),p.projectId?n(p.projectId):null,`Pajak ${taxMode}, diskon ${calc.discountAmount}`]);const [created]=await db.query(`${selectDoc} WHERE d.id=?`,[newId]);return Response.json(first(created),{status:201});
 }catch(e){return Response.json({error:e instanceof Error?e.message:"Gagal menyimpan dokumen"},{status:500})}}
export async function DELETE(request:Request){const auth=await requireSession(request,"manager");if(auth.response)return auth.response;try{const id=n(new URL(request.url).searchParams.get("id")),db=getDb();if(!id)return Response.json({error:"Dokumen tidak valid"},{status:400});const [rows]=await db.query("SELECT * FROM commercial_documents WHERE id=? LIMIT 1",[id]),d=first<Record<string,unknown>>(rows);if(!d)return Response.json({error:"Dokumen tidak ditemukan"},{status:404});if(d.type==="Tagihan"){const [receipt]=await db.query("SELECT id FROM commercial_documents WHERE source_document_id=? LIMIT 1",[id]);if(first(receipt))return Response.json({error:"Tagihan sudah memiliki kwitansi. Hapus kwitansi terlebih dahulu."},{status:409});}if(d.type==="Kwitansi"&&d.source_document_id){const [sourceRows]=await db.query("SELECT id,document_no documentNo,sent_at sentAt FROM commercial_documents WHERE id=? LIMIT 1",[d.source_document_id]),s=first<{id:number;documentNo:string;sentAt:string}>(sourceRows);if(s){const status=s.sentAt?"Terkirim":"Belum Terkirim";await db.execute("UPDATE commercial_documents SET paid_amount=0,status=? WHERE id=?",[status,s.id]);await db.execute("UPDATE finance_entries SET paid_amount=0,status=? WHERE document_no=?",[status,s.documentNo]);}}await db.execute("DELETE FROM finance_entries WHERE document_no=?",[d.document_no]);await db.execute("DELETE FROM commercial_documents WHERE id=?",[id]);return Response.json({ok:true});}catch(e){return Response.json({error:e instanceof Error?e.message:"Gagal menghapus dokumen"},{status:500})}}
