<?php
/**
 * File: api/karigar/receive_add.php
 * Purpose: Karigar থেকে item receive + wastage + shortage + labor
 * Method : POST
 *
 * Input: {
 *   karigar_party_id, receive_date, related_issue_id (optional), job_id (optional),
 *   item_description, category, item_type, pieces,
 *   karat, purity_percent, gross_weight_gram,
 *   wastage_pure_gram, shortage_pure_gram,
 *   shortage_settlement_mode (GOLD_BALANCE/CASH_CHARGE/RECORD_ONLY),
 *   shortage_cash_rate_per_gram (optional),
 *   labor_rate_per_vori, labor_rate_per_gram,
 *   labor_basis_weight_gram, labor_basis_type, labor_amount,
 *   destination_type, destination_reference_id (optional),
 *   note
 * }
 *
 * Side-effects:
 *   1) karigar_receives INSERT
 *   2) karigar_ledger INSERT (RECEIVE_GOLD + WASTAGE + SHORTAGE + LABOR_CHARGE)
 *   3) parties.gold_balance UPDATE (যদি GOLD_BALANCE shortage mode)
 *   4) gold_ledger INSERT (receive movement)
 *   5) karigar_jobs summary UPDATE (যদি job_id)
 *   6) audit_log
 */

ini_set('display_errors', 0);
error_reporting(E_ALL);

header('Content-Type: application/json; charset=utf-8');

require_once __DIR__ . '/../../config/session.php';
require_once __DIR__ . '/../../config/db.php';

function out_json($code, $success, $message, $data = null) {
    http_response_code($code);
    echo json_encode([
        'success' => (bool)$success,
        'status'  => (bool)$success,
        'message' => $message,
        'data'    => $data
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

if (function_exists('is_logged_in') && !is_logged_in()) {
    out_json(401, false, 'লগইন প্রয়োজন', null);
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    out_json(405, false, 'শুধু POST অনুরোধ গ্রহণযোগ্য', null);
}

if (!isset($pdo) || !($pdo instanceof PDO)) {
    out_json(500, false, 'Database connection পাওয়া যায়নি', null);
}

$raw  = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!is_array($data)) $data = $_POST;

// ===== Inputs =====
$karigar_party_id   = (int)($data['karigar_party_id'] ?? 0);
$receive_date       = trim((string)($data['receive_date'] ?? date('Y-m-d')));
$related_issue_id   = isset($data['related_issue_id']) && $data['related_issue_id'] !== ''
                        ? (int)$data['related_issue_id'] : null;
$job_id             = isset($data['job_id']) && $data['job_id'] !== ''
                        ? (int)$data['job_id'] : null;

$item_description   = trim((string)($data['item_description'] ?? ''));
$category           = trim((string)($data['category'] ?? ''));
$item_type          = trim((string)($data['item_type'] ?? ''));
$pieces             = (int)($data['pieces'] ?? 1);

$karat              = trim((string)($data['karat'] ?? '22K'));
$purity_percent     = (float)($data['purity_percent'] ?? 0);
$gross_weight_gram  = (float)($data['gross_weight_gram'] ?? 0);

$wastage_pure_gram  = (float)($data['wastage_pure_gram'] ?? 0);
$shortage_pure_gram = (float)($data['shortage_pure_gram'] ?? 0);

$shortage_mode      = trim((string)($data['shortage_settlement_mode'] ?? 'GOLD_BALANCE'));
$shortage_rate      = isset($data['shortage_cash_rate_per_gram']) && $data['shortage_cash_rate_per_gram'] !== ''
                        ? (float)$data['shortage_cash_rate_per_gram'] : null;

$labor_rate_vori    = (float)($data['labor_rate_per_vori'] ?? 0);
$labor_rate_gram    = (float)($data['labor_rate_per_gram'] ?? 0);
$labor_basis_weight = (float)($data['labor_basis_weight_gram'] ?? 0);
$labor_basis_type   = trim((string)($data['labor_basis_type'] ?? 'GROSS_RECEIVED'));
$labor_amount       = (float)($data['labor_amount'] ?? 0);

$destination_type   = trim((string)($data['destination_type'] ?? 'BARCODE_STOCK'));
$destination_ref_id = isset($data['destination_reference_id']) && $data['destination_reference_id'] !== ''
                        ? (int)$data['destination_reference_id'] : null;

$note               = trim((string)($data['note'] ?? ''));

// ===== Validate =====
if ($karigar_party_id <= 0) out_json(400, false, 'Karigar select করুন', null);
if ($gross_weight_gram <= 0) out_json(400, false, 'Gross weight ০-এর বেশি দিন', null);
if ($purity_percent <= 0 || $purity_percent > 100) {
    out_json(400, false, 'Purity ১-১০০ এর মধ্যে দিন', null);
}

$allowed_karat = ['24K','22K','21K','18K','other'];
if (!in_array($karat, $allowed_karat, true)) out_json(400, false, 'Invalid karat', null);

$allowed_short_mode = ['GOLD_BALANCE','CASH_CHARGE','RECORD_ONLY'];
if (!in_array($shortage_mode, $allowed_short_mode, true)) {
    out_json(400, false, 'Invalid shortage settlement mode', null);
}

$allowed_basis = ['GROSS_ISSUED','PURE_ISSUED','GROSS_RECEIVED','PURE_RECEIVED','MANUAL'];
if (!in_array($labor_basis_type, $allowed_basis, true)) {
    out_json(400, false, 'Invalid labor basis type', null);
}

$allowed_dest = ['BARCODE_STOCK','NEW_STOCK','GOLD_STOCK','OLD_GOLD_STOCK','SOLD_DIRECT','CUSTOMER_DELIVERY'];
if (!in_array($destination_type, $allowed_dest, true)) {
    out_json(400, false, 'Invalid destination', null);
}

if ($shortage_pure_gram > 0.0001 && $shortage_mode === 'CASH_CHARGE' && ($shortage_rate === null || $shortage_rate <= 0)) {
    out_json(400, false, 'CASH_CHARGE select করেছেন — gold rate দিন', null);
}

// Auto pure
$pure_weight_gram = round($gross_weight_gram * ($purity_percent / 100.0), 4);

// Shortage cash amount auto
$shortage_cash_amount = null;
if ($shortage_pure_gram > 0.0001 && $shortage_mode === 'CASH_CHARGE') {
    $shortage_cash_amount = round($shortage_pure_gram * (float)$shortage_rate, 2);
}

// Acceptable wastage snapshot
$acceptable_wastage_snapshot = null;

try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // ===== Karigar exists check =====
    $chk = $pdo->prepare("SELECT id, name, is_karigar, deleted_at, gold_balance
                          FROM parties WHERE id = ? LIMIT 1");
    $chk->execute([$karigar_party_id]);
    $karigar = $chk->fetch(PDO::FETCH_ASSOC);

    if (!$karigar)                                  out_json(404, false, 'এই karigar পাওয়া যায়নি', null);
    if ((int)$karigar['is_karigar'] !== 1)          out_json(400, false, 'এই party karigar না', null);
    if ($karigar['deleted_at'] !== null)            out_json(400, false, 'এই karigar deleted', null);

    // ===== Related issue check (যদি দেওয়া হয়) =====
    $related_issue = null;
    if ($related_issue_id !== null) {
        $is = $pdo->prepare("SELECT id, karigar_party_id, pure_weight_gram, gross_weight_gram
                             FROM karigar_issues WHERE id = ? AND deleted_at IS NULL LIMIT 1");
        $is->execute([$related_issue_id]);
        $related_issue = $is->fetch(PDO::FETCH_ASSOC);

        if (!$related_issue) out_json(404, false, 'Related issue পাওয়া যায়নি', null);
        if ((int)$related_issue['karigar_party_id'] !== $karigar_party_id) {
            out_json(400, false, 'Related issue অন্য karigar এর', null);
        }
    }

    // ===== Job check =====
    if ($job_id !== null) {
        $jchk = $pdo->prepare("SELECT id, karigar_party_id, status, deleted_at
                               FROM karigar_jobs WHERE id = ? LIMIT 1");
        $jchk->execute([$job_id]);
        $job = $jchk->fetch(PDO::FETCH_ASSOC);

        if (!$job)                              out_json(404, false, 'Job পাওয়া যায়নি', null);
        if ($job['deleted_at'] !== null)        out_json(400, false, 'Job deleted', null);
        if ((int)$job['karigar_party_id'] !== $karigar_party_id) {
            out_json(400, false, 'Job অন্য karigar এর', null);
        }
        if (in_array($job['status'], ['SETTLED','CANCELLED'], true)) {
            out_json(400, false, 'Job ' . $job['status'] . ' — receive করা যাবে না', null);
        }
    }

    // ===== Wastage % snapshot (যদি item_type থাকে) =====
    if ($item_type !== '') {
        $ws = $pdo->prepare("SELECT acceptable_wastage_percent
                             FROM karigar_wastage_settings
                             WHERE item_type = ? AND is_active = 1 LIMIT 1");
        $ws->execute([$item_type]);
        $wsRow = $ws->fetch(PDO::FETCH_ASSOC);
        if ($wsRow) $acceptable_wastage_snapshot = (float)$wsRow['acceptable_wastage_percent'];
    }

    // ===== Begin transaction =====
    $pdo->beginTransaction();

    $user_id = (int)($_SESSION['user_id'] ?? 0);
    $ip      = $_SERVER['REMOTE_ADDR'] ?? '';

    // ===== 1) karigar_receives INSERT =====
    $insR = $pdo->prepare("
        INSERT INTO karigar_receives
            (receive_date, karigar_party_id, job_id, related_issue_id,
             item_description, category, item_type, pieces,
             karat, purity_percent, gross_weight_gram, pure_weight_gram,
             wastage_pure_gram, acceptable_wastage_percent_snapshot,
             shortage_pure_gram, shortage_settlement_mode,
             shortage_cash_rate_per_gram, shortage_cash_amount,
             labor_rate_per_vori, labor_rate_per_gram, labor_basis_weight_gram,
             labor_basis_type, labor_amount,
             destination_type, destination_reference_id,
             note, created_by, created_at)
        VALUES
            (:rdate, :kid, :job_id, :rel_iss,
             :item_desc, :cat, :item_type, :pcs,
             :karat, :purity, :gross, :pure,
             :wastage, :ws_snap,
             :shortage, :short_mode,
             :short_rate, :short_amt,
             :lvori, :lgram, :lbw,
             :lbt, :lamt,
             :dest, :dest_ref,
             :note, :cby, NOW())
    ");
    $insR->execute([
        ':rdate'      => $receive_date,
        ':kid'        => $karigar_party_id,
        ':job_id'     => $job_id,
        ':rel_iss'    => $related_issue_id,
        ':item_desc'  => $item_description,
        ':cat'        => $category,
        ':item_type'  => ($item_type === '' ? null : $item_type),
        ':pcs'        => $pieces,
        ':karat'      => $karat,
        ':purity'     => $purity_percent,
        ':gross'      => $gross_weight_gram,
        ':pure'       => $pure_weight_gram,
        ':wastage'    => $wastage_pure_gram,
        ':ws_snap'    => $acceptable_wastage_snapshot,
        ':shortage'   => $shortage_pure_gram,
        ':short_mode' => $shortage_mode,
        ':short_rate' => $shortage_rate,
        ':short_amt'  => $shortage_cash_amount,
        ':lvori'      => $labor_rate_vori,
        ':lgram'      => $labor_rate_gram,
        ':lbw'        => $labor_basis_weight,
        ':lbt'        => $labor_basis_type,
        ':lamt'       => $labor_amount,
        ':dest'       => $destination_type,
        ':dest_ref'   => $destination_ref_id,
        ':note'       => $note,
        ':cby'        => $user_id
    ]);
    $receive_id = (int)$pdo->lastInsertId();

    // ===== 2) karigar_ledger INSERTs (multiple) =====
    $ledIns = $pdo->prepare("
        INSERT INTO karigar_ledger
            (entry_date, karigar_party_id, entry_type, reference_table, reference_id,
             gold_in_pure_gram, gold_out_pure_gram, cash_in, cash_out,
             note, created_by, created_at)
        VALUES
            (:dt, :kid, :etype, 'karigar_receives', :ref,
             :gin, :gout, :cin, :cout,
             :note, :cby, NOW())
    ");

    // 2a) RECEIVE_GOLD (pure received)
    $ledIns->execute([
        ':dt'    => $receive_date,
        ':kid'   => $karigar_party_id,
        ':etype' => 'RECEIVE_GOLD',
        ':ref'   => $receive_id,
        ':gin'   => $pure_weight_gram,
        ':gout'  => 0,
        ':cin'   => 0,
        ':cout'  => 0,
        ':note'  => 'Receive #' . $receive_id . ' — ' . $item_description,
        ':cby'   => $user_id
    ]);

    // 2b) WASTAGE_ACCEPTED (যদি wastage > 0)
    if ($wastage_pure_gram > 0.0001) {
        $ledIns->execute([
            ':dt'    => $receive_date,
            ':kid'   => $karigar_party_id,
            ':etype' => 'WASTAGE_ACCEPTED',
            ':ref'   => $receive_id,
            ':gin'   => $wastage_pure_gram,
            ':gout'  => 0,
            ':cin'   => 0,
            ':cout'  => 0,
            ':note'  => 'Acceptable wastage adjustment',
            ':cby'   => $user_id
        ]);
    }

    // 2c) SHORTAGE_CHARGED (যদি shortage > 0)
    if ($shortage_pure_gram > 0.0001) {
        if ($shortage_mode === 'GOLD_BALANCE') {
            // karigar gold balance এ যোগ — তাকে দিতে হবে
            $ledIns->execute([
                ':dt'    => $receive_date,
                ':kid'   => $karigar_party_id,
                ':etype' => 'SHORTAGE_CHARGED',
                ':ref'   => $receive_id,
                ':gin'   => $shortage_pure_gram,  // আমাদের পক্ষে gold আসার কথা ছিল
                ':gout'  => 0,
                ':cin'   => 0,
                ':cout'  => 0,
                ':note'  => 'Shortage → karigar gold balance এ যোগ',
                ':cby'   => $user_id
            ]);

            // parties.gold_balance update (karigar er upor amader pawa gold)
            $pdo->prepare("
                UPDATE parties
                SET gold_balance = COALESCE(gold_balance, 0) + ?
                WHERE id = ?
            ")->execute([$shortage_pure_gram, $karigar_party_id]);

        } elseif ($shortage_mode === 'CASH_CHARGE') {
            // Cash charge — karigar এর cash দেনা বাড়লো (আমরা পাব)
            // ব্যবসায়িক logic: shortage cash amount karigar এর labor due থেকে adjust হবে
            // অর্থাৎ labor payment এর সময় এটা কাটব
            // এখন শুধু ledger এ record
            $ledIns->execute([
                ':dt'    => $receive_date,
                ':kid'   => $karigar_party_id,
                ':etype' => 'SHORTAGE_CHARGED',
                ':ref'   => $receive_id,
                ':gin'   => 0,
                ':gout'  => 0,
                ':cin'   => $shortage_cash_amount,  // আমরা পাব
                ':cout'  => 0,
                ':note'  => 'Shortage → cash charge @ ৳' . $shortage_rate . '/g = ৳' . $shortage_cash_amount,
                ':cby'   => $user_id
            ]);
        } else {
            // RECORD_ONLY — শুধু entry, no balance impact
            $ledIns->execute([
                ':dt'    => $receive_date,
                ':kid'   => $karigar_party_id,
                ':etype' => 'SHORTAGE_CHARGED',
                ':ref'   => $receive_id,
                ':gin'   => 0,
                ':gout'  => 0,
                ':cin'   => 0,
                ':cout'  => 0,
                ':note'  => 'Shortage recorded (no financial impact)',
                ':cby'   => $user_id
            ]);
        }
    }

    // 2d) LABOR_CHARGE (যদি labor > 0)
    if ($labor_amount > 0.01) {
        $ledIns->execute([
            ':dt'    => $receive_date,
            ':kid'   => $karigar_party_id,
            ':etype' => 'LABOR_CHARGE',
            ':ref'   => $receive_id,
            ':gin'   => 0,
            ':gout'  => 0,
            ':cin'   => 0,
            ':cout'  => $labor_amount,  // আমরা দেব
            ':note'  => 'Labor charge — basis: ' . $labor_basis_type . ' (' . $labor_basis_weight . 'g)',
            ':cby'   => $user_id
        ]);
    }

    // ===== 3) gold_ledger INSERT (overall stock view) =====
    $glIns = $pdo->prepare("
        INSERT INTO gold_ledger
            (entry_date, party_id, location_id, entry_type, reference_id,
             gold_in, gold_out, amount_in, amount_out, karat, note, created_by, created_at)
        VALUES
            (:dt, :pid, 1, 'ADJUSTMENT', :ref,
             :gin, 0, 0, 0, :karat, :note, :cby, NOW())
    ");
    $glIns->execute([
        ':dt'    => $receive_date,
        ':pid'   => $karigar_party_id,
        ':ref'   => $receive_id,
        ':gin'   => $gross_weight_gram,
        ':karat' => $karat,
        ':note'  => 'Karigar Receive #' . $receive_id . ' (' . $karigar['name'] . ') → ' . $destination_type,
        ':cby'   => $user_id
    ]);

    // ===== 4) Job summary update =====
    if ($job_id !== null) {
        $pdo->prepare("
            UPDATE karigar_jobs
            SET total_received_gross = COALESCE(total_received_gross, 0) + :gross,
                total_received_pure  = COALESCE(total_received_pure, 0) + :pure,
                total_wastage_pure   = COALESCE(total_wastage_pure, 0) + :wastage,
                total_labor_due      = COALESCE(total_labor_due, 0) + :labor,
                status = CASE WHEN status IN ('OPEN','IN_PROGRESS') THEN 'DELIVERED' ELSE status END
            WHERE id = :id
        ")->execute([
            ':gross'   => $gross_weight_gram,
            ':pure'    => $pure_weight_gram,
            ':wastage' => $wastage_pure_gram,
            ':labor'   => $labor_amount,
            ':id'      => $job_id
        ]);
    }

    // ===== 5) Audit log =====
    try {
        $alog = $pdo->prepare("
            INSERT INTO audit_log
                (table_name, record_id, action, changed_by, changed_at, ip_address, new_values, note)
            VALUES
                ('karigar_receives', ?, 'INSERT', ?, NOW(), ?, ?, ?)
        ");
        $alog->execute([
            $receive_id,
            $user_id,
            $ip,
            json_encode([
                'karigar' => $karigar['name'],
                'gross'   => $gross_weight_gram,
                'pure'    => $pure_weight_gram,
                'wastage' => $wastage_pure_gram,
                'shortage'=> $shortage_pure_gram,
                'short_mode' => $shortage_mode,
                'labor'   => $labor_amount,
                'dest'    => $destination_type
            ], JSON_UNESCAPED_UNICODE),
            'Karigar receive #' . $receive_id
        ]);
    } catch (Throwable $e) { /* silent */ }

    $pdo->commit();

    out_json(200, true, 'Receive সফলভাবে save হয়েছে ✅', [
        'receive_id'           => $receive_id,
        'karigar_name'         => $karigar['name'],
        'gross_weight'         => $gross_weight_gram,
        'pure_weight'          => $pure_weight_gram,
        'wastage_pure'         => $wastage_pure_gram,
        'shortage_pure'        => $shortage_pure_gram,
        'shortage_cash_amount' => $shortage_cash_amount,
        'labor_amount'         => $labor_amount,
        'destination'          => $destination_type
    ]);

} catch (Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    out_json(500, false, 'সার্ভার ত্রুটি: ' . $e->getMessage(), null);
}
