/* global React, ReactDOM, Rail, TopBar, ListsView, ListDetailView, CampaignsView, PlanView,
   CreatePlanDrawer, SendToCampaignDrawer, AddCreatorsDrawer,
   LISTS, CREATORS_DB, PLANS, CAMPAIGNS, SEED_PLAN_INPUTS,
   TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakToggle, TweakSelect */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "planNoun": "Plan",
  "plansHome": "campaigns-tab",
  "showScenarios": false,
  "showSyncBanner": true,
  "showOnboardingBanner": true
}/*EDITMODE-END*/;

const App = () => {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // — Market gate — which division the user is in. Scopes visible lists + target CPM.
  const [division, setDivision] = React.useState(() => { try { return localStorage.getItem('planner_division') || null; } catch (e) { return null; } });
  const market = (window.MARKETS || []).find(m => String(m.division) === String(division)) || null;
  const marketCpm = market && market.cpm ? market.cpm : 75;
  const marketCurrency = (market && market.currency) || 'GBP';
  // Drive the global currency from the selected market (before children render).
  if (window.setCurrency) window.setCurrency(marketCurrency);
  const visibleLists = window.listsForDivision ? window.listsForDivision(division) : LISTS;
  const pickMarket = (m) => { setDivision(m.division); try { localStorage.setItem('planner_division', m.division); } catch (e) {} };

  // — Router state —
  const [route, setRoute] = React.useState({ route: 'lists' }); // {route, id?, ...}
  const [history, setHistory] = React.useState([]);

  // — Mutable plans / inputs (live in state) —
  const [plans, setPlans] = React.useState(PLANS);
  const [planInputs, setPlanInputs] = React.useState(SEED_PLAN_INPUTS);
  const [campaigns, setCampaigns] = React.useState(CAMPAIGNS);

  // — Drawers —
  const [createPlanFor, setCreatePlanFor] = React.useState(null); // {listId} or null
  const [sendToCampaignFor, setSendToCampaignFor] = React.useState(null);
  const [addCreatorsFor, setAddCreatorsFor] = React.useState(null);
  const [planCreated, setPlanCreated] = React.useState(null); // {planId, campaignId?}
  const [openListMenu, setOpenListMenu] = React.useState(null);

  // — Navigation helpers —
  const go = (next) => {
    setHistory(h => [...h, route]);
    setRoute(next);
    setOpenListMenu(null);
  };

  // Sidebar nav
  const onRailNav = (railId) => {
    const map = {
      lists: { route:'lists' },
      campaigns: { route:'campaigns' },
      search: { route:'lists' }, // demo: search routes back to lists
      discover: { route:'lists' },
      audiences: { route:'lists' },
      reports: { route:'lists' },
      payments: { route:'lists' },
    };
    if (map[railId]) go(map[railId]);
  };

  // — Plan creation (creates a draft plan and routes to it) —
  const handleCreatePlan = (cfg) => {
    const newId = 'plan-' + Math.random().toString(36).slice(2,8);
    // Seed the plan with the creators that belong to the source list (from the database).
    let seedCreatorIds = (window.LIST_MEMBERS && window.LIST_MEMBERS[cfg.listId]) || [];
    if (!seedCreatorIds.length) {
      // Fallback for the original demo lists.
      if (cfg.listId === 'lumen' || cfg.listId === 'film-q3') {
        seedCreatorIds = ['aria','jordan','priya','marcus','lina','theo','asha','eli'];
      } else if (cfg.listId === 'docu') {
        seedCreatorIds = ['theo','jordan','marcus'];
      } else {
        seedCreatorIds = ['aria','priya','theo'];
      }
    }
    const newPlan = {
      id: newId,
      name: cfg.name,
      listId: cfg.listId,
      currency: cfg.currency,
      targetBudget: cfg.targetBudget,
      targetViews: cfg.targetViews,
      targetCpm: cfg.targetCpm,
      targetEmv: cfg.targetEmv || 0,
      targetSmv: cfg.targetSmv || 0,
      paidMedia: cfg.paidMedia,
      viewsModifier: cfg.viewsModifier || 0,
      payoutBasis: cfg.payoutBasis || 'total',
      payoutValue: cfg.payoutValue != null ? cfg.payoutValue : 0,
      agencyFee: cfg.agencyFee || { enabled:false, basis:'total', type:'percentage', value:10 },
      creatorIds: seedCreatorIds,
      versions: [{label:'v1', when:'just now', who:'Sara Jacobson', note:'Initial pass'}],
      editedBy: 'Sara Jacobson',
      editedAt: 'just now',
      campaignId: null,
    };
    setPlans(p => [newPlan, ...p]);
    // seed inputs with reasonable defaults
    const seedInputs = {};
    const perPost = cfg.payoutBasis === 'perPost';
    const payoutVal = cfg.payoutValue != null ? cfg.payoutValue : 0;
    seedCreatorIds.forEach(id => {
      seedInputs[id] = { agencyFeePct: 0, payoutTotal: perPost ? 0 : payoutVal, handles: {} };
      const creator = CREATORS_DB.find(c => c.id === id);
      (creator?.handles || []).forEach(h => {
        seedInputs[id].handles[h.platform] = {};
        Object.keys(h.types).forEach((typeId, i) => {
          seedInputs[id].handles[h.platform][typeId] = { postCount: 1, payoutPerPost: perPost ? payoutVal : null, adjustmentPct:0 };
        });
      });
    });
    setPlanInputs(p => ({ ...p, [newId]: seedInputs }));
    setCreatePlanFor(null);
    setPlanCreated({ planId: newId });
    go({ route:'plan', id: newId });
  };

  // — Set a plan-level field (budget, target views, etc.) —
  const setPlanField = (planId, field, value) => {
    setPlans(p => p.map(x => x.id === planId ? { ...x, [field]: value } : x));
  };

  // — Set creator-level inputs for a plan —
  const updatePlanInputs = (planId, updater) => {
    setPlanInputs(prev => {
      const next = { ...prev };
      next[planId] = typeof updater === 'function' ? updater(next[planId] || {}) : updater;
      return next;
    });
  };

  // — Send to Campaign —
  const handleSendToCampaign = (cfg) => {
    const plan = sendToCampaignFor;
    if (!plan) return;
    const visibleIds = plan.creatorIds.filter(id => !((planInputs[plan.id]||{})[id]||{}).hidden);
    // Format a YYYY-MM-DD value from the date picker into the app's display style (e.g. "Jun 1, 2026").
    const fmtDate = (iso) => {
      if (!iso) return '';
      const [y,m,d] = iso.split('-').map(Number);
      const dt = new Date(y, m-1, d);
      return dt.toLocaleDateString('en-US', { month:'short', day:'numeric', year:'numeric' });
    };
    let newCampaign = null;
    if (cfg.mode === 'new') {
      const id = 'camp-' + Math.random().toString(36).slice(2,7);
      newCampaign = {
        id, name: cfg.campaignName, brand: 'CreatorIQ', status:'Draft',
        start: fmtDate(cfg.startDate), end: fmtDate(cfg.endDate),
        startISO: cfg.startDate, endISO: cfg.endDate,
        salesPerson:'Sara Jacobson',
        creators: visibleIds.length, posts:0, videos:0, fromPlanId: plan.id,
      };
      setCampaigns(c => [newCampaign, ...c]);
    }
    // Link plan → campaign
    setPlans(p => p.map(x => x.id === plan.id ? { ...x, campaignId: newCampaign ? newCampaign.id : cfg.existingCampaignId } : x));
    setSendToCampaignFor(null);
    // route to campaigns tab to show the new draft
    setTimeout(()=>go({ route:'campaigns' }), 200);
  };

  // — Add creators to a plan —
  const handleAddCreators = (creatorIds) => {
    const plan = addCreatorsFor;
    if (!plan) return;
    setPlans(p => p.map(x => x.id === plan.id ? { ...x, creatorIds: [...x.creatorIds, ...creatorIds] } : x));
    setPlanInputs(prev => {
      const next = { ...prev, [plan.id]: { ...(prev[plan.id] || {}) } };
      creatorIds.forEach(id => {
        next[plan.id][id] = next[plan.id][id] || { agencyFeePct: 10, payoutTotal: 2000, handles: {} };
        const creator = CREATORS_DB.find(c => c.id === id);
        (creator?.handles || []).forEach(h => {
          next[plan.id][id].handles[h.platform] = next[plan.id][id].handles[h.platform] || {};
          Object.keys(h.types).forEach((typeId, i) => {
            next[plan.id][id].handles[h.platform][typeId] = next[plan.id][id].handles[h.platform][typeId] || { postCount: 1, payoutPerPost:null, adjustmentPct:0 };
          });
        });
      });
      return next;
    });
    setAddCreatorsFor(null);
  };

  // — Duplicate plan —
  const handleDuplicate = (planId) => {
    const src = plans.find(p => p.id === planId);
    if (!src) return;
    const id = 'plan-' + Math.random().toString(36).slice(2,7);
    const copy = { ...JSON.parse(JSON.stringify(src)), id, name: src.name + ' (copy)', versions:[{label:'v1',when:'just now',who:'Sara Jacobson',note:'Duplicated from ' + src.name}], editedAt:'just now', editedBy:'Sara Jacobson', campaignId:null };
    setPlans(p => [copy, ...p]);
    setPlanInputs(prev => ({ ...prev, [id]: JSON.parse(JSON.stringify(prev[planId] || {})) }));
    go({ route:'plan', id });
  };

  const activeRailId = (() => {
    if (route.route === 'lists' || route.route === 'list') return 'lists';
    if (route.route === 'campaigns' || route.route === 'plan') return 'campaigns';
    return 'lists';
  })();

  // — Render —
  const renderRoute = () => {
    switch (route.route) {
      case 'lists':
        return <ListsView go={go} lists={visibleLists} openMenuFor={openListMenu} setOpenMenuFor={setOpenListMenu}
                          onCreatePlanFromList={(listId)=>setCreatePlanFor({ listId })}/>;
      case 'list': {
        const list = LISTS.find(l => l.id === route.id);
        if (!list) return <NoMatch/>;
        return <ListDetailView list={list} go={go} plans={plans.filter(p=>p.listId===list.id)}
                                onCreatePlan={(listId)=>setCreatePlanFor({ listId })}/>;
      }
      case 'campaigns':
        return <CampaignsView go={go} plans={plans} lists={visibleLists} plansHome={t.plansHome} initialTab={route.tab}
                              onCreatePlan={(listId)=>setCreatePlanFor({ listId })}/>;
      case 'plan': {
        const plan = plans.find(p => p.id === route.id);
        if (!plan) return <NoMatch/>;
        return <PlanView
          plan={plan}
          planInputs={planInputs[plan.id] || {}}
          setPlanInputs={(updater)=>updatePlanInputs(plan.id, updater)}
          setPlanField={(field, value) => setPlanField(plan.id, field, value)}
          go={go}
          lists={LISTS}
          plans={plans}
          campaigns={campaigns}
          tweaks={t}
          onSendToCampaign={()=>setSendToCampaignFor(plan)}
          onAddCreators={()=>setAddCreatorsFor(plan)}
          onDuplicate={()=>handleDuplicate(plan.id)}
        />;
      }
      default:
        return <NoMatch/>;
    }
  };

  return (
    <div className="app">
      <Rail activeId={activeRailId} onNavigate={onRailNav}
            market={market}
            onChangeMarket={()=>{ setDivision(null); try { localStorage.removeItem('planner_division'); } catch (e) {} }}/>
      <div className="main">{renderRoute()}</div>

      <div className="feedback-nub">Feedback</div>

      <CreatePlanDrawer
        open={!!createPlanFor}
        fromListId={createPlanFor?.listId}
        defaultCpm={marketCpm}
        currency={marketCurrency}
        onClose={()=>setCreatePlanFor(null)}
        onCreate={handleCreatePlan}
        lists={visibleLists}/>

      <SendToCampaignDrawer
        open={!!sendToCampaignFor}
        plan={sendToCampaignFor}
        visibleCreators={sendToCampaignFor
          ? sendToCampaignFor.creatorIds
              .filter(id => !((planInputs[sendToCampaignFor.id]||{})[id]||{}).hidden)
              .map(id => CREATORS_DB.find(c => c.id === id))
              .filter(Boolean)
          : []}
        onClose={()=>setSendToCampaignFor(null)}
        onSend={handleSendToCampaign}/>

      <AddCreatorsDrawer
        open={!!addCreatorsFor}
        plan={addCreatorsFor}
        onClose={()=>setAddCreatorsFor(null)}
        onAdd={handleAddCreators}/>

      <TweaksPanel title="Tweaks">
        <TweakSection title="Naming">
          <TweakRadio value={t.planNoun} onChange={v=>setTweak('planNoun', v)}
            options={[{value:'Plan',label:'Plan'},{value:'Draft',label:'Draft'},{value:'Forecast',label:'Forecast'}]}/>
          <div style={{fontSize:11,color:'rgba(255,255,255,.6)',marginTop:4}}>Naming experiment — affects copy across the prototype. <i>(Demo: only labels change; full propagation in next pass.)</i></div>
        </TweakSection>
        <TweakSection title="Where plans live">
          <TweakRadio value={t.plansHome} onChange={v=>setTweak('plansHome', v)}
            options={[
              {value:'campaigns-tab', label:'Tab inside Campaigns'},
              {value:'separate', label:'No plans tab'},
            ]}/>
        </TweakSection>
        <TweakSection title="Plan view">
          <TweakToggle value={t.showScenarios} onChange={v=>setTweak('showScenarios', v)} label="Scenario rail (A/B/C)"/>
          <TweakToggle value={t.showSyncBanner} onChange={v=>setTweak('showSyncBanner', v)} label="Talent Proposal sync banner"/>
        </TweakSection>
      </TweaksPanel>

      {/* — Toast when plan created from outside the plan view — */}
      {planCreated && route.route === 'plan' && route.id === planCreated.planId && (
        <Toast onClose={()=>setPlanCreated(null)}>
          ✨ <b>Plan created.</b> Edit inputs in the table.
        </Toast>
      )}

      {/* — Market gate — must pick a market before using the planner — */}
      {!division && <MarketGate onPick={pickMarket}/>}
    </div>
  );
};

// — Market gate — a required chooser shown on load. Only markets with a Division ID
//   are selectable; picking one scopes the visible lists and the plan target CPM.
const MarketGate = ({ onPick }) => {
  const markets = window.MARKETS || [];
  const [sel, setSel] = React.useState('');
  const chosen = markets.find(m => m.country === sel);
  const valid = !!(chosen && chosen.division != null);
  return (
    <div style={{position:'fixed',inset:0,zIndex:200,background:'rgba(16,10,14,.55)',backdropFilter:'blur(3px)',display:'flex',alignItems:'center',justifyContent:'center',padding:24}}>
      <div style={{width:420,maxWidth:'100%',background:'#fff',borderRadius:16,boxShadow:'var(--shadow-lg)',padding:'26px 26px 22px'}}>
        <div className="row gap-3" style={{alignItems:'center',marginBottom:6}}>
          <div style={{width:34,height:34,borderRadius:9,background:'var(--brand,#d31069)',display:'flex',alignItems:'center',justifyContent:'center',color:'#fff'}}>
            <Icon name="network" size={18}/>
          </div>
          <h2 style={{margin:0,fontSize:19,fontWeight:700,letterSpacing:'-.01em'}}>Select your market</h2>
        </div>
        <p style={{margin:'0 0 18px',color:'var(--ink-2)',fontSize:13,lineHeight:1.5}}>
          Choose your market to load the lists and planning rates for your division.
        </p>
        <label className="field-label" style={{display:'block',marginBottom:6,fontSize:12,fontWeight:700,color:'var(--ink-2)'}}>Market</label>
        <select value={sel} onChange={(e)=>setSel(e.target.value)}
          style={{width:'100%',height:42,padding:'0 12px',borderRadius:9,border:'1px solid var(--border,#e3e6ee)',background:'#fff',fontSize:14,color:'var(--ink)',cursor:'pointer'}}>
          <option value="" disabled>Select a market…</option>
          {markets.map(m => (
            <option key={m.country} value={m.country} disabled={m.division == null}>
              {m.country}{m.division == null ? ' — coming soon' : ''}
            </option>
          ))}
        </select>
        <button disabled={!valid} onClick={()=>onPick(chosen)}
          className="btn btn-primary"
          style={{width:'100%',marginTop:20,height:42,justifyContent:'center',opacity:valid?1:.5,cursor:valid?'pointer':'not-allowed'}}>
          Continue
        </button>
      </div>
    </div>
  );
};

const NoMatch = () => (
  <>
    <div className="body"><div className="card card-pad muted">That view doesn't exist in this prototype yet.</div></div>
  </>
);

const Toast = ({ children, onClose }) => {
  React.useEffect(() => {
    const t = setTimeout(onClose, 5000);
    return () => clearTimeout(t);
  }, [onClose]);
  return (
    <div style={{position:'fixed',bottom:24,left:'50%',transform:'translateX(-50%)',background:'#0a1b32',color:'#fff',padding:'10px 16px',borderRadius:12,boxShadow:'var(--shadow-lg)',fontSize:13,zIndex:100,display:'flex',alignItems:'center',gap:10}}>
      {children}
      <button onClick={onClose} style={{marginLeft:6,background:'transparent',border:0,color:'#fff',cursor:'pointer',padding:4,opacity:.7}}>✕</button>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
