/* =====================================================
   File: /ui/js/cash_entry.js
   Cash Entry + Party Search + Quick Party Add
   ===================================================== */

(function () {
  'use strict';

  var API = {
    accounts: '../api/cash/get_accounts.php',
    addTransaction: '../api/cash/add_transaction.php',
    listTransactions: '../api/cash/list_transactions.php',
    partyList: '../api/customers/party_list.php',
    partyAdd: '../api/customers/party_add.php'
  };

  var mode = 'IN';
  var allParties = [];

  function $(id) {
    return document.getElementById(id);
  }

  function todayISO() {
    var d = new Date();
    var m = String(d.getMonth() + 1).padStart(2, '0');
    var day = String(d.getDate()).padStart(2, '0');
    return d.getFullYear() + '-' + m + '-' + day;
  }

  function esc(v) {
    return String(v == null ? '' : v).replace(/[&<>"']/g, function (m) {
      return {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
      }[m];
    });
  }

  function num(v) {
    var n = parseFloat(v);
    return isNaN(n) ? 0 : n;
  }

  function tk(v) {
    return '৳' + Math.round(num(v)).toLocaleString('en-IN');
  }

  function showMsg(text, type) {
    var el = $('formMsg');
    if (!el) {
      alert(text);
      return;
    }

    el.className = 'msg ' + (type === 'err' ? 'err' : 'ok');
    el.textContent = text;

    setTimeout(function () {
      el.className = 'msg';
      el.textContent = '';
    }, 3500);
  }

  async function fetchJson(url, options) {
    options = options || {};

    var res = await fetch(url, Object.assign({
      credentials: 'same-origin',
      cache: 'no-store'
    }, options));

    var text = await res.text();

    try {
      return JSON.parse(text);
    } catch (e) {
      throw new Error('Invalid JSON: ' + text.substring(0, 180));
    }
  }

  function getRows(data, keys) {
    keys = keys || [];

    if (Array.isArray(data)) return data;

    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];

      if (data && Array.isArray(data[key])) return data[key];
      if (data && data.data && Array.isArray(data.data[key])) return data.data[key];
    }

    if (data && Array.isArray(data.data)) return data.data;
    if (data && Array.isArray(data.rows)) return data.rows;
    if (data && Array.isArray(data.items)) return data.items;
    if (data && Array.isArray(data.accounts)) return data.accounts;
    if (data && Array.isArray(data.transactions)) return data.transactions;
    if (data && Array.isArray(data.parties)) return data.parties;

    return [];
  }

  function injectPartyStyle() {
    if (document.getElementById('partyPickerStyle')) return;

    var style = document.createElement('style');
    style.id = 'partyPickerStyle';
    style.textContent = `
      .party-live-box{
        margin-top:8px;
        background:#071122;
        border:1px solid rgba(245,184,0,.35);
        border-radius:14px;
        max-height:280px;
        overflow:auto;
        display:none;
      }
      .party-live-box.show{display:block}
      .party-live-item{
        padding:13px 15px;
        border-bottom:1px solid rgba(26,45,80,.85);
        cursor:pointer;
      }
      .party-live-item:last-child{border-bottom:0}
      .party-live-name{
        color:#E8F0FE;
        font-size:20px;
        font-weight:900;
      }
      .party-live-phone{
        color:#A8BEE4;
        font-size:15px;
        margin-top:4px;
        font-weight:700;
      }
      .party-live-badge{
        display:inline-block;
        margin-top:7px;
        padding:4px 10px;
        border-radius:999px;
        background:rgba(245,184,0,.16);
        color:#F5B800;
        font-size:12px;
        font-weight:900;
      }
      .party-live-add{
        padding:15px;
        text-align:center;
        color:#34D399;
        background:rgba(16,185,129,.10);
        font-size:19px;
        font-weight:900;
        cursor:pointer;
      }
      .selected-party-pill{
        margin-top:8px;
        padding:11px 13px;
        border-radius:13px;
        background:rgba(16,185,129,.12);
        color:#34D399;
        border:1px solid rgba(16,185,129,.35);
        font-size:15px;
        font-weight:900;
        display:none;
      }
      .selected-party-pill.show{display:block}
    `;
    document.head.appendChild(style);
  }

  function normalizeParty(p) {
    p = p || {};
    return {
      id: p.id || p.party_id || p.customer_id || '',
      name: p.name || p.party_name || p.customer_name || '',
      phone: p.phone || p.mobile || p.mobile_no || p.contact || '',
      address: p.address || '',
      type: p.type || p.party_type || ''
    };
  }

  function ensurePartyPickerBox() {
    var search = $('party_search');
    if (!search) return null;

    var box = $('partyLiveBox');

    if (!box) {
      box = document.createElement('div');
      box.id = 'partyLiveBox';
      box.className = 'party-live-box';
      search.insertAdjacentElement('afterend', box);
    }

    var pill = $('selectedPartyPill');

    if (!pill) {
      pill = document.createElement('div');
      pill.id = 'selectedPartyPill';
      pill.className = 'selected-party-pill';

      var select = $('party_id');
      if (select) {
        select.insertAdjacentElement('afterend', pill);
      }
    }

    return box;
  }

  function renderHiddenPartySelect(parties, selectedId) {
    selectedId = selectedId || '';

    var select = $('party_id');
    if (!select) return;

    var html = '<option value="">— পার্টি নির্বাচন করুন —</option>';

    parties.forEach(function (raw) {
      var p = normalizeParty(raw);
      var label = p.phone ? (p.name + ' — ' + p.phone) : p.name;
      html += '<option value="' + esc(p.id) + '">' + esc(label) + '</option>';
    });

    select.innerHTML = html;

    if (selectedId) {
      select.value = String(selectedId);
    }
  }

  function renderPartyLiveList(query) {
    query = query || '';

    var box = ensurePartyPickerBox();
    if (!box) return;

    var q = query.trim().toLowerCase();

    var rows = allParties
      .map(normalizeParty)
      .filter(function (p) {
        if (!q) return true;

        return String(p.name).toLowerCase().includes(q) ||
               String(p.phone).toLowerCase().includes(q);
      })
      .slice(0, 20);

    var html = '';

    rows.forEach(function (p) {
      html += ''
        + '<div class="party-live-item" '
        + 'data-party-id="' + esc(p.id) + '" '
        + 'data-party-name="' + esc(p.name) + '" '
        + 'data-party-phone="' + esc(p.phone) + '">'
        + '<div class="party-live-name">' + esc(p.name || 'নাম নেই') + '</div>'
        + '<div class="party-live-phone">📞 ' + esc(p.phone || 'মোবাইল নেই') + '</div>'
        + '<span class="party-live-badge">পার্টি</span>'
        + '</div>';
    });

    html += '<div class="party-live-add" id="partyLiveAddBtn">+ নতুন পার্টি যোগ করুন</div>';

    box.innerHTML = html;
    box.classList.add('show');
  }

  function selectParty(id, name, phone) {
    var select = $('party_id');
    var search = $('party_search');
    var box = $('partyLiveBox');
    var pill = $('selectedPartyPill');

    if (select) select.value = String(id || '');
    if (search) search.value = phone ? (name + ' — ' + phone) : name;

    if (pill) {
      pill.textContent = 'নির্বাচিত: ' + (phone ? (name + ' — ' + phone) : name);
      pill.classList.add('show');
    }

    if (box) box.classList.remove('show');
  }

  async function loadPartyList(selectedId) {
    selectedId = selectedId || '';

    try {
      var data = await fetchJson(API.partyList);
      allParties = getRows(data, ['parties', 'customers', 'party']);
      renderHiddenPartySelect(allParties, selectedId);
    } catch (err) {
      console.error('Party list error:', err);
      allParties = [];
    }
  }

  async function loadAccounts(selectedId) {
    selectedId = selectedId || '';

    var select = $('cash_account_id');
    if (!select) return;

    select.innerHTML = '<option value="">লোড হচ্ছে...</option>';

    try {
      var data = await fetchJson(API.accounts);
      var accounts = getRows(data, ['accounts', 'cash_accounts']);

      if (!accounts.length) {
        select.innerHTML = '<option value="">কোনো অ্যাকাউন্ট পাওয়া যায়নি</option>';
        return;
      }

      var html = '<option value="">— অ্যাকাউন্ট বাছাই করুন —</option>';

      accounts.forEach(function (acc) {
        var id = acc.id || acc.account_id || '';
        var name = acc.name || acc.account_name || acc.title || 'Account';
        var balance = acc.current_balance != null ? acc.current_balance : (acc.balance != null ? acc.balance : 0);

        html += '<option value="' + esc(id) + '">' + esc(name) + ' (' + tk(balance) + ')</option>';
      });

      select.innerHTML = html;

      if (selectedId) {
        select.value = String(selectedId);
      }

    } catch (err) {
      console.error('Account error:', err);
      select.innerHTML = '<option value="">অ্যাকাউন্ট লোড হয়নি</option>';
    }
  }

  function setMode(nextMode) {
    mode = nextMode;

    var inTab = $('cashInTab');
    var outTab = $('cashOutTab');
    var title = $('formTitle');
    var submit = $('submitBtn');
    var purpose = $('transaction_purpose');
    var previewLabel = $('amountPreviewLabel');

    if (mode === 'IN') {
      if (inTab) inTab.classList.add('active');
      if (outTab) outTab.classList.remove('active');

      if (title) title.textContent = 'ক্যাশ ইন এন্ট্রি';

      if (submit) {
        submit.textContent = '💾 ক্যাশ ইন সেভ করুন';
        submit.className = 'submit-btn in';
      }

      if (previewLabel) previewLabel.textContent = 'ক্যাশ ইন হবে';

      if (purpose) {
        purpose.innerHTML = ''
          + '<option value="বিক্রয় আদায়">বিক্রয় আদায়</option>'
          + '<option value="বন্ধক আদায়">বন্ধক আদায়</option>'
          + '<option value="পুরাতন স্বর্ণ বিক্রয়">পুরাতন স্বর্ণ বিক্রয়</option>'
          + '<option value="অন্যান্য আয়">অন্যান্য আয়</option>';
      }

    } else {
      if (outTab) outTab.classList.add('active');
      if (inTab) inTab.classList.remove('active');

      if (title) title.textContent = 'ক্যাশ আউট এন্ট্রি';

      if (submit) {
        submit.textContent = '💾 ক্যাশ আউট সেভ করুন';
        submit.className = 'submit-btn out';
      }

      if (previewLabel) previewLabel.textContent = 'ক্যাশ আউট হবে';

      if (purpose) {
        purpose.innerHTML = ''
          + '<option value="নতুন স্টক">নতুন স্টক</option>'
          + '<option value="বন্ধক ঋণ বিতরণ">বন্ধক ঋণ বিতরণ</option>'
          + '<option value="খরচ">খরচ</option>'
          + '<option value="সেলার পেমেন্ট">সেলার পেমেন্ট</option>'
          + '<option value="অন্যান্য ব্যয়">অন্যান্য ব্যয়</option>';
      }
    }

    updateAmountPreview();
  }

  function updateAmountPreview() {
    var amount = num($('amount') ? $('amount').value : 0);
    var preview = $('amountPreview');

    if (!preview) return;

    preview.textContent = tk(amount);
    preview.style.color = mode === 'IN' ? '#10B981' : '#EF4444';
  }

  function buildNote() {
    var purpose = $('transaction_purpose') ? $('transaction_purpose').value : '';
    var note = $('note') ? $('note').value.trim() : '';
    var partyText = $('party_search') ? $('party_search').value.trim() : '';

    var finalNote = purpose;

    if (partyText) finalNote += ' - ' + partyText;
    if (note) finalNote += ' - ' + note;

    return finalNote;
  }

  async function submitCashEntry(e) {
    e.preventDefault();

    var accountId = $('cash_account_id') ? $('cash_account_id').value : '';
    var partyId = $('party_id') ? $('party_id').value : '';
    var amount = num($('amount') ? $('amount').value : 0);
    var entryDate = $('entry_date') ? $('entry_date').value : todayISO();
    var purpose = $('transaction_purpose') ? $('transaction_purpose').value : '';
    var note = buildNote();

    if (!accountId) {
      showMsg('অ্যাকাউন্ট নির্বাচন করুন', 'err');
      return;
    }

    if (amount <= 0) {
      showMsg('টাকার পরিমাণ দিন', 'err');
      return;
    }

    var submit = $('submitBtn');

    if (submit) {
      submit.disabled = true;
      submit.textContent = 'সেভ হচ্ছে...';
    }

    try {
      var fd = new FormData();

      fd.append('cash_account_id', accountId);
      fd.append('account_id', accountId);

      fd.append('transaction_type', mode);
      fd.append('type', mode === 'IN' ? 'cash_in' : 'cash_out');

      fd.append('amount', amount);

      fd.append('date', entryDate);
      fd.append('entry_date', entryDate);
      fd.append('transaction_date', entryDate);

      fd.append('purpose', purpose);
      fd.append('note', note);
      fd.append('description', note);

      if (partyId) {
        fd.append('party_id', partyId);
        fd.append('customer_id', partyId);
      }

      var data = await fetchJson(API.addTransaction, {
        method: 'POST',
        body: fd
      });

      if (data.success || data.status || data.ok) {
        showMsg('লেনদেন সফলভাবে সেভ হয়েছে', 'ok');

        if ($('amount')) $('amount').value = '';
        if ($('note')) $('note').value = '';

        updateAmountPreview();

        await loadAccounts(accountId);
        await loadTransactions();

      } else {
        showMsg(data.message || data.error || 'লেনদেন সেভ হয়নি', 'err');
      }

    } catch (err) {
      console.error(err);
      showMsg('সার্ভার সমস্যা: ' + err.message, 'err');

    } finally {
      if (submit) submit.disabled = false;
      setMode(mode);
    }
  }

  async function loadTransactions() {
    var box = $('transactionList');
    if (!box) return;

    box.innerHTML = '<div class="empty">লোড হচ্ছে...</div>';

    try {
      var url = API.listTransactions + '?limit=20&date=' + encodeURIComponent(todayISO());
      var data = await fetchJson(url);
      var rows = getRows(data, ['transactions', 'items', 'rows']);

      if (!rows.length) {
        box.innerHTML = '<div class="empty">আজ কোনো লেনদেন নেই</div>';
        return;
      }

      var html = '';

      rows.slice(0, 20).forEach(function (tx) {
        var rawType = String(tx.transaction_type || tx.type || '').toUpperCase();

        var isIn =
          rawType === 'IN' ||
          rawType === 'CASH_IN' ||
          rawType === 'CREDIT' ||
          String(tx.type || '').toLowerCase() === 'cash_in';

        html += ''
          + '<div class="tx-card">'
          +   '<div class="tx-top">'
          +     '<div>'
          +       '<div class="tx-type">' + (isIn ? 'IN' : 'OUT') + '</div>'
          +       '<div class="tx-note">' + esc(tx.note || tx.description || tx.purpose || '—') + '</div>'
          +       '<div class="tx-account">' + esc(tx.account_name || tx.cash_account_name || tx.name || '') + '</div>'
          +       '<div class="tx-date">' + esc(tx.created_at || tx.transaction_date || tx.date || '') + '</div>'
          +     '</div>'
          +     '<div class="tx-amount ' + (isIn ? 'in' : 'out') + '">' + (isIn ? '+' : '-') + tk(tx.amount || 0) + '</div>'
          +   '</div>'
          + '</div>';
      });

      box.innerHTML = html;

    } catch (err) {
      console.error('Transaction load error:', err);
      box.innerHTML = '<div class="empty">লেনদেন লোড হয়নি</div>';
    }
  }

  function openQuickPartyModal() {
    var modal = $('quickPartyModal');
    if (!modal) return;

    if ($('qp_name')) $('qp_name').value = '';
    if ($('qp_phone')) $('qp_phone').value = '';
    if ($('qp_address')) $('qp_address').value = '';

    var msg = $('quickPartyMsg');

    if (msg) {
      msg.textContent = '';
      msg.style.color = '';
    }

    modal.classList.add('show');

    setTimeout(function () {
      if ($('qp_name')) $('qp_name').focus();
    }, 100);
  }

  function closeQuickPartyModal() {
    var modal = $('quickPartyModal');
    if (modal) modal.classList.remove('show');
  }

  async function saveQuickParty() {
    var name = $('qp_name') ? $('qp_name').value.trim() : '';
    var phone = $('qp_phone') ? $('qp_phone').value.trim() : '';
    var address = $('qp_address') ? $('qp_address').value.trim() : '';
    var msg = $('quickPartyMsg');

    if (!name) {
      if (msg) {
        msg.textContent = 'পার্টির নাম দিন';
        msg.style.color = '#F87171';
      }
      return;
    }

    if (!phone) {
      if (msg) {
        msg.textContent = 'মোবাইল নাম্বার দিন';
        msg.style.color = '#F87171';
      }
      return;
    }

    try {
      var fd = new FormData();

      fd.append('name', name);
      fd.append('party_name', name);
      fd.append('customer_name', name);

      fd.append('phone', phone);
      fd.append('mobile', phone);
      fd.append('mobile_no', phone);
      fd.append('contact', phone);

      fd.append('address', address);
      fd.append('type', 'customer');
      fd.append('party_type', 'customer');

      var data = await fetchJson(API.partyAdd, {
        method: 'POST',
        body: fd
      });

      if (data.success || data.status || data.ok) {
        if (msg) {
          msg.textContent = 'পার্টি সফলভাবে যোগ হয়েছে';
          msg.style.color = '#34D399';
        }

        await loadPartyList();

        var found = allParties.map(normalizeParty).find(function (p) {
          return String(p.phone) === String(phone);
        });

        if (found) {
          renderHiddenPartySelect(allParties, found.id);
          selectParty(found.id, found.name, found.phone);
        } else {
          if ($('party_search')) {
            $('party_search').value = name + ' — ' + phone;
          }
        }

        setTimeout(closeQuickPartyModal, 650);

      } else {
        if (msg) {
          msg.textContent = data.message || data.error || 'পার্টি যোগ করা যায়নি';
          msg.style.color = '#F87171';
        }
      }

    } catch (err) {
      console.error('Quick party add error:', err);

      if (msg) {
        msg.textContent = 'সার্ভার সমস্যা: ' + err.message;
        msg.style.color = '#F87171';
      }
    }
  }

  function bindEvents() {
    document.addEventListener('click', function (e) {
      if (e.target.closest('#cashInTab')) {
        setMode('IN');
      }

      if (e.target.closest('#cashOutTab')) {
        setMode('OUT');
      }

      if (e.target.closest('#quickPartyBtn')) {
        e.preventDefault();
        openQuickPartyModal();
      }

      if (e.target.closest('#partyLiveAddBtn')) {
        e.preventDefault();
        openQuickPartyModal();
      }

      var partyItem = e.target.closest('.party-live-item');

      if (partyItem) {
        selectParty(
          partyItem.getAttribute('data-party-id'),
          partyItem.getAttribute('data-party-name'),
          partyItem.getAttribute('data-party-phone')
        );
      }

      if (e.target.closest('#quickPartyCancel')) {
        closeQuickPartyModal();
      }

      if (e.target.closest('#quickPartySave')) {
        saveQuickParty();
      }

      if (e.target === $('quickPartyModal')) {
        closeQuickPartyModal();
      }
    });

    document.addEventListener('input', function (e) {
      if (e.target.id === 'party_search') {
        renderPartyLiveList(e.target.value);
      }

      if (e.target.id === 'amount') {
        updateAmountPreview();
      }
    });

    document.addEventListener('focusin', function (e) {
      if (e.target.id === 'party_search') {
        renderPartyLiveList(e.target.value);
      }
    });

    document.addEventListener('submit', function (e) {
      if (e.target.id === 'cashForm') {
        submitCashEntry(e);
      }
    });
  }

  function init() {
    injectPartyStyle();
    ensurePartyPickerBox();
    bindEvents();

    if ($('entry_date')) {
      $('entry_date').value = todayISO();
    }

    if ($('todayText')) {
      $('todayText').textContent = todayISO();
    }

    setMode('IN');

    loadAccounts();
    loadPartyList();
    loadTransactions();
  }

  if (document.r