/* Odoo learning and implementation tracker */

const ODOO_TRACKER_STORAGE_KEY = 'ppt-odoo-tracker-v1';
const ODOO_SITE_FONT = "var(--ui-font)";

const ODOO_PHASES = [
  {
    id: 'phase-01-concepts',
    number: '01',
    title: 'Odoo Core Concepts',
    source: 'odoo/phase_01_odoo_core_concepts.md',
    color: '#38BDF8',
    goal: 'Track which Odoo concepts are understood and which ones have been practiced in a real module.',
    focus: ['Apps / Modules', 'Addons Path', 'Database', 'Models', 'Fields', 'ORM', 'Views', 'Actions', 'Menus', 'Security', 'Record Rules'],
    tasks: [
      'Learn - Apps, modules, addons path and how Odoo loads custom code',
      'Learn - Database, company, user, group and basic system settings',
      'Learn - Model, record, field types and relationships',
      'Learn - ORM basics: create, search, browse, write, unlink and env',
      'Learn - Views: list, form, search, kanban and view inheritance',
      'Learn - Actions, menus and how users open a screen',
      'Learn - Security: access rights, groups and record rules',
      'Do - Read a core module such as sale, purchase, stock or account',
      'Do - Create concept notes with one small code/example per concept',
      'Do - Map one flow from menu to action to view to model to database table',
      'Do - Setup custom module furniture_work_order for simple furniture production orders',
    ],
  },
  {
    id: 'phase-02',
    number: '02',
    title: 'Builder: Content System & CRUD',
    source: 'odoo/phase_02_content_system.md',
    color: '#F5B96B',
    goal: 'Turn static notes into real data management with create, edit, delete, search, filter and storage.',
    focus: ['CRUD Concepts', 'CRUD Modules', 'CRUD Logs', 'CRUD Bugs', 'CRUD Snippets', 'CRUD Projects', 'Search / Filter', 'Data Relationships'],
    tasks: [
      'Choose local-first or cloud-friendly storage',
      'Create content schema for concepts and modules',
      'Add CRUD for concepts',
      'Add CRUD for modules',
      'Add CRUD for implementation logs',
      'Add CRUD for bug and fix notes',
      'Add CRUD for code snippets',
      'Add CRUD for projects and labs',
      'Add global search and filters',
      'Build dashboard metrics from real data',
    ],
  },
  {
    id: 'phase-03',
    number: '03',
    title: 'Power User: Research System',
    source: 'odoo/phase_03_odoo_power_tracker.md',
    color: '#A855F7',
    goal: 'Make the tracker useful for real Odoo research, implementation decisions, debugging and weekly review.',
    focus: ['Research Notes', 'Decision Log', 'Version Notes', 'Dependency Map', 'Checklist Templates', 'Learning Score', 'Weekly Review'],
    tasks: [
      'Create research notes entity',
      'Create decision log entity',
      'Track Odoo version differences',
      'Create module dependency map',
      'Create reusable checklist templates',
      'Calculate learning score',
      'Create weekly review page',
      'Show open research questions',
      'Show recent decisions and active implementation tasks',
    ],
  },
  {
    id: 'phase-04',
    number: '04',
    title: 'Hero: Knowledge Platform',
    source: 'odoo/phase_04_hero_platform.md',
    color: '#22C55E',
    goal: 'Turn Odoo Tracker into a production-ready personal platform and portfolio proof.',
    focus: ['Production UI', 'Import / Export', 'Backup', 'AI Prompt Library', 'AI Context Export', 'Portfolio Mode', 'Analytics', 'Tags', 'Deployment Docs', 'Privacy'],
    tasks: [
      'Polish production-ready UI',
      'Add import and export',
      'Add manual backup system',
      'Create AI prompt library',
      'Create AI-ready context export',
      'Create portfolio mode with public/private flags',
      'Add analytics charts',
      'Upgrade shared tag system',
      'Write deployment docs',
      'Add security and privacy controls',
    ],
  },
];

const ODOO_ROADMAP_LEVELS = [
  { title: 'Level 1 - Odoo Basics', items: ['Docker install', 'Apps / Modules', 'PostgreSQL', 'addons path', 'model / field / view basics'] },
  { title: 'Level 2 - Custom Module Basics', items: ['scaffold', '__manifest__.py', 'model', 'tree view', 'form view', 'menu / action', 'access rights'] },
  { title: 'Level 3 - Business Modules', items: ['Sales', 'Purchase', 'Inventory', 'Manufacturing', 'Accounting basics'] },
  { title: 'Level 4 - Advanced Customization', items: ['model inheritance', 'XPath view inheritance', 'computed fields', 'onchange', 'constraints', 'record rules', 'QWeb report'] },
  { title: 'Level 5 - Deployment & Real Use', items: ['Docker Compose', 'PostgreSQL backup', 'Caddy reverse proxy', 'custom addons deployment', 'staging / production workflow'] },
];

const ODOO_STATUS_OPTIONS = [
  { value: 'Planned', label: 'Planned', icon: 'M12 6v6l4 2M21 12a9 9 0 11-2.6-6.4M21 4v6h-6', color: '#F59E0B', bg: 'rgba(245,158,11,0.13)' },
  { value: 'Doing', label: 'Doing', icon: 'M4 12h5l2-7 2 14 2-7h5', color: '#38BDF8', bg: 'rgba(56,189,248,0.13)' },
  { value: 'Done', label: 'Done', icon: 'M5 12l4 4L19 6', color: '#22C55E', bg: 'rgba(34,197,94,0.13)' },
  { value: 'Blocked', label: 'Blocked', icon: 'M12 9v4M12 17h.01M10.3 4.3L2.8 18a2 2 0 001.7 3h15a2 2 0 001.7-3L13.7 4.3a2 2 0 00-3.4 0z', color: '#EF4444', bg: 'rgba(239,68,68,0.13)' },
];

const ODOO_BEGINNER_PRACTICES = [
  {
    id: 'practice-furniture-work-order',
    phaseId: 'phase-01-concepts',
    title: 'Practice 01 - Furniture Work Order Module',
    level: 'Beginner',
    moduleName: 'furniture_work_order',
    outcome: 'Create one installable module to track simple furniture production orders in a factory.',
    files: [
      'custom_addons/furniture_work_order/__manifest__.py',
      'custom_addons/furniture_work_order/models/work_order.py',
      'custom_addons/furniture_work_order/views/work_order_views.xml',
      'custom_addons/furniture_work_order/security/ir.model.access.csv',
    ],
    steps: [
      'Create custom_addons/furniture_work_order with models, views and security folders.',
      'Add __manifest__.py so Odoo can detect the module.',
      'Create model furniture.work.order with product, customer, quantity, deadline and state fields.',
      'Add ir.model.access.csv so normal users can read and edit records.',
      'Add list/form views, action and menu item for work orders.',
      'Restart Odoo, update Apps List, install furniture_work_order and create one work order.',
    ],
    commands: [
      'mkdir -p custom_addons/furniture_work_order/{models,views,security}',
      'touch custom_addons/furniture_work_order/__init__.py custom_addons/furniture_work_order/models/__init__.py',
      './odoo-bin -d odoo_dev -u furniture_work_order --addons-path=addons,custom_addons',
    ],
    checks: [
      'Apps can find module furniture_work_order.',
      'Menu Furniture Work Orders opens without access error.',
      'You can create a work order for a table, chair, cabinet or custom item.',
      'You can move the work order from Draft to In Progress or Done.',
      'The database has a table named furniture_work_order.',
    ],
    starterCode: `# __manifest__.py
{
    'name': 'Furniture Work Order Practice',
    'version': '1.0',
    'category': 'Manufacturing',
    'summary': 'Beginner module for tracking simple furniture work orders',
    'depends': ['base'],
    'data': [
        'security/ir.model.access.csv',
        'views/work_order_views.xml',
    ],
    'application': True,
}

# __init__.py
from . import models

# models/__init__.py
from . import work_order

# models/work_order.py
from odoo import fields, models


class FurnitureWorkOrder(models.Model):
    _name = 'furniture.work.order'
    _description = 'Furniture Work Order'

    name = fields.Char(required=True)
    product_name = fields.Char(required=True)
    customer_name = fields.Char()
    quantity = fields.Integer(default=1)
    deadline = fields.Date()
    state = fields.Selection([
        ('draft', 'Draft'),
        ('in_progress', 'In Progress'),
        ('done', 'Done'),
    ], default='draft')
    note = fields.Text()
    active = fields.Boolean(default=True)

# security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_furniture_work_order,furniture.work.order,model_furniture_work_order,,1,1,1,1

# views/work_order_views.xml
<odoo>
    <record id="view_furniture_work_order_tree" model="ir.ui.view">
        <field name="name">furniture.work.order.tree</field>
        <field name="model">furniture.work.order</field>
        <field name="arch" type="xml">
            <tree>
                <field name="name"/>
                <field name="product_name"/>
                <field name="customer_name"/>
                <field name="quantity"/>
                <field name="deadline"/>
                <field name="state"/>
            </tree>
        </field>
    </record>

    <record id="view_furniture_work_order_form" model="ir.ui.view">
        <field name="name">furniture.work.order.form</field>
        <field name="model">furniture.work.order</field>
        <field name="arch" type="xml">
            <form>
                <header>
                    <field name="state" widget="statusbar" statusbar_visible="draft,in_progress,done"/>
                </header>
                <sheet>
                    <group>
                        <field name="name"/>
                        <field name="product_name"/>
                        <field name="customer_name"/>
                        <field name="quantity"/>
                        <field name="deadline"/>
                        <field name="active"/>
                    </group>
                    <group>
                        <field name="note"/>
                    </group>
                </sheet>
            </form>
        </field>
    </record>

    <record id="action_furniture_work_order" model="ir.actions.act_window">
        <field name="name">Furniture Work Orders</field>
        <field name="res_model">furniture.work.order</field>
        <field name="view_mode">tree,form</field>
    </record>

    <menuitem id="menu_furniture_work_order_root" name="Furniture Factory"/>
    <menuitem id="menu_furniture_work_order" name="Work Orders" parent="menu_furniture_work_order_root" action="action_furniture_work_order"/>
</odoo>`,
  },
];

function OdooTrackerPage({ tweaks, onBackHome }) {
  const primary = tweaks.primaryColor;
  const [activePhaseId, setActivePhaseId] = React.useState(ODOO_PHASES[0].id);
  const [selectedDate, setSelectedDate] = React.useState(getTodayInputValue);
  const [query, setQuery] = React.useState('');
  const [draft, setDraft] = React.useState({
    title: '',
    module: '',
    result: '',
    status: 'Done',
  });
  const [tracker, setTracker] = React.useState(() => loadOdooTracker());

  React.useEffect(() => {
    try {
      localStorage.setItem(ODOO_TRACKER_STORAGE_KEY, JSON.stringify(tracker));
    } catch (err) {}
  }, [tracker]);

  const activePhase = ODOO_PHASES.find(phase => phase.id === activePhaseId) || ODOO_PHASES[0];
  const allTasks = ODOO_PHASES.flatMap(phase => phase.tasks.map((task, index) => ({
    id: `${phase.id}-${index}`,
    phaseId: phase.id,
    phaseTitle: phase.title,
    color: phase.color,
    title: task,
  })));
  const doneTaskIds = tracker.doneTaskIds || {};
  const doneCount = allTasks.filter(task => doneTaskIds[task.id]).length;
  const progress = allTasks.length ? Math.round(doneCount / allTasks.length * 100) : 0;
  const logs = tracker.logs || [];
  const activeTasks = allTasks.filter(task => !doneTaskIds[task.id]);
  const todayLogs = logs.filter(log => log.date === selectedDate);
  const filteredLogs = logs.filter(log => {
    const needle = query.trim().toLowerCase();
    if (!needle) return true;
    return [log.title, log.module, log.result, log.status].some(value => String(value || '').toLowerCase().includes(needle));
  });

  const toggleTask = (taskId) => {
    setTracker(current => ({
      ...current,
      doneTaskIds: {
        ...(current.doneTaskIds || {}),
        [taskId]: !current.doneTaskIds?.[taskId],
      },
    }));
  };

  const addLog = (event) => {
    event.preventDefault();
    const title = draft.title.trim();
    if (!title) return;

    const entry = {
      id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
      date: selectedDate,
      title,
      module: draft.module.trim(),
      result: draft.result.trim(),
      status: draft.status,
      createdAt: new Date().toISOString(),
    };

    setTracker(current => ({
      ...current,
      logs: [entry, ...(current.logs || [])],
    }));
    setDraft({ title: '', module: '', result: '', status: 'Done' });
  };

  const removeLog = (logId) => {
    setTracker(current => ({
      ...current,
      logs: (current.logs || []).filter(log => log.id !== logId),
    }));
  };

  const phaseTasks = activePhase.tasks.map((task, index) => ({
    id: `${activePhase.id}-${index}`,
    title: task,
  }));
  const phaseDone = phaseTasks.filter(task => doneTaskIds[task.id]).length;
  const phasePractices = ODOO_BEGINNER_PRACTICES.filter(practice => practice.phaseId === activePhase.id);

  return (
    <main className="odoo-page" style={{
      minHeight: '100vh',
      padding: '118px clamp(18px, 3vw, 48px) 80px',
      background: 'var(--theme-bg)',
      color: 'var(--theme-text)',
      fontFamily: ODOO_SITE_FONT,
      animation: 'fadeIn 0.3s ease',
    }}>
      <div style={{
        width: 'min(1800px, calc(100vw - clamp(36px, 4vw, 96px)))',
        maxWidth: '100%',
        margin: '0 auto',
      }}>
        <div className="odoo-header" style={{
          display: 'flex',
          alignItems: 'flex-start',
          justifyContent: 'space-between',
          gap: 20,
          marginBottom: 24,
        }}>
          <div style={{ maxWidth: 920 }}>
            <div style={{
              fontSize: 12,
              fontWeight: 900,
              letterSpacing: '3px',
              textTransform: 'uppercase',
              color: primary,
              marginBottom: 10,
            }}>Admin workspace</div>
            <h1 style={{
              margin: 0,
              color: 'var(--theme-strong)',
              fontSize: 'clamp(40px, 5vw, 66px)',
              lineHeight: 1.04,
            }}>Odoo Tracker</h1>
            <p style={{
              margin: '12px 0 0',
              color: 'rgba(var(--theme-text-rgb),0.66)',
              lineHeight: 1.7,
              fontSize: 15,
            }}>
              Learning, research, implementation logs, bug fixes and module practice from the phase markdown roadmap.
            </p>
          </div>
          <button type="button" onClick={onBackHome} style={deButtonStyle(primary, false)}>Back home</button>
        </div>

        <section className="odoo-dashboard-grid" style={{
          display: 'grid',
          gridTemplateColumns: '1.15fr repeat(4, minmax(150px, 0.62fr))',
          gap: 14,
          marginBottom: 18,
        }}>
          <OdooProgressCard progress={progress} doneCount={doneCount} totalCount={allTasks.length} color={primary}/>
          <OdooMetricCard label="Phases" value={`${ODOO_PHASES.length}`} sub="roadmap files" color="#38BDF8"/>
          <OdooMetricCard label="Active Tasks" value={`${activeTasks.length}`} sub="not done" color="#F59E0B"/>
          <OdooMetricCard label="Logs" value={`${logs.length}`} sub="entries" color="#22C55E"/>
          <OdooMetricCard label="Today" value={`${todayLogs.length}`} sub={selectedDate} color="#A855F7"/>
        </section>

        <div className="odoo-grid" style={{
          display: 'grid',
          gridTemplateColumns: 'minmax(260px, 0.78fr) minmax(0, 1.45fr) minmax(360px, 0.95fr)',
          gap: 18,
          alignItems: 'start',
        }}>
          <section className="odoo-card" style={odooCardStyle()}>
            <div style={odooSectionTitleStyle(primary)}>Phase Roadmap</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {ODOO_PHASES.map(phase => {
                const active = phase.id === activePhase.id;
                const phaseTaskIds = phase.tasks.map((_, index) => `${phase.id}-${index}`);
                const phaseDoneCount = phaseTaskIds.filter(id => doneTaskIds[id]).length;
                return (
                  <button key={phase.id} type="button" onClick={() => setActivePhaseId(phase.id)} style={{
                    width: '100%',
                    minWidth: 0,
                    padding: 13,
                    borderRadius: 16,
                    border: `1px solid ${active ? phase.color : 'rgba(var(--theme-text-rgb),0.09)'}`,
                    background: active ? `${phase.color}16` : 'rgba(var(--theme-bg-rgb),0.3)',
                    color: 'var(--theme-text)',
                    cursor: 'pointer',
                    textAlign: 'left',
                  }}>
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
                      <span style={{ color: phase.color, fontSize: 12, fontWeight: 900 }}>Phase {phase.number}</span>
                      <span style={{ color: 'rgba(var(--theme-text-rgb),0.54)', fontSize: 12, fontWeight: 800 }}>
                        {phaseDoneCount}/{phase.tasks.length}
                      </span>
                    </div>
                    <div style={{ marginTop: 6, color: 'var(--theme-strong)', fontWeight: 900, lineHeight: 1.25 }}>{phase.title}</div>
                    <div style={{ marginTop: 8, height: 6, borderRadius: 999, background: 'rgba(var(--theme-text-rgb),0.08)', overflow: 'hidden' }}>
                      <div style={{
                        height: '100%',
                        width: `${Math.round(phaseDoneCount / phase.tasks.length * 100)}%`,
                        borderRadius: 999,
                        background: phase.color,
                      }}/>
                    </div>
                  </button>
                );
              })}
            </div>

            <div style={{ ...odooSectionTitleStyle(primary), marginTop: 22 }}>Roadmap Levels</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {ODOO_ROADMAP_LEVELS.map(level => (
                <div key={level.title} style={{
                  padding: 13,
                  borderRadius: 15,
                  background: 'rgba(var(--theme-bg-rgb),0.28)',
                  border: '1px solid rgba(var(--theme-text-rgb),0.07)',
                }}>
                  <div style={{ color: 'var(--theme-strong)', fontWeight: 900, fontSize: 13 }}>{level.title}</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 9 }}>
                    {level.items.map(item => <OdooPill key={item} label={item} color={primary}/>)}
                  </div>
                </div>
              ))}
            </div>
          </section>

          <section className="odoo-card" style={odooCardStyle()}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 16, alignItems: 'flex-start', marginBottom: 16 }}>
              <div>
                <div style={odooSectionTitleStyle(activePhase.color)}>Active Phase</div>
                <h2 style={{ margin: '4px 0 8px', color: 'var(--theme-strong)', fontSize: 26, lineHeight: 1.15 }}>
                  Phase {activePhase.number} - {activePhase.title}
                </h2>
                <p style={{ margin: 0, color: 'rgba(var(--theme-text-rgb),0.64)', lineHeight: 1.65, fontSize: 14 }}>
                  {activePhase.goal}
                </p>
              </div>
              <div style={{
                flex: '0 0 auto',
                padding: '10px 12px',
                borderRadius: 999,
                color: activePhase.color,
                background: `${activePhase.color}14`,
                border: `1px solid ${activePhase.color}30`,
                fontWeight: 900,
                fontSize: 12,
                whiteSpace: 'nowrap',
              }}>{phaseDone}/{phaseTasks.length} done</div>
            </div>

            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 16 }}>
              {activePhase.focus.map(item => <OdooPill key={item} label={item} color={activePhase.color}/>)}
            </div>

            <div className="odoo-task-list" style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
              {phaseTasks.map(task => {
                const done = Boolean(doneTaskIds[task.id]);
                return (
                  <label key={task.id} className="odoo-task-item" style={{
                    minWidth: 0,
                    display: 'grid',
                    gridTemplateColumns: '24px minmax(0, 1fr) auto',
                    gap: 12,
                    alignItems: 'center',
                    padding: '12px 13px',
                    borderRadius: 15,
                    background: done ? `${activePhase.color}12` : 'rgba(var(--theme-bg-rgb),0.28)',
                    border: `1px solid ${done ? `${activePhase.color}30` : 'rgba(var(--theme-text-rgb),0.07)'}`,
                    cursor: 'pointer',
                    transition: 'transform 0.2s ease, border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease',
                  }}>
                    <input
                      type="checkbox"
                      checked={done}
                      onChange={() => toggleTask(task.id)}
                      style={{ width: 18, height: 18, accentColor: activePhase.color }}
                    />
                    <span style={{
                      color: done ? 'rgba(var(--theme-text-rgb),0.46)' : 'rgba(var(--theme-text-rgb),0.78)',
                      textDecoration: done ? 'line-through' : 'none',
                      lineHeight: 1.45,
                      fontSize: 14,
                      overflowWrap: 'anywhere',
                    }}>{task.title}</span>
                    <span style={{
                      display: 'inline-flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      minWidth: 58,
                      minHeight: 26,
                      padding: '5px 8px',
                      borderRadius: 999,
                      background: done ? `${activePhase.color}18` : 'rgba(var(--theme-text-rgb),0.06)',
                      border: `1px solid ${done ? `${activePhase.color}34` : 'rgba(var(--theme-text-rgb),0.08)'}`,
                      color: done ? activePhase.color : 'rgba(var(--theme-text-rgb),0.48)',
                      fontSize: 11,
                      fontWeight: 900,
                      whiteSpace: 'nowrap',
                    }}>{done ? 'Done' : 'To do'}</span>
                  </label>
                );
              })}
            </div>

            {phasePractices.length > 0 && (
              <div style={{ marginTop: 22 }}>
                <div style={odooSectionTitleStyle(activePhase.color)}>Beginner Practice</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 10 }}>
                  {phasePractices.map(practice => (
                    <OdooPracticeCard key={practice.id} practice={practice} color={activePhase.color}/>
                  ))}
                </div>
              </div>
            )}

            <div style={{ ...odooSectionTitleStyle(activePhase.color), marginTop: 22 }}>Source</div>
            <div style={{
              padding: '12px 13px',
              borderRadius: 14,
              background: 'rgba(var(--theme-bg-rgb),0.26)',
              border: '1px solid rgba(var(--theme-text-rgb),0.07)',
              color: 'rgba(var(--theme-text-rgb),0.62)',
              fontSize: 13,
              overflowWrap: 'anywhere',
            }}>{activePhase.source}</div>
          </section>

          <section className="odoo-card" style={odooCardStyle()}>
            <div className="odoo-worklog-header" style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              gap: 12,
              flexWrap: 'wrap',
              marginBottom: 14,
            }}>
              <div style={odooSectionTitleStyle(primary)}>Worklog</div>
              <OdooDatePicker
                value={selectedDate}
                onChange={date => setSelectedDate(date)}
                color={primary}
              />
            </div>

            <form onSubmit={addLog} className="odoo-log-form" style={{ display: 'grid', gridTemplateColumns: '1fr 0.7fr', gap: 10 }}>
              <input
                value={draft.title}
                onChange={event => setDraft(current => ({ ...current, title: event.target.value }))}
                placeholder="Task done"
                style={odooFieldStyle()}
              />
              <input
                value={draft.module}
                onChange={event => setDraft(current => ({ ...current, module: event.target.value }))}
                placeholder="Module"
                style={odooFieldStyle()}
              />
              <textarea
                value={draft.result}
                onChange={event => setDraft(current => ({ ...current, result: event.target.value }))}
                placeholder="Result / lesson"
                rows={3}
                style={{ ...odooFieldStyle(), resize: 'vertical', gridColumn: '1 / -1', lineHeight: 1.5 }}
              />
              <div style={{ gridColumn: '1 / -1' }}>
                <OdooStatusPicker
                  value={draft.status}
                  onChange={status => setDraft(current => ({ ...current, status }))}
                />
              </div>
              <button type="submit" style={{ ...deButtonStyle(primary, true), gridColumn: '1 / -1', justifySelf: 'start' }}>Add log</button>
            </form>

            <div style={{ marginTop: 18 }}>
              <input
                value={query}
                onChange={event => setQuery(event.target.value)}
                placeholder="Search logs"
                style={odooFieldStyle()}
              />
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 14, maxHeight: 520, overflowY: 'auto', paddingRight: 4 }}>
              {filteredLogs.length === 0 ? (
                <div style={{
                  padding: 18,
                  borderRadius: 14,
                  background: 'rgba(var(--theme-bg-rgb),0.28)',
                  border: '1px dashed rgba(var(--theme-text-rgb),0.13)',
                  color: 'rgba(var(--theme-text-rgb),0.48)',
                  fontSize: 14,
                  textAlign: 'center',
                }}>No Odoo log yet.</div>
              ) : filteredLogs.map(log => (
                <div key={log.id} style={{
                  padding: 13,
                  borderRadius: 15,
                  background: 'rgba(var(--theme-bg-rgb),0.3)',
                  border: '1px solid rgba(var(--theme-text-rgb),0.07)',
                }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, alignItems: 'flex-start' }}>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ color: 'var(--theme-strong)', fontWeight: 900, lineHeight: 1.35, overflowWrap: 'anywhere' }}>{log.title}</div>
                      <div style={{ marginTop: 5, color: 'rgba(var(--theme-text-rgb),0.52)', fontSize: 12, fontWeight: 800 }}>
                        {log.date}{log.module ? ` / ${log.module}` : ''}
                      </div>
                    </div>
                    <button type="button" onClick={() => removeLog(log.id)} aria-label="Delete Odoo log" style={{
                      width: 34,
                      height: 34,
                      borderRadius: 11,
                      border: '1px solid rgba(239,68,68,0.25)',
                      background: 'rgba(239,68,68,0.1)',
                      color: '#EF4444',
                      cursor: 'pointer',
                      flex: '0 0 auto',
                    }}>
                      <TrashIcon/>
                    </button>
                  </div>
                  {log.result && (
                    <div style={{
                      marginTop: 9,
                      color: 'rgba(var(--theme-text-rgb),0.68)',
                      fontSize: 13,
                      lineHeight: 1.55,
                      overflowWrap: 'anywhere',
                    }}>{log.result}</div>
                  )}
                  <div style={{ display: 'flex', gap: 7, marginTop: 10, flexWrap: 'wrap' }}>
                    <OdooStatusBadge status={log.status}/>
                  </div>
                </div>
              ))}
            </div>
          </section>
        </div>
      </div>
    </main>
  );
}

function loadOdooTracker() {
  try {
    const saved = JSON.parse(localStorage.getItem(ODOO_TRACKER_STORAGE_KEY) || '{}');
    return {
      doneTaskIds: saved.doneTaskIds && typeof saved.doneTaskIds === 'object' ? saved.doneTaskIds : {},
      logs: Array.isArray(saved.logs) ? saved.logs : [],
    };
  } catch (err) {
    return { doneTaskIds: {}, logs: [] };
  }
}

function OdooProgressCard({ progress, doneCount, totalCount, color }) {
  return (
    <section className="odoo-card" style={{ ...odooCardStyle(), display: 'grid', gridTemplateColumns: '112px 1fr', gap: 18, alignItems: 'center' }}>
      <svg width="112" height="112" viewBox="0 0 112 112" aria-label="Odoo progress">
        <circle cx="56" cy="56" r="45" fill="none" stroke="rgba(var(--theme-text-rgb),0.08)" strokeWidth="13"/>
        <circle
          cx="56"
          cy="56"
          r="45"
          fill="none"
          stroke={color}
          strokeWidth="13"
          strokeLinecap="round"
          strokeDasharray={`${progress * 2.827} 282.7`}
          transform="rotate(-90 56 56)"
        />
        <text x="56" y="61" textAnchor="middle" fill="var(--theme-strong)" fontSize="22" fontWeight="900">{progress}%</text>
      </svg>
      <div>
        <div style={odooSectionTitleStyle(color)}>Overall Progress</div>
        <h2 style={{ margin: '4px 0 7px', color: 'var(--theme-strong)', fontSize: 25 }}>{doneCount}/{totalCount} tasks</h2>
        <div style={{ color: 'rgba(var(--theme-text-rgb),0.6)', lineHeight: 1.55, fontSize: 14 }}>
          Checklist progress across all Odoo roadmap phases.
        </div>
      </div>
    </section>
  );
}

function OdooMetricCard({ label, value, sub, color }) {
  return (
    <section className="odoo-card" style={odooCardStyle()}>
      <div style={{ color, fontSize: 11, fontWeight: 900, letterSpacing: '1.7px', textTransform: 'uppercase' }}>{label}</div>
      <div style={{ color: 'var(--theme-strong)', fontSize: 30, fontWeight: 900, marginTop: 8 }}>{value}</div>
      <div style={{ color: 'rgba(var(--theme-text-rgb),0.5)', fontSize: 12, fontWeight: 800, marginTop: 3, overflowWrap: 'anywhere' }}>{sub}</div>
    </section>
  );
}

function OdooStatusPicker({ value, onChange }) {
  return (
    <div className="odoo-status-picker" style={{
      display: 'grid',
      gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
      gap: 8,
      padding: 7,
      borderRadius: 16,
      background: 'rgba(var(--theme-bg-rgb),0.3)',
      border: '1px solid rgba(var(--theme-text-rgb),0.08)',
    }}>
      {ODOO_STATUS_OPTIONS.map(option => {
        const active = option.value === value;
        return (
          <button key={option.value} type="button" onClick={() => onChange(option.value)} style={{
            minWidth: 0,
            minHeight: 44,
            padding: '9px 10px',
            borderRadius: 13,
            border: `1px solid ${active ? option.color : 'rgba(var(--theme-text-rgb),0.08)'}`,
            background: active ? option.bg : 'rgba(var(--theme-surface-rgb),0.14)',
            color: active ? option.color : 'rgba(var(--theme-text-rgb),0.62)',
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center',
            gap: 7,
            fontFamily: ODOO_SITE_FONT,
            fontSize: 12,
            fontWeight: 900,
            cursor: 'pointer',
            boxShadow: active ? `0 10px 24px ${option.color}18` : 'none',
          }}>
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d={option.icon}/>
            </svg>
            <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{option.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function OdooPracticeCard({ practice, color }) {
  return (
    <details className="odoo-practice-card" style={{
      padding: 15,
      borderRadius: 18,
      background: `linear-gradient(135deg, ${color}12, rgba(var(--theme-bg-rgb),0.28))`,
      border: `1px solid ${color}2B`,
      boxShadow: `0 16px 34px ${color}0F`,
      transition: 'transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease',
    }}>
      <summary className="odoo-practice-summary" style={{
        display: 'flex',
        justifyContent: 'space-between',
        gap: 14,
        alignItems: 'flex-start',
        cursor: 'pointer',
      }}>
        <div style={{ minWidth: 0 }}>
          <div style={{
            color,
            fontSize: 11,
            fontWeight: 900,
            letterSpacing: '1.7px',
            textTransform: 'uppercase',
          }}>{practice.level}</div>
          <h3 style={{
            margin: '5px 0 7px',
            color: 'var(--theme-strong)',
            fontSize: 18,
            lineHeight: 1.25,
          }}>{practice.title}</h3>
          <p style={{
            margin: 0,
            color: 'rgba(var(--theme-text-rgb),0.64)',
            fontSize: 13,
            lineHeight: 1.55,
          }}>{practice.outcome}</p>
        </div>
        <span style={{
          flex: '0 0 auto',
          display: 'inline-flex',
          alignItems: 'center',
          gap: 8,
          padding: '7px 9px',
          borderRadius: 999,
          background: `${color}18`,
          border: `1px solid ${color}34`,
          color,
          fontSize: 11,
          fontWeight: 900,
          whiteSpace: 'nowrap',
        }}>
          {practice.moduleName}
          <svg className="odoo-practice-chevron" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ transition: 'transform 0.2s ease' }}>
            <path d="M6 9l6 6 6-6"/>
          </svg>
        </span>
      </summary>

      <div className="odoo-practice-body" style={{ paddingTop: 14 }}>
        <div className="odoo-practice-grid" style={{
          display: 'grid',
          gridTemplateColumns: 'minmax(0, 1.15fr) minmax(0, 0.85fr)',
          gap: 12,
        }}>
          <OdooPracticeList title="Steps" items={practice.steps} color={color} ordered/>
          <OdooPracticeList title="Done When" items={practice.checks} color={color}/>
        </div>

        <div style={{ marginTop: 13 }}>
          <div style={{
            color: 'rgba(var(--theme-text-rgb),0.5)',
            fontSize: 11,
            fontWeight: 900,
            letterSpacing: '1.3px',
            textTransform: 'uppercase',
            marginBottom: 8,
          }}>Files to create</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7 }}>
            {practice.files.map(file => <OdooPill key={file} label={file} color={color}/>)}
          </div>
        </div>

        <pre style={{
          margin: '13px 0 0',
          padding: 12,
          borderRadius: 14,
          background: 'rgba(0,0,0,0.18)',
          border: '1px solid rgba(var(--theme-text-rgb),0.08)',
          color: 'rgba(var(--theme-text-rgb),0.74)',
          fontFamily: ODOO_SITE_FONT,
          fontSize: 12,
          lineHeight: 1.65,
          overflowX: 'auto',
          whiteSpace: 'pre-wrap',
        }}>{practice.commands.join('\n')}</pre>

        <details className="odoo-practice-details" style={{
          marginTop: 12,
          borderRadius: 14,
          background: 'rgba(var(--theme-bg-rgb),0.2)',
          border: '1px solid rgba(var(--theme-text-rgb),0.08)',
          overflow: 'hidden',
        }}>
          <summary style={{
            padding: '11px 12px',
            color,
            cursor: 'pointer',
            fontSize: 12,
            fontWeight: 900,
            letterSpacing: '1.2px',
            textTransform: 'uppercase',
          }}>Starter file content</summary>
          <pre style={{
            margin: 0,
            padding: 12,
            borderTop: '1px solid rgba(var(--theme-text-rgb),0.08)',
            background: 'rgba(0,0,0,0.18)',
            color: 'rgba(var(--theme-text-rgb),0.74)',
            fontFamily: ODOO_SITE_FONT,
            fontSize: 12,
            lineHeight: 1.55,
            overflowX: 'auto',
            whiteSpace: 'pre',
          }}>{practice.starterCode}</pre>
        </details>
      </div>
    </details>
  );
}

function OdooPracticeList({ title, items, color, ordered }) {
  const ListTag = ordered ? 'ol' : 'ul';
  return (
    <div style={{
      minWidth: 0,
      padding: 12,
      borderRadius: 14,
      background: 'rgba(var(--theme-bg-rgb),0.24)',
      border: '1px solid rgba(var(--theme-text-rgb),0.07)',
    }}>
      <div style={{
        color,
        fontSize: 11,
        fontWeight: 900,
        letterSpacing: '1.4px',
        textTransform: 'uppercase',
        marginBottom: 8,
      }}>{title}</div>
      <ListTag style={{
        margin: 0,
        paddingLeft: ordered ? 18 : 16,
        color: 'rgba(var(--theme-text-rgb),0.68)',
        fontSize: 12,
        lineHeight: 1.6,
      }}>
        {items.map(item => <li key={item} style={{ marginBottom: 6, overflowWrap: 'anywhere' }}>{item}</li>)}
      </ListTag>
    </div>
  );
}

function OdooDatePicker({ value, onChange, color }) {
  return (
    <label className="odoo-date-picker" style={{
      width: 'min(100%, 260px)',
      minHeight: 50,
      display: 'grid',
      gridTemplateColumns: '38px minmax(0, 1fr)',
      alignItems: 'center',
      gap: 10,
      padding: '7px 12px 7px 8px',
      borderRadius: 16,
      background: `linear-gradient(135deg, ${color}18, rgba(var(--theme-bg-rgb),0.42))`,
      border: `1px solid ${color}2E`,
      boxShadow: `0 14px 34px ${color}12`,
      color: 'var(--theme-text)',
      transition: 'transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease',
    }}>
      <span style={{
        width: 38,
        height: 38,
        borderRadius: 13,
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        background: `${color}1F`,
        border: `1px solid ${color}36`,
        color,
      }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 012 2v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6a2 2 0 012-2z"/>
        </svg>
      </span>
      <span style={{ minWidth: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
        <span style={{
          color,
          fontSize: 10,
          fontWeight: 900,
          letterSpacing: '1.5px',
          textTransform: 'uppercase',
        }}>Log date</span>
        <input
          className="odoo-date-input"
          type="date"
          value={value}
          onChange={event => onChange(event.target.value)}
          style={{
            width: '100%',
            minWidth: 0,
            border: 0,
            padding: 0,
            background: 'transparent',
            color: 'var(--theme-strong)',
            fontFamily: ODOO_SITE_FONT,
            fontSize: 14,
            fontWeight: 900,
            outline: 'none',
          }}
        />
      </span>
    </label>
  );
}

function OdooStatusBadge({ status }) {
  const option = getOdooStatusOption(status);
  return (
    <span style={{
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      minHeight: 30,
      padding: '6px 10px',
      borderRadius: 999,
      background: option.bg,
      border: `1px solid ${option.color}30`,
      color: option.color,
      fontSize: 12,
      fontWeight: 900,
      lineHeight: 1.2,
    }}>
      <span style={{
        width: 8,
        height: 8,
        borderRadius: '50%',
        background: option.color,
        boxShadow: `0 0 0 4px ${option.color}18`,
      }}/>
      {option.label}
    </span>
  );
}

function OdooPill({ label, color }) {
  return (
    <span style={{
      display: 'inline-flex',
      alignItems: 'center',
      minHeight: 26,
      padding: '5px 8px',
      borderRadius: 999,
      background: `${color}14`,
      border: `1px solid ${color}28`,
      color,
      fontSize: 11,
      fontWeight: 900,
      lineHeight: 1.2,
    }}>{label}</span>
  );
}

function getOdooStatusOption(status) {
  return ODOO_STATUS_OPTIONS.find(option => option.value === status) || ODOO_STATUS_OPTIONS[0];
}

function odooStatusColor(status) {
  return getOdooStatusOption(status).color;
}

function odooCardStyle() {
  return {
    minWidth: 0,
    padding: 20,
    borderRadius: 20,
    background: 'rgba(var(--theme-surface-rgb),0.22)',
    border: '1px solid rgba(var(--theme-text-rgb),0.08)',
    boxShadow: '0 18px 50px rgba(0,0,0,0.14)',
  };
}

function odooSectionTitleStyle(color) {
  return {
    color,
    fontSize: 11,
    fontWeight: 900,
    letterSpacing: '2px',
    textTransform: 'uppercase',
  };
}

function odooFieldStyle() {
  return {
    width: '100%',
    minWidth: 0,
    padding: '11px 12px',
    borderRadius: 12,
    border: '1px solid rgba(var(--theme-text-rgb),0.1)',
    background: 'rgba(var(--theme-bg-rgb),0.42)',
    color: 'var(--theme-text)',
    fontFamily: ODOO_SITE_FONT,
    fontSize: 14,
    outline: 'none',
  };
}
