<script setup lang="ts">
// End-user dashboard. Faithfully ports project/platform-screens.jsx
// `EndUserDashboard` — same layout, same spacing tokens, same copy.


import type { IconName } from '~/components/UiIcon.vue'
import { appTiles, currentUser, todayAgenda, recentFiles, needsAttention } from '~/data/enduser'

const toast = useToast()
const router = useRouter()

const presence = ref<'available' | 'meeting' | 'focus' | 'away'>('available')

// Date eyebrow ("Monday, 25 May") + dynamic greeting that follows the source's
// hour-bucket rules.
const now = new Date()
const dateEyebrow = now.toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' })
const firstName = currentUser.name.split(' ')[0]
const greet = (() => {
  const h = now.getHours()
  if (h < 5) return 'Still up'
  if (h < 12) return 'Good morning'
  if (h < 17) return 'Good afternoon'
  return 'Good evening'
})()

const previewFile = ref<typeof recentFiles[number] | null>(null)
const joining = ref<typeof todayAgenda[number] | null>(null)
const joinMic = ref(true)
const joinCam = ref(true)
watch(joining, (v) => { if (v) { joinMic.value = true; joinCam.value = true } })

function openApp(name: string) {
  toast.info(`Opening ${name}…`)
}

const APP_ICONS: Record<string, IconName> = {
  mail: 'mail', drev: 'folder', moder: 'video', chat: 'chat',
}

// Tone → icon tint colour for the pending-task icon boxes.
function attentionIconStyle(tone: string) {
  if (tone === 'bad')  return { background: 'rgba(226, 48, 48, 0.12)',  color: 'var(--bad)'  }
  if (tone === 'warn') return { background: 'rgba(232, 154, 31, 0.12)', color: 'var(--warn)' }
  return { background: 'rgba(10, 10, 10, 0.08)', color: 'var(--text)' }
}

function fireAttention(item: typeof needsAttention[number]) {
  if (item.target === 'security') return router.push('/security')
  if (item.target === 'file') {
    previewFile.value = { id: 'attn-q3', name: 'Q3 forecast.xlsx', path: 'Drev · /Finance', updated: 'yesterday', size: '482 KB' }
    return
  }
  toast.ok(`${item.cta} · ${item.title}`)
}
</script>

<template>
  <div class="dash">
    <!-- Greeting + presence -->
    <header class="head">
      <div>
        <Eyebrow>{{ dateEyebrow }}</Eyebrow>
        <h1>{{ greet }}, {{ firstName }}.</h1>
      </div>
      <EnduserPresenceSelector v-model="presence" />
    </header>

    <!-- 4 app tiles -->
    <section class="tiles">
      <button v-for="t in appTiles" :key="t.key" class="tile" @click="openApp(t.name)">
        <span class="tile-icon">
          <UiIcon :name="APP_ICONS[t.key] ?? 'file'" :size="18" />
        </span>
        <div class="tile-body">
          <div class="tile-name">{{ t.name }}</div>
          <div class="tile-badge">{{ t.badge }}</div>
        </div>
      </button>
    </section>

    <!-- Today's meetings + recent files -->
    <section class="two-col">
      <Card :pad="0">
        <div class="card-head">
          <div>
            <Eyebrow>Today</Eyebrow>
            <div class="card-title">Meetings</div>
          </div>
          <UiButton size="sm" variant="ghost" @click="toast.info('Opening calendar at cal.dezky.com')">
            View calendar
            <template #trailing><UiIcon name="chevRight" :size="12" /></template>
          </UiButton>
        </div>
        <div
          v-for="(m, i) in todayAgenda"
          :key="m.id"
          class="agenda-row"
          :class="{ last: i === todayAgenda.length - 1 }"
        >
          <div class="agenda-time">{{ m.time }}</div>
          <div class="agenda-meta">
            <div class="agenda-title">{{ m.title }}</div>
            <div class="agenda-with">{{ m.with }}</div>
          </div>
          <div class="agenda-in">in {{ m.in }}</div>
          <UiButton size="sm" variant="primary" @click="joining = m">Join</UiButton>
        </div>
      </Card>

      <Card :pad="0">
        <div class="card-head no-action">
          <Eyebrow>Recent</Eyebrow>
          <div class="card-title">Files</div>
        </div>
        <button
          v-for="(f, i) in recentFiles.slice(0, 5)"
          :key="f.id"
          class="file-row"
          :class="{ last: i === 4 }"
          @click="previewFile = f"
        >
          <span class="file-icon"><UiIcon name="file" :size="14" /></span>
          <div class="file-text">
            <div class="file-name">{{ f.name }}</div>
            <div class="file-meta">{{ f.path }} · {{ f.updated }}</div>
          </div>
          <UiIcon name="chevRight" :size="12" stroke="var(--text-mute)" />
        </button>
      </Card>
    </section>

    <!-- Pending tasks -->
    <section class="block">
      <Card :pad="0">
        <div class="card-head">
          <div>
            <Eyebrow>Needs your attention</Eyebrow>
            <div class="card-title">Pending · {{ needsAttention.length }} items</div>
          </div>
          <UiButton size="sm" variant="ghost" @click="toast.info('Opening full task list')">
            See all
            <template #trailing><UiIcon name="chevRight" :size="12" /></template>
          </UiButton>
        </div>
        <div class="attention">
          <div
            v-for="(t, i) in needsAttention"
            :key="t.id"
            class="att-row"
            :class="{
              'right-col': i % 2 === 1,
              'bottom': i >= needsAttention.length - 2,
            }"
          >
            <span class="att-icon" :style="attentionIconStyle(t.tone)">
              <UiIcon :name="(t.icon as IconName)" :size="14" />
            </span>
            <div class="att-text">
              <div class="att-title">{{ t.title }}</div>
              <Mono dim>{{ t.hint }}</Mono>
            </div>
            <UiButton
              size="sm"
              :variant="t.tone === 'bad' ? 'primary' : 'secondary'"
              @click="fireAttention(t)"
            >
              {{ t.cta }}
            </UiButton>
          </div>
        </div>
      </Card>
    </section>

    <!-- Announcement + system status -->
    <section class="two-col">
      <div class="announce">
        <div class="announce-text">
          <div class="announce-kicker">// announcement</div>
          <div class="announce-head">We're moving to single-sign-on next Monday. Set up your authenticator app this week.</div>
          <div class="announce-by">posted by Anne · 2h ago</div>
        </div>
        <UiButton variant="primary" @click="router.push('/security')">Set it up</UiButton>
      </div>

      <Card :pad="0">
        <div class="card-head no-action">
          <Eyebrow>System</Eyebrow>
          <div class="card-title">All services operational</div>
        </div>
        <div class="services">
          <div v-for="s in ['Mail', 'Drev', 'Møder', 'Chat', 'Auth (SSO)']" :key="s" class="svc-row">
            <span class="svc-name">{{ s }}</span>
            <div class="svc-state">
              <StatusDot color="var(--ok)" :size="7" :glow="false" />
              <span>operational</span>
            </div>
          </div>
        </div>
      </Card>
    </section>

    <!-- File preview modal -->
    <Modal :open="previewFile !== null" eyebrow="Drev · preview" :title="previewFile?.name" size="md" @close="previewFile = null">
      <div class="preview">
        <div class="preview-stage">
          <span class="preview-icon"><UiIcon name="file" :size="28" /></span>
          <Mono dim>preview not available · open in Drev to view</Mono>
        </div>
        <div class="preview-meta">
          <dl>
            <div><dt>Location</dt><dd><Mono>{{ previewFile?.path }}</Mono></dd></div>
            <div><dt>Modified</dt><dd>{{ previewFile?.updated }}</dd></div>
            <div><dt>Size</dt><dd><Mono>{{ previewFile?.size ?? '2.4 MB' }}</Mono></dd></div>
            <div><dt>Shared with</dt><dd>3 people · Engineering team</dd></div>
            <div><dt>Permissions</dt><dd>You can edit</dd></div>
          </dl>
        </div>
        <div class="preview-actions">
          <UiButton size="sm" variant="secondary" @click="toast.ok('Link copied')">
            <template #leading><UiIcon name="copy" :size="13" /></template>
            Copy link
          </UiButton>
          <UiButton size="sm" variant="secondary" @click="toast.info('Opening sharing')">
            <template #leading><UiIcon name="users" :size="13" /></template>
            Manage access
          </UiButton>
          <UiButton size="sm" variant="ghost" @click="toast.info('Starred')">
            <template #leading><UiIcon name="external" :size="13" /></template>
            Star
          </UiButton>
        </div>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="previewFile = null">Close</UiButton>
        <div style="flex: 1" />
        <UiButton variant="secondary" @click="toast.info('Downloading')">
          <template #leading><UiIcon name="download" :size="13" /></template>
          Download
        </UiButton>
        <UiButton variant="primary" @click="toast.info('Opening in Drev')">
          <template #leading><UiIcon name="external" :size="13" /></template>
          Open in Drev
        </UiButton>
      </template>
    </Modal>

    <!-- Join meeting modal -->
    <Modal :open="joining !== null" eyebrow="Møder" :title="joining ? `Join · ${joining.title}` : ''" size="md" @close="joining = null">
      <div class="join">
        <div class="cam">
          <div class="cam-avatar">A</div>
          <div class="cam-label">camera preview</div>
        </div>
        <div class="join-info">
          <dl>
            <div><dt>Meeting</dt><dd>{{ joining?.title }}</dd></div>
            <div><dt>With</dt><dd>{{ joining?.with }}</dd></div>
            <div><dt>Starts</dt><dd>{{ joining?.time }} · in {{ joining?.in }}</dd></div>
            <div><dt>Room</dt><dd><Mono>meet.dezky.com/{{ joining?.title.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '') }}</Mono></dd></div>
          </dl>
        </div>
        <div class="join-toggles">
          <button class="toggle" :class="{ off: !joinMic }" @click="joinMic = !joinMic">
            <UiIcon :name="joinMic ? 'check' : 'x'" :size="14" :stroke="joinMic ? 'var(--ok)' : 'var(--bad)'" :stroke-width="2.5" />
            <div class="toggle-text">
              <div class="toggle-label">Microphone</div>
              <Mono dim>{{ joinMic ? 'unmuted' : 'muted' }}</Mono>
            </div>
          </button>
          <button class="toggle" :class="{ off: !joinCam }" @click="joinCam = !joinCam">
            <UiIcon :name="joinCam ? 'check' : 'x'" :size="14" :stroke="joinCam ? 'var(--ok)' : 'var(--bad)'" :stroke-width="2.5" />
            <div class="toggle-text">
              <div class="toggle-label">Camera</div>
              <Mono dim>{{ joinCam ? 'on' : 'off' }}</Mono>
            </div>
          </button>
        </div>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="joining = null">Cancel</UiButton>
        <UiButton variant="primary" @click="joining = null; toast.ok('Joining meeting…')">
          <template #leading><UiIcon name="video" :size="13" /></template>
          Join now
        </UiButton>
      </template>
    </Modal>
  </div>
</template>

<style scoped>
/* Container — single column, 1400px max, balanced 32 top / 40 sides / 64 bottom. */
.dash {
  padding: 32px 40px 64px 40px;
  max-width: 1400px;
  margin: 0 auto;
}

/* Greeting strip. No subtitle line, no bottom border — the design lets the
   tiles below do the visual divide. */
.head {
  margin-bottom: 32px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.head h1 {
  font-family: var(--font-display);
  font-size: 44px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 8px 0 0 0;
}

/* App tiles — 4 col grid, 130 minHeight, dark inverted icon box. */
.tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-height: 130px;
  cursor: pointer;
  color: inherit;
  font-family: inherit;
  text-align: left;
  transition: border-color 0.12s, background 0.12s;
}
.tile:hover { border-color: var(--text); }
.tile-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--text);
  color: var(--bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tile-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.015em;
}
.tile-badge {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 6px;
}

/* Two-column blocks reused for meetings/files + announce/status */
.two-col {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 16px;
  margin-top: 16px;
}
.two-col:first-of-type { margin-top: 0; }

/* Stand-alone full-width sections between two-col rows. Source design uses
   marginTop: 16 between each top-level block after the tile grid. */
.block { margin-top: 16px; }

/* Card head — eyebrow + 18px title + optional ghost action right */
.card-head {
  padding: 20px 24px 16px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.card-head.no-action { display: block; }
.card-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 18px;
  margin-top: 4px;
  letter-spacing: -0.01em;
}

/* Meetings — 4-col row: time / meta / "in X" / Join */
.agenda-row {
  padding: 14px 24px;
  display: grid;
  grid-template-columns: 60px 1fr auto auto;
  align-items: center;
  gap: 16px;
  border-bottom: 1px solid var(--border);
}
.agenda-row.last { border-bottom: none; }
.agenda-time {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 600;
}
.agenda-title { font-size: 14px; font-weight: 500; }
.agenda-with { font-size: 12px; color: var(--text-mute); margin-top: 2px; }
.agenda-in {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
}

/* Recent files — 28x28 icon, name + meta line, chev */
.file-row {
  padding: 12px 24px;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  color: var(--text);
  transition: background 0.1s;
}
.file-row.last { border-bottom: none; }
.file-row:hover { background: var(--row-hover); }
.file-icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: var(--bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-mute);
  flex-shrink: 0;
}
.file-text { flex: 1; min-width: 0; }
.file-name {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.file-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
}

/* Pending tasks — 2-col grid, dividers only between cells, none on last row */
.attention { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; }
.att-row {
  padding: 14px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--border);
}
.att-row:not(.right-col) { border-right: 1px solid var(--border); }
.att-row.bottom { border-bottom: none; }
.att-icon {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.att-text { flex: 1; min-width: 0; }
.att-title { font-size: 13px; font-weight: 500; }

/* Announcement — carbon background, two-up flex row with button on the right */
.announce {
  background: var(--text);
  color: var(--bg);
  border-radius: 8px;
  padding: 28px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.announce-text { min-width: 0; }
.announce-kicker {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  letter-spacing: 0.08em;
}
.announce-head {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 8px;
  text-wrap: balance;
  line-height: 1.25;
}
.announce-by {
  font-family: var(--font-mono);
  font-size: 12px;
  opacity: 0.6;
  margin-top: 8px;
}

/* System services — 5 rows, mono name + green dot + 'operational' */
.services {
  padding: 14px 24px 18px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.svc-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 13px;
}
.svc-name { font-family: var(--font-mono); }
.svc-state {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-mute);
  font-size: 12px;
}

/* Preview modal */
.preview { display: flex; flex-direction: column; gap: 14px; }
.preview-stage {
  aspect-ratio: 4 / 3;
  background: var(--surface);
  border-radius: 8px;
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  overflow: hidden;
}
.preview-icon {
  width: 64px;
  height: 64px;
  border-radius: 12px;
  background: var(--bg);
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.preview-meta { padding: 14px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; }
.preview-actions { display: flex; gap: 8px; }
.preview-meta dl, .join-info dl {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.preview-meta dl > div, .join-info dl > div { display: flex; gap: 12px; }
.preview-meta dt, .join-info dt {
  width: 110px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-mute);
}
.preview-meta dd, .join-info dd { margin: 0; font-size: 13px; color: var(--text); }

/* Join meeting modal */
.join { display: flex; flex-direction: column; gap: 16px; }
.cam {
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  background: linear-gradient(135deg, #0A0A0A, #1A1A1A);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
.cam-avatar {
  width: 80px;
  height: 80px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 32px;
}
.cam-label {
  position: absolute;
  bottom: 12px;
  left: 12px;
  color: #F4F3EE;
  opacity: 0.6;
  font-family: var(--font-mono);
  font-size: 11px;
}
.join-info { padding: 14px; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; }
.join-toggles { display: flex; gap: 10px; }
.toggle {
  flex: 1;
  padding: 12px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
}
.toggle.off {
  background: rgba(226, 48, 48, 0.08);
  border-color: rgba(226, 48, 48, 0.3);
}
.toggle-text { display: flex; flex-direction: column; }
.toggle-label { font-size: 13px; font-weight: 500; }
</style>
