/* Ten31 CRM — shared client store (single source of truth across the four mobile surfaces).
   Mirrors the server model: investors carry stage/notes/funds/contacts/priority/last_activity;
   reminders are their own collection keyed by investor. One canonical copy so a stage move,
   logged communication, or reminder edit on any tab is reflected on every other tab.
   Installed as a window singleton so it survives child-surface remounts within the shell. */
(function () {
  if (window.T31Store) return;

  var C = function (name, email) { return { name: name, email: email }; };

  function seedInvestors() {
    return [
      { id: 1, name: 'Northwall Capital', priority: true, stage: 'commitment', daysAgo: 2,
        contacts: [C('Dana Reyes', 'dana@northwall.com'), C('Per Holt', 'per@northwall.com')],
        funds: [['Ten31 Terahash', 1500000], ['Sats and Stats', 600000], ['Join the Fold', 400000]],
        views: ['Main Fundraising', 'All Investors'],
        notes: [['Email', 'Confirmed $2.5M allocation across funds', '2026-06-17'], ['Meeting', 'DD call — covered redemption terms', '2026-06-10']] },
      { id: 2, name: 'Brightseed Partners', priority: true, stage: 'engaged', daysAgo: 5,
        contacts: [C('Omar Said', 'omar@brightseed.vc')], funds: [['Ten31 Terahash', 0]],
        views: ['Main Fundraising', 'Follow-up List'], notes: [['Note', 'Intro from Polaris — warm', '2026-06-14']] },
      { id: 3, name: 'Cedarline Family Office', priority: false, stage: 'commitment', daysAgo: 7,
        contacts: [C('Lena Cho', 'lena@cedarline.com')], funds: [['Ten31 Terahash', 800000], ['Pawn to F4', 400000]],
        views: ['Main Fundraising', 'All Investors', 'Fund II investors'], notes: [['Call', 'Wire received, fully funded', '2026-06-12']] },
      { id: 4, name: 'Vance & Co', priority: false, stage: 'engaged', daysAgo: 3,
        contacts: [C('Marcus Vance', 'mv@vanceco.com')], funds: [['Ten31 Terahash', 0]],
        views: ['Main Fundraising', 'Follow-up List'], notes: [] },
      { id: 5, name: 'Polaris Endowment', priority: true, stage: 'diligence', daysAgo: 1,
        contacts: [C('Ruth Almeida', 'ralmeida@polaris.org')], funds: [['Ten31 Terahash', 3000000], ['Sats and Stats', 2000000]],
        views: ['Main Fundraising', 'All Investors', 'Follow-up List', 'Fund II investors'],
        notes: [['Meeting', 'IC presentation went well', '2026-06-18'], ['Email', 'Sent data room access', '2026-06-15']] },
      { id: 6, name: 'Hartman Group', priority: false, stage: null, daysAgo: 14,
        contacts: [], funds: [['Ten31 Terahash', 0]], views: ['Main Fundraising'], notes: [] },
      { id: 7, name: 'Meridian Trust', priority: false, stage: 'commitment', daysAgo: 4,
        contacts: [C('Sofia Marin', 'sofia@meridiantrust.com')], funds: [['Ten31 Terahash', 800000]],
        views: ['Main Fundraising', 'All Investors'], notes: [['Note', 'Signed side letter', '2026-06-14']] },
      { id: 8, name: 'Atlas Ventures Fund', priority: false, stage: 'engaged', daysAgo: 6,
        contacts: [C('Will Tanaka', 'will@atlasvf.com')], funds: [['Ten31 Terahash', 0]],
        views: ['Main Fundraising'], notes: [] },
      { id: 9, name: 'K. Whitfield', priority: false, stage: null, daysAgo: 21,
        contacts: [C('Kira Whitfield', 'kira@whitfield.io')], funds: [],
        views: ['Graveyard'], notes: [['Note', 'No allocation — parked', '2026-05-28']] },
      { id: 10, name: 'Granite Bay LP', priority: false, stage: 'commitment', daysAgo: 30,
        contacts: [C('Tom Becker', 'tom@granitebay.com')], funds: [['Ten31 Terahash', 2000000], ['Sats and Stats', 1300000]],
        views: ['Main Fundraising', 'All Investors', 'Fund II investors'], notes: [] },
      { id: 11, name: 'Forsythe Holdings', priority: false, stage: 'lead', daysAgo: 35,
        contacts: [], funds: [], views: ['Graveyard'], notes: [] }
    ];
  }

  function seedReminders() {
    return [
      { id: 1, note: 'Resend deck — bounced', orgId: 4, due: '2026-06-18', done: false },
      { id: 2, note: 'Re-engage — cold 2 weeks', orgId: 6, due: '2026-06-16', done: false },
      { id: 3, note: 'IC memo due', orgId: 5, due: '2026-06-19', done: false },
      { id: 4, note: 'Follow up after intro call', orgId: 2, due: '2026-06-19', done: false },
      { id: 5, note: 'Share data room link', orgId: 8, due: '2026-06-20', done: false },
      { id: 6, note: 'Countersign side letter', orgId: 7, due: '2026-06-21', done: false },
      { id: 7, note: 'Send Q2 update deck', orgId: 1, due: '2026-06-24', done: false },
      { id: 8, note: 'Quarterly check-in call', orgId: 3, due: '2026-07-08', done: false },
      { id: 9, note: 'Thank-you note post-wire', orgId: 10, due: '2026-06-13', done: true }
    ];
  }

  var MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  var store = {
    investors: seedInvestors(),
    reminders: seedReminders(),
    tab: 'grid',
    theme: 'dark',
    focusInvestorId: null,
    today: new Date(2026, 5, 19),
    _subs: [],

    subscribe: function (fn) {
      this._subs.push(fn);
      var self = this;
      return function () { self._subs = self._subs.filter(function (f) { return f !== fn; }); };
    },
    _notify: function () { this._subs.slice().forEach(function (f) { try { f(); } catch (e) {} }); },

    setTab: function (t) { this.tab = t; this._notify(); },
    openInvestor: function (id) { this.focusInvestorId = id; this.tab = 'grid'; this._notify(); },
    setTheme: function (t) { this.theme = t; this._notify(); },
    toggleTheme: function () { this.theme = this.theme === 'light' ? 'dark' : 'light'; this._notify(); },

    // ----- investor mutations -----
    updateInvestor: function (id, patch) {
      this.investors = this.investors.map(function (i) { return i.id === id ? Object.assign({}, i, patch) : i; });
      this._notify();
    },
    logNote: function (id, entry) {
      this.investors = this.investors.map(function (i) { return i.id === id ? Object.assign({}, i, { notes: [entry].concat(i.notes), daysAgo: 0 }) : i; });
      this._notify();
    },
    addInvestor: function (inv) {
      var id = this.investors.reduce(function (m, i) { return Math.max(m, i.id); }, 0) + 1;
      var ni = Object.assign({ id: id, priority: false, stage: 'lead', daysAgo: 0, contacts: [], funds: [['Ten31 Terahash', 0]], views: ['Main Fundraising'], notes: [] }, inv);
      this.investors = [ni].concat(this.investors);
      this._notify();
      return id;
    },

    // ----- reminder mutations -----
    addReminder: function (orgId, note, due) {
      var id = this.reminders.reduce(function (m, r) { return Math.max(m, r.id); }, 0) + 1;
      this.reminders = [{ id: id, note: note, orgId: orgId, due: due, done: false }].concat(this.reminders);
      this._notify();
      return id;
    },
    updateReminder: function (id, patch) {
      this.reminders = this.reminders.map(function (r) { return r.id === id ? Object.assign({}, r, patch) : r; });
      this._notify();
    },
    deleteReminder: function (id) {
      this.reminders = this.reminders.filter(function (r) { return r.id !== id; });
      this._notify();
    },
    toggleReminder: function (id) {
      this.reminders = this.reminders.map(function (r) { return r.id === id ? Object.assign({}, r, { done: !r.done }) : r; });
      this._notify();
    },
    reminderFor: function (orgId) {
      // the soonest open reminder for an investor (used by the Grid detail)
      var open = this.reminders.filter(function (r) { return r.orgId === orgId && !r.done; });
      open.sort(function (a, b) { return a.due < b.due ? -1 : 1; });
      return open[0] || null;
    },

    // ----- derived helpers -----
    investorById: function (id) { return this.investors.find(function (i) { return i.id === id; }); },
    committed: function (i) { return (i.funds || []).reduce(function (a, f) { return a + f[1]; }, 0); },
    money: function (n) {
      if (!n) return '$0';
      if (n >= 1e6) return '$' + (n / 1e6).toFixed(n % 1e6 === 0 ? 0 : 1) + 'M';
      if (n >= 1e3) return '$' + Math.round(n / 1e3) + 'K';
      return '$' + n;
    },
    parseDate: function (iso) { var p = iso.split('-'); return new Date(+p[0], +p[1] - 1, +p[2]); },
    diffDays: function (iso) { return Math.round((this.parseDate(iso) - this.today) / 86400000); },
    monthDay: function (iso) { var d = this.parseDate(iso); return MONTHS[d.getMonth()] + ' ' + d.getDate(); }
  };

  window.T31Store = store;
})();
